ckeditor5 1.19.5 → 1.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,7 +2,46 @@
2
2
 
3
3
  module CKEditor5::Rails::Hooks
4
4
  module SimpleForm
5
+ # Custom input type for Simple Form integration with CKEditor 5.
6
+ # This class enables seamless integration with Simple Form, allowing use of CKEditor 5
7
+ # as a form input with all its features and configurations.
8
+ #
9
+ # @example Basic usage in a form
10
+ # <%= simple_form_for @post do |f| %>
11
+ # <%= f.input :content,
12
+ # as: :ckeditor5,
13
+ # input_html: { style: 'width: 600px' },
14
+ # required: true
15
+ # %>
16
+ # <% end %>
17
+ #
18
+ # @example With custom preset and styling
19
+ # <%= simple_form_for @post do |f| %>
20
+ # <%= f.input :content,
21
+ # as: :ckeditor5,
22
+ # preset: :custom,
23
+ # type: :inline,
24
+ # input_html: {
25
+ # style: 'width: 600px',
26
+ # class: 'custom-editor',
27
+ # initial_data: 'Hello!'
28
+ # }
29
+ # %>
30
+ # <% end %>
31
+ #
32
+ # @example With validation and error handling
33
+ # <%= simple_form_for @post do |f| %>
34
+ # <%= f.input :content,
35
+ # as: :ckeditor5,
36
+ # required: true,
37
+ # input_html: { style: 'width: 600px' },
38
+ # error: 'Content cannot be blank'
39
+ # %>
40
+ # <% end %>
5
41
  class CKEditor5Input < ::SimpleForm::Inputs::Base
42
+ # Renders the CKEditor 5 input field
43
+ # @param wrapper_options [Hash] Options passed from the form wrapper
44
+ # @return [String] Rendered editor HTML
6
45
  def input(wrapper_options = nil)
7
46
  merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
8
47
  @builder.template.ckeditor5_editor(**editor_options(merged_input_options))
@@ -10,6 +49,9 @@ module CKEditor5::Rails::Hooks
10
49
 
11
50
  private
12
51
 
52
+ # Builds options hash for the editor
53
+ # @param merged_input_options [Hash] Combined input options
54
+ # @return [Hash] Options for CKEditor instance
13
55
  def editor_options(merged_input_options)
