ckeditor5 1.19.4 → 1.20.0
Sign up to get free protection for your applications and to get access to all the features.
- 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']")
|