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.
- checksums.yaml +4 -4
- data/Gemfile +5 -2
- data/README.md +2 -0
- data/lib/ckeditor5/rails/assets/assets_bundle_html_serializer.rb +43 -25
- data/lib/ckeditor5/rails/cdn/helpers.rb +81 -2
- data/lib/ckeditor5/rails/context/helpers.rb +28 -0
- data/lib/ckeditor5/rails/context/preset_builder.rb +33 -0
- data/lib/ckeditor5/rails/editor/helpers/config_helpers.rb +39 -0
- data/lib/ckeditor5/rails/editor/helpers/editor_helpers.rb +73 -13
- data/lib/ckeditor5/rails/engine.rb +11 -3
- data/lib/ckeditor5/rails/hooks/form.rb +44 -0
- data/lib/ckeditor5/rails/hooks/importmap.rb +58 -0
- data/lib/ckeditor5/rails/hooks/simple_form.rb +42 -0
- data/lib/ckeditor5/rails/presets/concerns/configuration_methods.rb +45 -0
- data/lib/ckeditor5/rails/presets/concerns/plugin_methods.rb +54 -0
- data/lib/ckeditor5/rails/presets/manager.rb +49 -0
- data/lib/ckeditor5/rails/presets/plugins_builder.rb +32 -0
- data/lib/ckeditor5/rails/presets/preset_builder.rb +117 -0
- data/lib/ckeditor5/rails/presets/toolbar_builder.rb +33 -0
- data/lib/ckeditor5/rails/version.rb +1 -1
- data/spec/e2e/features/editor_types_spec.rb +1 -1
- data/spec/e2e/spec_helper.rb +2 -7
- data/spec/lib/ckeditor5/rails/assets/{asset_bundle_hml_serializer_spec.rb → assets_bundle_hml_serializer_spec.rb} +58 -15
- data/spec/lib/ckeditor5/rails/cdn/helpers_spec.rb +41 -5
- data/spec/lib/ckeditor5/rails/engine_spec.rb +32 -0
- data/spec/lib/ckeditor5/rails/hooks/importmap_spec.rb +131 -0
- metadata +7 -4
@@ -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)
|
@@ -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
|
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']")
|