14
56
  {
15
57
  preset: input_options.fetch(:preset, :default),
@@ -5,6 +5,34 @@ require 'active_support'
5
5
  module CKEditor5::Rails
6
6
  module Presets
7
7
  module Concerns
8
+ # ConfigurationMethods provides functionality for configuring CKEditor 5 presets and instances.
9
+ #
10
+ # This module is included in preset builders and allows setting various configuration options
11
+ # for the editor.
12
+ #
13
+ # @example Basic configuration in preset
14
+ # presets.define :custom do
15
+ # configure :height, '400px'
16
+ # configure :width, '600px'
17
+ # end
18
+ #
19
+ # @example Complex configuration with nested options
20
+ # presets.define :custom do
21
+ # configure :image, {
22
+ # toolbar: ['imageTextAlternative', 'imageStyle:inline'],
23
+ # styles: ['alignLeft', 'alignCenter']
24
+ # }
25
+ # end
26
+ #
27
+ # @example Plugin-specific configuration
28
+ # presets.define :custom do
29
+ # configure :heading, {
30
+ # options: [
31
+ # { model: 'paragraph', title: 'Paragraph', class: 'ck-heading_paragraph' },
32
+ # { model: 'heading1', view: 'h1', title: 'Heading 1', class: 'ck-heading_heading1' }
33
+ # ]
34
+ # }
35
+ # end
8
36
  module ConfigurationMethods
9
37
  extend ActiveSupport::Concern
10
38
 
@@ -12,6 +40,23 @@ module CKEditor5::Rails
12
40
  attr_reader :config
13
41
  end
14
42
 
43
+ # Sets a configuration value for a given key in the editor configuration.
44
+ #
45
+ # @param key [Symbol, String] The configuration key
46
+ # @param value [Object] The configuration value
47
+ #
48
+ # @example Setting simple configuration
49
+ # configure :width, '500px'
50
+ #
51
+ # @example Setting plugin configuration
52
+ # configure :toolbar, ['bold', 'italic', '|', 'undo', 'redo']
53
+ #
54
+ # @example Setting nested configuration
55
+ # configure :image, {
56
+ # styles: {
57
+ # options: ['alignLeft', 'alignCenter']
58
+ # }
59
+ # }
15
60
  def configure(key, value)
16
61
  config[key] = value
17
62
  end
@@ -6,6 +6,10 @@ module CKEditor5::Rails
6
6
  module PluginMethods
7
7
  private
8
8
 
9
+ # Register a plugin in the editor configuration
10
+ #
11
+ # @param plugin_obj [Editor::PropsBasePlugin] Plugin instance to register
12
+ # @return [Editor::PropsBasePlugin] The registered plugin
9
13
  def register_plugin(plugin_obj)
10
14
  config[:plugins] << plugin_obj
11
15
  plugin_obj
@@ -13,19 +17,69 @@ module CKEditor5::Rails
13
17
 
14
18
  public
15
19
 
20
+ # Registers an external plugin loaded from a URL
21
+ #
22
+ # @param name [Symbol] Plugin name
23
+ # @param kwargs [Hash] Plugin options like :script, :import_as, :window_name, :stylesheets
24
+ # @example Load plugin from URL
25
+ # external_plugin :MyPlugin, script: 'https://example.com/plugin.js'
26
+ # @example Load with import alias
27
+ # external_plugin :MyPlugin,
28
+ # script: 'https://example.com/plugin.js',
29
+ # import_as: 'Plugin'
16
30
  def external_plugin(name, **kwargs)
17
31
  register_plugin(Editor::PropsExternalPlugin.new(name, **kwargs))
18
32
  end
19
33
 
34
+ # Registers an inline plugin with raw JavaScript code
35
+ #
36
+ # @param name [Symbol] Plugin name
37
+ # @param code [String] JavaScript code defining the plugin
38
+ # @example Define custom highlight plugin
39
+ # inline_plugin :MyCustomPlugin, <<~JS
40
+ # import { Plugin } from 'ckeditor5';
41
+ #
42
+ # export default class MyCustomPlugin extends Plugin {
43
+ # static get pluginName() {
44
+ # return 'MyCustomPlugin';
45
+ # }
46
+ #
47
+ # init() {
48
+ # // Plugin initialization code
49
+ # }
50
+ # }
51
+ # JS
20
52
  def inline_plugin(name, code)
21
53
  register_plugin(Editor::PropsInlinePlugin.new(name, code))
22
54
  end
23
55
 
56
+ # Register a single plugin by name
57
+ #
58
+ # @param name [Symbol, Editor::PropsBasePlugin] Plugin name or instance
59
+ # @param kwargs [Hash] Plugin configuration options
60
+ # @example Register standard plugin
61
+ # plugin :Bold
62
+ # @example Register premium plugin
63
+ # plugin :RealTimeCollaboration, premium: true
64
+ # @example Register custom plugin
65
+ # plugin :MyPlugin, import_name: 'my-custom-plugin'
24
66
  def plugin(name, **kwargs)
25
67
  premium(true) if kwargs[:premium] && respond_to?(:premium)
26
68
  register_plugin(PluginsBuilder.create_plugin(name, **kwargs))
27
69
  end
28
70
 
71
+ # Register multiple plugins and configure plugin settings
72
+ #
73
+ # @param names [Array<Symbol>] Plugin names to register
74
+ # @param kwargs [Hash] Shared plugin configuration
75
+ # @example Register multiple plugins
76
+ # plugins :Bold, :Italic, :Underline
77
+ # @example Configure plugins with block
78
+ # plugins do
79
+ # remove :Heading
80
+ # append :SelectAll, :RemoveFormat
81
+ # prepend :SourceEditing
82
+ # end
29
83
  def plugins(*names, **kwargs, &block)
30
84
  config[:plugins] ||= []
31
85
 
@@ -8,11 +8,28 @@ module CKEditor5::Rails::Presets
8
8
  class Manager
9
9
  attr_reader :presets
10
10
 
11
+ # Initializes a new Manager instance and sets up the default preset
11
12
  def initialize
12
13
  @presets = {}
13
14
  define_default_preset
14
15
  end
15
16
 
17
+ # Define a new preset configuration
18
+ #
19
+ # @param name [Symbol] Name of the preset
20
+ # @param inherit [Boolean] Whether to inherit from default preset
21
+ # @example Define custom preset inheriting from default
22
+ # presets.define :custom do
23
+ # menubar visible: false
24
+ # toolbar :bold, :italic
25
+ # end
26
+ # @example Define preset from scratch
27
+ # presets.define :blank, inherit: false do
28
+ # version '43.3.1'
29
+ # gpl
30
+ # type :classic
31
+ # end
32
+ # @return [PresetBuilder] Created preset instance
16
33
  def define(name, inherit: true, &block)
17
34
  preset = if inherit && default.present?
18
35
  default.clone
@@ -24,35 +41,66 @@ module CKEditor5::Rails::Presets
24
41
  @presets[name] = preset
25
42
  end
26
43
 
44
+ # Override existing preset configuration
45
+ #
46
+ # @param name [Symbol] Name of the preset to override
47
+ # @example Override existing preset
48
+ # presets.override :custom do
49
+ # menubar visible: false
50
+ # toolbar do
51
+ # remove :underline, :heading
52
+ # end
53
+ # end
27
54
  def override(name, &block)
28
55
  @presets[name].instance_eval(&block)
29
56
  end
30
57
 
31
58
  alias extend override
32
59
 
60
+ # Get the default preset configuration
61
+ # @return [PresetBuilder, nil] Default preset or nil if not defined
33
62
  def default
34
63
  @presets[:default]
35
64
  end
36
65
 
66
+ # Get a preset by name
67
+ # @param name [Symbol] Name of the preset
68
+ # @return [PresetBuilder, nil] Found preset or nil if not found
37
69
  def [](name)
38
70
  @presets[name]
39
71
  end
40
72
 
41
73
  private
42
74
 
75
+ # Defines the default preset with common editor settings
76
+ # @example Basic configuration
77
+ # CKEditor5::Rails.configure do
78
+ # presets.define :default do
79
+ # version '43.3.1'
80
+ # gpl
81
+ # type :classic
82
+ # menubar
83
+ # end
84
+ # end
43
85
  def define_default_preset
44
86
  define :default do
87
+ # Set default version from gem constant
45
88
  version CKEditor5::Rails::DEFAULT_CKEDITOR_VERSION
46
89
 
90
+ # Enable automatic version upgrades for security patches
47
91
  automatic_upgrades
92
+
93
+ # Use GPL license and classic editor type
48
94
  gpl
49
95
  type :classic
50
96
  menubar
51
97
 
98
+ # Configure default toolbar items
52
99
  toolbar :undo, :redo, :|, :heading, :|, :bold, :italic, :underline, :|,
53
100
  :link, :insertImage, :mediaEmbed, :insertTable, :blockQuote, :|,
54
101
  :bulletedList, :numberedList, :todoList, :outdent, :indent
55
102
 
103
+ # Configure default plugins
56
104
  plugins :AccessibilityHelp, :Autoformat, :AutoImage, :Autosave,
57
105
  :BlockQuote, :Bold, :CloudServices,
58
106
  :Essentials, :Heading, :ImageBlock, :ImageCaption, :ImageInline,
@@ -64,6 +112,7 @@ module CKEditor5::Rails::Presets
64
112
  :TableColumnResize, :TableProperties, :TableToolbar,
65
113
  :TextTransformation, :TodoList, :Underline, :Undo, :Base64UploadAdapter
66
114
 
115
+ # Configure default image toolbar
67
116
  configure :image, {
68
117
  toolbar: ['imageTextAlternative', 'imageStyle:inline', 'imageStyle:block', 'imageStyle:side']
69
118
  }
@@ -8,6 +8,11 @@ module CKEditor5::Rails
8
8
  @items = plugins
9
9
  end
10
10
 
11
+ # Creates a plugin instance from a name or returns the plugin if it's already a PropsBasePlugin
12
+ #
13
+ # @param name [Symbol, Editor::PropsBasePlugin] Plugin name or instance
14
+ # @param kwargs [Hash] Additional plugin configuration
15
+ # @return [Editor::PropsBasePlugin] Plugin instance
11
16
  def self.create_plugin(name, **kwargs)
12
17
  if name.is_a?(Editor::PropsBasePlugin)
13
18
  name
@@ -16,10 +21,27 @@ module CKEditor5::Rails
16
21
  end
17
22
  end
18
23
 
24
+ # Removes specified plugins from the editor configuration
25
+ #
26
+ # @param names [Array<Symbol>] Names of plugins to remove
27
+ # @example Remove plugins from configuration
28
+ # plugins do
29
+ # remove :Heading, :Link
30
+ # end
19
31
  def remove(*names)
20
32
  names.each { |name| items.delete_if { |plugin| plugin.name == name } }
21
33
  end
22
34
 
35
+ # Prepends plugins to the beginning of the plugins list or before a specific plugin
36
+ #
37
+ # @param names [Array<Symbol>] Names of plugins to prepend
38
+ # @param before [Symbol, nil] Optional plugin name before which to insert new plugins
39
+ # @param kwargs [Hash] Additional plugin configuration
40
+ # @raise [ArgumentError] When the specified 'before' plugin is not found
41
+ # @example Prepend plugins to configuration
42
+ # plugins do
43
+ # prepend :Bold, :Italic, before: :Link
44
+ # end
23
45
  def prepend(*names, before: nil, **kwargs)
24
46
  new_plugins = names.map { |name| self.class.create_plugin(name, **kwargs) }
25
47
 
@@ -33,6 +55,16 @@ module CKEditor5::Rails
33
55
  end
34
56
  end
35
57
 
58
+ # Appends plugins to the end of the plugins list or after a specific plugin
59
+ #
60
+ # @param names [Array<Symbol>] Names of plugins to append
61
+ # @param after [Symbol, nil] Optional plugin name after which to insert new plugins
62
+ # @param kwargs [Hash] Additional plugin configuration
63
+ # @raise [ArgumentError] When the specified 'after' plugin is not found
64
+ # @example Append plugins to configuration
65
+ # plugins do
66
+ # append :Bold, :Italic, after: :Link
67
+ # end
36
68
  def append(*names, after: nil, **kwargs)
37
69
  new_plugins = names.map { |name| self.class.create_plugin(name, **kwargs) }
38
70
 
@@ -10,6 +10,12 @@ module CKEditor5::Rails
10
10
  include Concerns::ConfigurationMethods
11
11
  include Concerns::PluginMethods
12
12
 
13
+ # @example Basic initialization
14
+ # PresetBuilder.new do
15
+ # version '43.3.1'
16
+ # gpl
17
+ # type :classic
18
+ # end
13
19
  def initialize(&block)
14
20
  @version = nil
15
21
  @premium = false
@@ -28,6 +34,9 @@ module CKEditor5::Rails
28
34
  instance_eval(&block) if block_given?
29
35
  end
30
36
 
37
+ # @example Copy preset and modify it
38
+ # original = PresetBuilder.new
39
+ # copied = original.initialize_copy(original)
31
40
  def initialize_copy(source)
32
41
  super
33
42
 
@@ -41,10 +50,14 @@ module CKEditor5::Rails
41
50
  )
