ckeditor5 1.14.1 → 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: a2d481ae5f7ed4d671e8d6ade94e9efa0ab5d0b4bba36f24b8052d84eadd21e9
4
- data.tar.gz: 3d8ff1d8a23aadc4398e2439996d9a86aa792eec16e33a70837e731e68f6ba9f
3
+ metadata.gz: 2a9a17d760584b0e960fe984a39421cb779f6ecbbbff0e01dd996530051e5257
4
+ data.tar.gz: 9612989fa0d36927280d3d2023499a5944c7cd22cae9f7a3f9eb1b56fb5a5651
5
5
  SHA512:
6
- metadata.gz: a407f380c8f2295959533cd08966aace68f1d9d20208608a16269921ae167ba450e719663d918ff725ee10f0be6d020c2130d50873b51cc726b00bf4fa55b573
7
- data.tar.gz: 37f51f50d80ce4e51aeed85188b7bf48963723b0b1cf004bc6faceb5ec561c85c79d00887ca50ce4fe2ed702468677718b35c7cdaceb7af9db10fed5ce088381
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,38 +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
 
65
- ## Demos 🚀
72
+ ## Try Our Demos! 🎮 ✨
66
73
 
67
- Interested in more advanced configuration? Visit the demos in the [demo application](https://github.com/Mati365/ckeditor5-rails/tree/main/sandbox/app/views/demos) or take a look at official CKEditor 5 [examples](https://ckeditor.com/docs/ckeditor5/latest/examples/builds/classic-editor.html).
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
- In order to run all demos locally, you can clone the repository and run the following commands:
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
- cd sandbox
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
- Then visit [http://localhost:3000/demos](http://localhost:3000/) to see the demos in action. 🚀
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 🚀](#demos-)
91
+ - [Try Our Demos! 🎮 ✨](#try-our-demos--)
84
92
  - [Table of Contents 📚](#table-of-contents-)
85
93
  - [Presets 🎨](#presets-)
86
94
  - [Available Configuration Methods ⚙️](#available-configuration-methods-️)
87
95
  - [`cdn(cdn = nil, &block)` method](#cdncdn--nil-block-method)
88
96
  - [`version(version)` method](#versionversion-method)
97
+ - [`automatic_upgrades(enabled: true)` method](#automatic_upgradesenabled-true-method)
89
98
  - [`gpl` method](#gpl-method)
90
99
  - [`license_key(key)` method](#license_keykey-method)
91
100
  - [`premium` method](#premium-method)
@@ -101,6 +110,7 @@ Then visit [http://localhost:3000/demos](http://localhost:3000/) to see the demo
101
110
  - [`plugins(*names, **kwargs)` method](#pluginsnames-kwargs-method)
102
111
  - [`inline_plugin(name, code)` method](#inline_pluginname-code-method)
103
112
  - [`simple_upload_adapter(url)` method](#simple_upload_adapterurl-method)
113
+ - [Automatic upgrades 🔄](#automatic-upgrades-)
104
114
  - [Controller / View helpers 📦](#controller--view-helpers-)
105
115
  - [`ckeditor5_element_ref(selector)` method](#ckeditor5_element_refselector-method)
106
116
  - [`ckeditor5_preset(&block)` method](#ckeditor5_presetblock-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
 
@@ -254,6 +269,24 @@ CKEditor5::Rails.configure do
254
269
  end
255
270
  ```
256
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
+
257
290
  #### `gpl` method
258
291
 
259
292
  Defines the license of CKEditor 5. The example below shows how to set the license to GPL:
@@ -605,6 +638,22 @@ CKEditor5::Rails.configure do
605
638
  end
606
639
  ```
607
640
 
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.
646
+
647
+ ```rb
648
+ # config/initializers/ckeditor5.rb
649
+
650
+ CKEditor5::Rails.configure do
651
+ # ... other configuration
652
+
653
+ automatic_upgrades enabled: false
654
+ end
655
+ ```
656
+
608
657
  ### Controller / View helpers 📦
609
658
 
610
659
  #### `ckeditor5_element_ref(selector)` method
@@ -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: []
@@ -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
- @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
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
- 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.1'
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.1
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