42
51
  end
43
52
 
53
+ # Check if preset is using premium features
54
+ # @return [Boolean]
44
55
  def premium?
45
56
  @premium
46
57
  end
47
58
 
59
+ # Check if preset is using GPL license
60
+ # @return [Boolean]
48
61
  def gpl?
49
62
  license_key == 'GPL'
50
63
  end
@@ -55,12 +68,24 @@ module CKEditor5::Rails
55
68
  end
56
69
  end
57
70
 
71
+ # Create a new preset by overriding current configuration
72
+ # @example Override existing preset
73
+ # preset.override do
74
+ # menubar visible: false
75
+ # toolbar do
76
+ # remove :underline, :heading
77
+ # end
78
+ # end
79
+ # @return [PresetBuilder] New preset instance
58
80
  def override(&block)
59
81
  clone.tap do |preset|
60
82
  preset.instance_eval(&block)
61
83
  end
62
84
  end
63
85
 
86
+ # Merge preset with configuration hash
87
+ # @param overrides [Hash] Configuration options to merge
88
+ # @return [self]
64
89
  def merge_with_hash!(**overrides) # rubocop:disable Metrics/AbcSize
65
90
  @version = Semver.new(overrides[:version]) if overrides.key?(:version)
66
91
  @premium = overrides.fetch(:premium, premium)
@@ -76,12 +101,22 @@ module CKEditor5::Rails
76
101
  self
77
102
  end
78
103
 
104
+ # Set or get editable height in pixels
105
+ # @param height [Integer, nil] Height in pixels
106
+ # @example Set editor height to 300px
107
+ # editable_height 300
108
+ # @return [Integer, nil] Current height value
79
109
  def editable_height(height = nil)
80
110
  return @editable_height if height.nil?
81
111
 
82
112
  @editable_height = height
83
113
  end
84
114
 
115
+ # Configure CKBox integration
116
+ # @param version [String, nil] CKBox version
117
+ # @param theme [Symbol] Theme name (:lark)
118
+ # @example Enable CKBox with custom version
119
+ # ckbox '2.6.0', theme: :lark
85
120
  def ckbox(version = nil, theme: :lark)
86
121
  return @ckbox if version.nil?
87
122
 
@@ -91,6 +126,11 @@ module CKEditor5::Rails
91
126
  }
92
127
  end
93
128
 
129
+ # Set or get license key
130
+ # @param license_key [String, nil] License key
131
+ # @example Set commercial license
132
+ # license_key 'your-license-key'
133
+ # @return [String, nil] Current license key
94
134
  def license_key(license_key = nil)
95
135
  return @license_key if license_key.nil?
96
136
 
@@ -99,23 +139,41 @@ module CKEditor5::Rails
99
139
  cdn(:cloud) unless gpl?
100
140
  end
101
141
 
142
+ # Set GPL license and disable premium features
143
+ # @example Enable GPL license
144
+ # gpl
102
145
  def gpl
103
146
  license_key('GPL')
104
147
  premium(false)
105
148
  end
106
149
 
150
+ # Enable or check premium features
151
+ # @param premium [Boolean, nil] Enable/disable premium features
152
+ # @example Enable premium features
153
+ # premium true
154
+ # @return [Boolean] Premium status
107
155
  def premium(premium = nil)
108
156
  return @premium if premium.nil?
109
157
 
110
158
  @premium = premium
111
159
  end
112
160
 
161
+ # Set or get translations
162
+ # @param translations [Array<Symbol>] Language codes
163
+ # @example Add Polish and Spanish translations
164
+ # translations :pl, :es
165
+ # @return [Array<Symbol>] Current translations
113
166
  def translations(*translations)
114
167
  return @translations if translations.empty?
115
168
 
116
169
  @translations = translations
117
170
  end
118
171
 
172
+ # Set or get editor version
173
+ # @param version [String, nil] Editor version
174
+ # @example Set specific version
175
+ # version '43.3.1'
176
+ # @return [String, nil] Current version
119
177
  def version(version = nil)
120
178
  return @version&.to_s if version.nil?
121
179
 
@@ -127,14 +185,29 @@ module CKEditor5::Rails
127
185
  end
128
186
  end
129
187
 
188
+ # Enable or disable automatic version upgrades
189
+ # @param enabled [Boolean] Enable/disable upgrades
190
+ # @example Enable automatic upgrades
191
+ # automatic_upgrades enabled: true
130
192
  def automatic_upgrades(enabled: true)
131
193
  @automatic_upgrades = enabled
132
194
  end
133
195
 
196
+ # Check if automatic upgrades are enabled
197
+ # @return [Boolean]
134
198
  def automatic_upgrades?
135
199
  @automatic_upgrades
136
200
  end
137
201
 
202
+ # Configure CDN source
203
+ # @param cdn [Symbol, nil] CDN name or custom block
204
+ # @example Use jsDelivr CDN
205
+ # cdn :jsdelivr
206
+ # @example Custom CDN configuration
207
+ # cdn do |bundle, version, path|
208
+ # "https://custom-cdn.com/#{bundle}@#{version}/#{path}"
209
+ # end
210
+ # @return [Symbol, Proc] Current CDN configuration
138
211
  def cdn(cdn = nil, &block)
139
212
  return @cdn if cdn.nil? && block.nil?
140
213
 
@@ -150,6 +223,12 @@ module CKEditor5::Rails
150
223
  end
151
224
  end
152
225
 
226
+ # Set or get editor type
227
+ # @param type [Symbol, nil] Editor type (:classic, :inline, :balloon, :decoupled)
228
+ # @example Set editor type to inline
229
+ # type :inline
230
+ # @raise [ArgumentError] If invalid type provided
231
+ # @return [Symbol] Current editor type
153
232
  def type(type = nil)
154
233
  return @type if type.nil?
155
234
  raise ArgumentError, "Invalid editor type: #{type}" unless Editor::Props.valid_editor_type?(type)
@@ -157,16 +236,33 @@ module CKEditor5::Rails
157
236
  @type = type
158
237
  end
159
238
 
239
+ # Configure menubar visibility
240
+ # @param visible [Boolean] Show/hide menubar
241
+ # @example Hide menubar
242
+ # menubar visible: false
160
243
  def menubar(visible: true)
161
244
  config[:menuBar] = {
162
245
  isVisible: visible
163
246
  }
164
247
  end
165
248
 
249
+ # Check if menubar is visible
250
+ # @return [Boolean]
166
251
  def menubar?
167
252
  config.dig(:menuBar, :isVisible) || false
168
253
  end
169
254
 
255
+ # Configure toolbar items and grouping
256
+ # @param items [Array<Symbol>] Toolbar items
257
+ # @param should_group_when_full [Boolean] Enable grouping
258
+ # @example Configure toolbar items
259
+ # toolbar :bold, :italic, :|, :link
260
+ # @example Configure with block
261
+ # toolbar do
262
+ # append :selectAll
263
+ # remove :heading
264
+ # end
265
+ # @return [ToolbarBuilder] Toolbar configuration
170
266
  def toolbar(*items, should_group_when_full: true, &block)
171
267
  if @config[:toolbar].blank? || !items.empty?
172
268
  @config[:toolbar] = {
@@ -180,10 +276,20 @@ module CKEditor5::Rails
180
276
  builder
181
277
  end
182
278
 
279
+ # Check if language is configured
280
+ # @return [Boolean]
183
281
  def language?
184
282
  config[:language].present?
185
283
  end
186
284
 
285
+ # Configure editor language
286
+ # @param ui [Symbol, nil] UI language code
287
+ # @param content [Symbol] Content language code
288
+ # @example Set Polish UI and content language
289
+ # language :pl
290
+ # @example Different UI and content languages
291
+ # language :pl, content: :en
292
+ # @return [Hash, nil] Language configuration
187
293
  def language(ui = nil, content: ui) # rubocop:disable Naming/MethodParameterName
188
294
  return config[:language] if ui.nil?
189
295
 
@@ -195,6 +301,10 @@ module CKEditor5::Rails
195
301
  }
196
302
  end
197
303
 
304
+ # Configure simple upload adapter
305
+ # @param upload_url [String] Upload endpoint URL
306
+ # @example Enable upload adapter
307
+ # simple_upload_adapter '/uploads'
198
308
  def simple_upload_adapter(upload_url = '/uploads')
199
309
  plugins do
200
310
  remove(:Base64UploadAdapter)
@@ -204,6 +314,13 @@ module CKEditor5::Rails
204
314
  configure(:simpleUpload, { uploadUrl: upload_url })
205
315
  end
206
316
 
317
+ # Configure WProofreader plugin
318
+ # @param version [String, nil] Plugin version
319
+ # @param cdn [String, nil] CDN URL
320
+ # @param config [Hash] Plugin configuration
321
+ # @example Basic configuration
322
+ # wproofreader serviceId: 'your-service-ID',
323
+ # srcUrl: 'https://svc.webspellchecker.net/spellcheck31/wscbundle/wscbundle.js'
207
324
  def wproofreader(version: nil, cdn: nil, **config)
208
325
  configure :wproofreader, config
209
326
  plugins do
@@ -8,10 +8,30 @@ module CKEditor5::Rails::Presets
8
8
  @items = items
9
9
  end
10
10
 
11
+ # Remove items from the editor toolbar.
12
+ #
13
+ # @param removed_items [Array<Symbol>] Toolbar items to be removed
14
+ # @example Remove items from toolbar
15
+ # toolbar do
16
+ # remove :underline, :heading
17
+ # end
11
18
  def remove(*removed_items)
12
19
  removed_items.each { |item| items.delete(item) }
13
20
  end
14
21
 
22
+ # Prepend items to the editor toolbar.
23
+ #
24
+ # @param prepended_items [Array<Symbol>] Toolbar items to be prepended
25
+ # @param before [Symbol, nil] Optional item before which to insert new items
26
+ # @example Prepend items to toolbar
27
+ # toolbar do
28
+ # prepend :selectAll, :|, :selectAll, :selectAll
29
+ # end
30
+ # @example Insert items before specific item
31
+ # toolbar do
32
+ # prepend :selectAll, before: :bold
33
+ # end
34
+ # @raise [ArgumentError] When the specified 'before' item is not found
15
35
  def prepend(*prepended_items, before: nil)
16
36
  if before
17
37
  index = items.index(before)
@@ -23,6 +43,19 @@ module CKEditor5::Rails::Presets
23
43
  end
24
44
  end
25
45
 
46
+ # Append items to the editor toolbar.
47
+ #
48
+ # @param appended_items [Array<Symbol>] Toolbar items to be appended
49
+ # @param after [Symbol, nil] Optional item after which to insert new items
50
+ # @example Append items to toolbar
51
+ # toolbar do
52
+ # append :selectAll, :|, :selectAll, :selectAll
53
+ # end
54
+ # @example Insert items after specific item
55
+ # toolbar do
56
+ # append :selectAll, after: :bold
57
+ # end
58
+ # @raise [ArgumentError] When the specified 'after' item is not found
26
59
  def append(*appended_items, after: nil)
27
60
  if after
28
61
  index = items.index(after)
@@ -2,7 +2,7 @@
2
2
 
3
3
  module CKEditor5
4
4
  module Rails
5
- VERSION = '1.19.5'
5
+ VERSION = '1.20.0'
6
6
 
7
7
  DEFAULT_CKEDITOR_VERSION = '43.3.1'
8
8
  end
@@ -153,7 +153,7 @@ RSpec.describe 'CKEditor5 Types Integration', type: :feature, js: true do
153
153
  container.appendChild(newEditable);
154
154
  JS
155
155
 
156
- sleep 0.1 # Wait for component initialization
156
+ sleep 1 # Wait for component initialization
157
157
 
158
158
  # Find and interact with new editable
159
159
  new_editable = find("[name='new-root']")