ckeditor5 1.11.1 โ 1.14.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +4 -0
- data/README.md +103 -2
- data/lib/ckeditor5/rails/cdn/helpers.rb +1 -1
- data/lib/ckeditor5/rails/editor/helpers/config_helpers.rb +17 -0
- data/lib/ckeditor5/rails/editor/helpers/editor_helpers.rb +97 -0
- data/lib/ckeditor5/rails/editor/helpers.rb +4 -102
- data/lib/ckeditor5/rails/editor/props.rb +22 -2
- data/lib/ckeditor5/rails/editor/props_inline_plugin.rb +2 -2
- data/lib/ckeditor5/rails/editor/props_plugin.rb +2 -4
- data/lib/ckeditor5/rails/engine.rb +8 -0
- data/lib/ckeditor5/rails/helpers.rb +2 -1
- data/lib/ckeditor5/rails/plugins/simple_upload_adapter.rb +80 -0
- data/lib/ckeditor5/rails/presets/manager.rb +2 -1
- data/lib/ckeditor5/rails/presets/plugins_builder.rb +49 -0
- data/lib/ckeditor5/rails/presets/preset_builder.rb +28 -7
- data/lib/ckeditor5/rails/presets/toolbar_builder.rb +5 -7
- data/lib/ckeditor5/rails/semver.rb +0 -1
- data/lib/ckeditor5/rails/version.rb +1 -1
- data/spec/lib/ckeditor5/rails/cdn/url_generator_spec.rb +67 -0
- data/spec/lib/ckeditor5/rails/semver_spec.rb +45 -0
- data/spec/spec_helper.rb +60 -0
- metadata +12 -3
- data/lib/ckeditor5/rails/editor/config_helpers.rb +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6b4d6c95733dd5744553bb787f20f9efaf474086c6268d6842561905747ec10f
|
4
|
+
data.tar.gz: 17052fae7a4e0e88fcc7c0af8ab397c8fadb3421ce611c64a10fe597d15a9d82
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4dbaefb77863ceaeaad0805d430c86b90c7fbec675a7478fc55994a9706bfc3b8ec59c7791ce916389346da508f47a88ce2ff8c38a79d1c9189aa77405769f9f
|
7
|
+
data.tar.gz: 6b1d599bbfe28b35c81d037b052085c15fe55c1248f8e858efc77b7515c88b5ea2818187082f0db7810192b7d2cdfd3bb45d3dba57f7cf03cd0f53932dfbb202
|
data/Gemfile
CHANGED
@@ -8,7 +8,9 @@ group :development do
|
|
8
8
|
gem 'brakeman', '~> 6.1', '>= 6.1.1', require: false
|
9
9
|
gem 'guard', '~> 2.19', '>= 2.19.0'
|
10
10
|
gem 'guard-process', '~> 1.2'
|
11
|
+
gem 'guard-rspec', '~> 4.7', '>= 4.7.3'
|
11
12
|
gem 'pry', '~> 0.15', '>= 0.15.0'
|
13
|
+
gem 'pry-rails', '~> 0.3', '>= 0.3.11'
|
12
14
|
gem 'rails', '~> 7.0', '>= 7.0.0'
|
13
15
|
gem 'rake', '~> 13.2', '>= 13.2.1'
|
14
16
|
gem 'rspec', '~> 3.13'
|
@@ -17,6 +19,8 @@ group :development do
|
|
17
19
|
gem 'rubocop', '~> 1.66', require: false
|
18
20
|
gem 'rubocop-rails', '~> 2.26', '>= 2.26.2', require: false
|
19
21
|
gem 'rubocop-rails-omakase', '~> 1.0.0', require: false
|
22
|
+
gem 'simplecov', '~> 0.21', '>= 0.21.2', require: false
|
23
|
+
gem 'simplecov_json_formatter', '~> 0.1.4', require: false
|
20
24
|
gem 'simple_form', '~> 5.3', '>= 5.3.0'
|
21
25
|
gem 'slim', '~> 5.2', '>= 5.2.0'
|
22
26
|
gem 'sprockets-rails', '~> 3.2', '>= 3.2.2'
|
data/README.md
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
[![License: GPL v2](https://img.shields.io/badge/License-GPL_v2-blue.svg?style=flat-square)](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
|
4
4
|
![Gem Version](https://img.shields.io/gem/v/ckeditor5?style=flat-square)
|
5
5
|
![Gem Total Downloads](https://img.shields.io/gem/dt/ckeditor5?style=flat-square&color=orange)
|
6
|
+
[![Coverage](https://img.shields.io/codecov/c/github/mati365/ckeditor5-rails?style=flat-square)](https://codecov.io/gh/mati365/ckeditor5-rails)
|
6
7
|
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-green.svg?style=flat-square)](http://makeapullrequest.com)
|
7
8
|
![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/mati365/ckeditor5-rails?style=flat-square)
|
8
9
|
[![GitHub issues](https://img.shields.io/github/issues/mati365/ckeditor5-rails?style=flat-square)](https://github.com/Mati365/ckeditor5-rails/issues)
|
@@ -84,7 +85,10 @@ Voilร ! You have CKEditor 5 integrated with your Rails application. ๐
|
|
84
85
|
- [`plugin(name, premium:, import_name:)` method](#pluginname-premium-import_name-method)
|
85
86
|
- [`plugins(*names, **kwargs)` method](#pluginsnames-kwargs-method)
|
86
87
|
- [`inline_plugin(name, code)` method](#inline_pluginname-code-method)
|
88
|
+
- [`simple_upload_adapter(url)` method](#simple_upload_adapterurl-method)
|
89
|
+
- [Controller / View helpers ๐ฆ](#controller--view-helpers-)
|
87
90
|
- [`ckeditor5_element_ref(selector)` method](#ckeditor5_element_refselector-method)
|
91
|
+
- [`ckeditor5_preset(&block)` method](#ckeditor5_presetblock-method)
|
88
92
|
- [Including CKEditor 5 assets ๐ฆ](#including-ckeditor-5-assets-)
|
89
93
|
- [Format ๐](#format-)
|
90
94
|
- [Using default preset](#using-default-preset)
|
@@ -118,6 +122,7 @@ Voilร ! You have CKEditor 5 integrated with your Rails application. ๐
|
|
118
122
|
- [`editor-change` event](#editor-change-event)
|
119
123
|
- [Inline event handling](#inline-event-handling)
|
120
124
|
- [Gem Development ๐ ](#gem-development-)
|
125
|
+
- [Running tests ๐งช](#running-tests-)
|
121
126
|
- [Trademarks ๐](#trademarks-)
|
122
127
|
- [License ๐](#license-)
|
123
128
|
|
@@ -327,7 +332,7 @@ Defines the CKBox plugin to be included in the editor. The example below shows h
|
|
327
332
|
CKEditor5::Rails.configure do
|
328
333
|
# ... other configuration
|
329
334
|
|
330
|
-
ckbox '2.
|
335
|
+
ckbox '2.6.0', theme: :lark
|
331
336
|
end
|
332
337
|
```
|
333
338
|
|
@@ -530,6 +535,20 @@ CKEditor5::Rails.configure do
|
|
530
535
|
end
|
531
536
|
```
|
532
537
|
|
538
|
+
Methods such as `remove`, `append`, and `prepend` can be used to modify the plugins configuration. To remove a plugin, you can use the `remove` method with the plugin name as an argument:
|
539
|
+
|
540
|
+
```rb
|
541
|
+
# config/initializers/ckeditor5.rb
|
542
|
+
|
543
|
+
CKEditor5::Rails.configure do
|
544
|
+
# ... other configuration
|
545
|
+
|
546
|
+
plugins do
|
547
|
+
remove :Heading
|
548
|
+
end
|
549
|
+
end
|
550
|
+
```
|
551
|
+
|
533
552
|
#### `inline_plugin(name, code)` method
|
534
553
|
|
535
554
|
Use with caution as this is an inline definition of the plugin code, and you can define a custom class or function for the plugin here. The example below shows how to define a custom plugin that highlights the text:
|
@@ -556,6 +575,37 @@ CKEditor5::Rails.configure do
|
|
556
575
|
end
|
557
576
|
```
|
558
577
|
|
578
|
+
#### `simple_upload_adapter(url)` method
|
579
|
+
|
580
|
+
Defines the URL for the simple upload adapter. The default endpoint is `/uploads` and the method is `POST`. The example below shows how to set the URL to `/uploads`:
|
581
|
+
|
582
|
+
```rb
|
583
|
+
# config/initializers/ckeditor5.rb
|
584
|
+
|
585
|
+
CKEditor5::Rails.configure do
|
586
|
+
# ... other configuration
|
587
|
+
|
588
|
+
simple_upload_adapter
|
589
|
+
# or: simple_upload_adapter '/uploads'
|
590
|
+
end
|
591
|
+
```
|
592
|
+
|
593
|
+
Remember to remove the `Base64UploadAdapter` plugin from the plugins list if you want to use the simple upload adapter. It may cause issues.
|
594
|
+
|
595
|
+
```rb
|
596
|
+
# config/initializers/ckeditor5.rb
|
597
|
+
|
598
|
+
CKEditor5::Rails.configure do
|
599
|
+
# ... other configuration
|
600
|
+
|
601
|
+
plugins do
|
602
|
+
remove :Base64UploadAdapter
|
603
|
+
end
|
604
|
+
end
|
605
|
+
```
|
606
|
+
|
607
|
+
### Controller / View helpers ๐ฆ
|
608
|
+
|
559
609
|
#### `ckeditor5_element_ref(selector)` method
|
560
610
|
|
561
611
|
Defines a reference to a CKEditor 5 element. In other words, it allows you to reference DOM elements that will be used by the editor's features. It's particularly useful for features that need to check element presence or operate on specific DOM elements. The primary example is the `presence list` feature that requires a reference to the element that will be used to display the list.
|
@@ -572,6 +622,43 @@ CKEditor5::Rails.configure do
|
|
572
622
|
end
|
573
623
|
```
|
574
624
|
|
625
|
+
#### `ckeditor5_preset(&block)` method
|
626
|
+
|
627
|
+
The `ckeditor5_preset` method allows you to define a custom preset in your application controller. It may be useful when you want to define a preset based on the current user or request.
|
628
|
+
|
629
|
+
```rb
|
630
|
+
# app/controllers/application_controller.rb
|
631
|
+
|
632
|
+
class ApplicationController < ActionController::Base
|
633
|
+
def show
|
634
|
+
@preset = ckeditor5_preset do
|
635
|
+
version '43.3.0'
|
636
|
+
|
637
|
+
toolbar :sourceEditing, :|, :bold, :italic, :underline, :strikethrough,
|
638
|
+
:subscript, :superscript, :removeFormat, :|, :bulletedList, :numberedList,
|
639
|
+
:fontFamily, :fontSize, :|, :link, :anchor, :|,
|
640
|
+
:fontColor, :fontBackgroundColor
|
641
|
+
|
642
|
+
plugins :Essentials, :Paragraph, :Bold, :Italic, :Underline, :Strikethrough,
|
643
|
+
:Subscript, :Superscript, :RemoveFormat, :List, :Link, :Font,
|
644
|
+
:FontFamily, :FontSize, :FontColor, :FontBackgroundColor, :SourceEditing, :Essentials, :Paragraph
|
645
|
+
end
|
646
|
+
end
|
647
|
+
end
|
648
|
+
```
|
649
|
+
|
650
|
+
In order to use the preset in the view, you can pass it to the `ckeditor5_assets` helper method:
|
651
|
+
|
652
|
+
```erb
|
653
|
+
<!-- app/views/demos/index.html.erb -->
|
654
|
+
|
655
|
+
<% content_for :head do %>
|
656
|
+
<%= ckeditor5_assets preset: @preset %>
|
657
|
+
<% end %>
|
658
|
+
|
659
|
+
<%= ckeditor5_editor %>
|
660
|
+
```
|
661
|
+
|
575
662
|
## Including CKEditor 5 assets ๐ฆ
|
576
663
|
|
577
664
|
To include CKEditor 5 assets in your application, you can use the `ckeditor5_assets` helper method. This method takes the version of CKEditor 5 as an argument and includes the necessary resources of the editor. Depending on the specified configuration, it includes the JS and CSS assets from the official CKEditor 5 CDN or one of the popular CDNs.
|
@@ -1329,7 +1416,21 @@ If you want to contribute to the gem, you can clone the repository and run the f
|
|
1329
1416
|
```sh
|
1330
1417
|
gem install bundler -v 2.5.22
|
1331
1418
|
bundle install
|
1332
|
-
bundle exec guard
|
1419
|
+
bundle exec guard -g rails
|
1420
|
+
```
|
1421
|
+
|
1422
|
+
### Running tests ๐งช
|
1423
|
+
|
1424
|
+
You can run the tests using the following command:
|
1425
|
+
|
1426
|
+
```sh
|
1427
|
+
bundle exec rspec
|
1428
|
+
```
|
1429
|
+
|
1430
|
+
If you want to watch the tests, you can use the following command:
|
1431
|
+
|
1432
|
+
```sh
|
1433
|
+
bundle exec guard -g rspec
|
1333
1434
|
```
|
1334
1435
|
|
1335
1436
|
## Trademarks ๐
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CKEditor5::Rails
|
4
|
+
module Editor::Helpers::Config
|
5
|
+
def ckeditor5_element_ref(selector)
|
6
|
+
{ '$element': selector }
|
7
|
+
end
|
8
|
+
|
9
|
+
def ckeditor5_preset(name = nil, &block)
|
10
|
+
return Engine.find_preset(name) if name
|
11
|
+
|
12
|
+
raise ArgumentError, 'Configuration block is required for preset definition' unless block_given?
|
13
|
+
|
14
|
+
CKEditor5::Rails::Presets::PresetBuilder.new(&block)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'config_helpers'
|
4
|
+
|
5
|
+
module CKEditor5::Rails
|
6
|
+
module Editor::Helpers::Editor
|
7
|
+
include Editor::Helpers::Config
|
8
|
+
|
9
|
+
class EditorContextError < StandardError; end
|
10
|
+
class PresetNotFoundError < ArgumentError; end
|
11
|
+
class InvalidEditableHeightError < ArgumentError; end
|
12
|
+
|
13
|
+
# Creates a CKEditor 5 editor instance
|
14
|
+
#
|
15
|
+
# @param preset [Symbol] High-level configuration preset that defines base editor setup,
|
16
|
+
# including editor type, plugins, and default configuration
|
17
|
+
# @param config [Hash] Editor-specific configuration that overrides preset defaults
|
18
|
+
# @param extra_config [Hash] Additional configuration to be merged with the base config
|
19
|
+
# @param type [Symbol] Editor type (:classic, :inline, :balloon, :decoupled, :multiroot),
|
20
|
+
# defaults to preset's type if not specified
|
21
|
+
# @param initial_data [String] Initial content for the editor
|
22
|
+
# @param watchdog [Boolean] Whether to enable the CKEditor watchdog feature
|
23
|
+
# @param editable_height [String, Integer] Height of the editable area (Classic editor only)
|
24
|
+
# @param html_attributes [Hash] Additional HTML attributes for the editor element
|
25
|
+
def ckeditor5_editor( # rubocop:disable Metrics/ParameterLists
|
26
|
+
preset: nil,
|
27
|
+
config: nil, extra_config: {}, type: nil,
|
28
|
+
initial_data: nil, watchdog: true,
|
29
|
+
editable_height: nil,
|
30
|
+
**html_attributes, &block
|
31
|
+
)
|
32
|
+
validate_editor_input!(initial_data, block)
|
33
|
+
|
34
|
+
controller_context = validate_and_get_editor_context!
|
35
|
+
|
36
|
+
preset = find_preset(preset || controller_context[:preset] || :default)
|
37
|
+
config = build_editor_config(preset, config, extra_config, initial_data)
|
38
|
+
type ||= preset.type
|
39
|
+
|
40
|
+
editor_props = Editor::Props.new(
|
41
|
+
controller_context, type, config,
|
42
|
+
watchdog: watchdog,
|
43
|
+
editable_height: editable_height
|
44
|
+
)
|
45
|
+
|
46
|
+
tag_attributes = html_attributes.merge(editor_props.to_attributes)
|
47
|
+
|
48
|
+
tag.send(:'ckeditor-component', **tag_attributes, &block)
|
49
|
+
end
|
50
|
+
|
51
|
+
def ckeditor5_editable(name = nil, **kwargs, &block)
|
52
|
+
tag.send(:'ckeditor-editable-component', name: name, **kwargs, &block)
|
53
|
+
end
|
54
|
+
|
55
|
+
def ckeditor5_ui_part(name, **kwargs, &block)
|
56
|
+
tag.send(:'ckeditor-ui-part-component', name: name, **kwargs, &block)
|
57
|
+
end
|
58
|
+
|
59
|
+
def ckeditor5_toolbar(**kwargs)
|
60
|
+
ckeditor5_ui_part('toolbar', **kwargs)
|
61
|
+
end
|
62
|
+
|
63
|
+
def ckeditor5_menubar(**kwargs)
|
64
|
+
ckeditor5_ui_part('menuBarView', **kwargs)
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def validate_editor_input!(initial_data, block)
|
70
|
+
return unless initial_data && block
|
71
|
+
|
72
|
+
raise ArgumentError, 'Cannot pass initial data and block at the same time.'
|
73
|
+
end
|
74
|
+
|
75
|
+
def build_editor_config(preset, config, extra_config, initial_data)
|
76
|
+
editor_config = config || preset.config
|
77
|
+
editor_config = editor_config.deep_merge(extra_config)
|
78
|
+
editor_config[:initialData] = initial_data if initial_data
|
79
|
+
editor_config
|
80
|
+
end
|
81
|
+
|
82
|
+
def validate_and_get_editor_context!
|
83
|
+
unless defined?(@__ckeditor_context)
|
84
|
+
raise EditorContextError,
|
85
|
+
'CKEditor installation context is not defined. ' \
|
86
|
+
'Ensure ckeditor5_assets is called in the head section.'
|
87
|
+
end
|
88
|
+
|
89
|
+
@__ckeditor_context
|
90
|
+
end
|
91
|
+
|
92
|
+
def find_preset(preset)
|
93
|
+
Engine.find_preset(preset) or
|
94
|
+
raise PresetNotFoundError, "Preset #{preset} is not defined."
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -3,107 +3,9 @@
|
|
3
3
|
require_relative 'props_plugin'
|
4
4
|
require_relative 'props_inline_plugin'
|
5
5
|
require_relative 'props'
|
6
|
-
require_relative 'config_helpers'
|
7
6
|
|
8
|
-
module CKEditor5::Rails
|
9
|
-
module Editor::Helpers
|
10
|
-
include Editor::ConfigHelpers
|
11
|
-
|
12
|
-
class EditorContextError < StandardError; end
|
13
|
-
class PresetNotFoundError < ArgumentError; end
|
14
|
-
class InvalidEditableHeightError < ArgumentError; end
|
15
|
-
|
16
|
-
def ckeditor5_editor( # rubocop:disable Metrics/ParameterLists
|
17
|
-
config: nil, extra_config: {},
|
18
|
-
type: nil, preset: nil,
|
19
|
-
initial_data: nil, watchdog: true,
|
20
|
-
editable_height: nil,
|
21
|
-
**html_attributes, &block
|
22
|
-
)
|
23
|
-
validate_editor_input!(initial_data, block)
|
24
|
-
|
25
|
-
controller_context = validate_and_get_editor_context!
|
26
|
-
|
27
|
-
preset = resolve_editor_preset(preset || controller_context[:preset])
|
28
|
-
config = build_editor_config(preset, config, extra_config, initial_data)
|
29
|
-
type ||= preset.type
|
30
|
-
|
31
|
-
validated_height = validate_editable_height(type, editable_height) || preset.editable_height
|
32
|
-
editor_props = Editor::Props.new(controller_context, type, config, watchdog: watchdog)
|
33
|
-
|
34
|
-
tag_attributes = html_attributes
|
35
|
-
.merge(editor_props.to_attributes)
|
36
|
-
.merge(validated_height ? { 'editable-height' => validated_height } : {})
|
37
|
-
|
38
|
-
tag.send(:'ckeditor-component', **tag_attributes, &block)
|
39
|
-
end
|
40
|
-
|
41
|
-
def ckeditor5_editable(name = nil, **kwargs, &block)
|
42
|
-
tag.send(:'ckeditor-editable-component', name: name, **kwargs, &block)
|
43
|
-
end
|
44
|
-
|
45
|
-
def ckeditor5_ui_part(name, **kwargs, &block)
|
46
|
-
tag.send(:'ckeditor-ui-part-component', name: name, **kwargs, &block)
|
47
|
-
end
|
48
|
-
|
49
|
-
def ckeditor5_toolbar(**kwargs)
|
50
|
-
ckeditor5_ui_part('toolbar', **kwargs)
|
51
|
-
end
|
52
|
-
|
53
|
-
def ckeditor5_menubar(**kwargs)
|
54
|
-
ckeditor5_ui_part('menuBarView', **kwargs)
|
55
|
-
end
|
56
|
-
|
57
|
-
private
|
58
|
-
|
59
|
-
def validate_editor_input!(initial_data, block)
|
60
|
-
return unless initial_data && block
|
61
|
-
|
62
|
-
raise ArgumentError, 'Cannot pass initial data and block at the same time.'
|
63
|
-
end
|
64
|
-
|
65
|
-
def resolve_editor_preset(preset_name)
|
66
|
-
fetch_editor_preset(preset_name || :default)
|
67
|
-
end
|
68
|
-
|
69
|
-
def build_editor_config(preset, config, extra_config, initial_data)
|
70
|
-
editor_config = config || preset.config
|
71
|
-
editor_config = editor_config.deep_merge(extra_config)
|
72
|
-
editor_config[:initialData] = initial_data if initial_data
|
73
|
-
editor_config
|
74
|
-
end
|
75
|
-
|
76
|
-
def validate_and_get_editor_context!
|
77
|
-
unless defined?(@__ckeditor_context)
|
78
|
-
raise EditorContextError,
|
79
|
-
'CKEditor installation context is not defined. ' \
|
80
|
-
'Ensure ckeditor5_assets is called in the head section.'
|
81
|
-
end
|
82
|
-
|
83
|
-
@__ckeditor_context
|
84
|
-
end
|
85
|
-
|
86
|
-
def fetch_editor_preset(preset)
|
87
|
-
Engine.base.presets[preset] or
|
88
|
-
raise PresetNotFoundError, "Preset #{preset} is not defined."
|
89
|
-
end
|
90
|
-
|
91
|
-
def validate_editable_height(type, height)
|
92
|
-
return nil if height.nil?
|
93
|
-
|
94
|
-
unless type == :classic
|
95
|
-
raise InvalidEditableHeightError,
|
96
|
-
'editable_height can be used only with ClassicEditor'
|
97
|
-
end
|
98
|
-
|
99
|
-
case height
|
100
|
-
when String, /^\d+px$/ then height
|
101
|
-
when Integer, /^\d+$/ then "#{height}px"
|
102
|
-
else
|
103
|
-
raise InvalidEditableHeightError,
|
104
|
-
"editable_height must be an integer representing pixels or string ending with 'px'\n" \
|
105
|
-
"(e.g. 500 or '500px'). Got: #{height.inspect}"
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
7
|
+
module CKEditor5::Rails::Editor::Helpers
|
109
8
|
end
|
9
|
+
|
10
|
+
require_relative 'helpers/config_helpers'
|
11
|
+
require_relative 'helpers/editor_helpers'
|
@@ -12,13 +12,14 @@ module CKEditor5::Rails::Editor
|
|
12
12
|
multiroot: 'MultiRootEditor'
|
13
13
|
}.freeze
|
14
14
|
|
15
|
-
def initialize(controller_context, type, config, watchdog: true)
|
15
|
+
def initialize(controller_context, type, config, watchdog: true, editable_height: nil)
|
16
16
|
raise ArgumentError, "Invalid editor type: #{type}" unless Props.valid_editor_type?(type)
|
17
17
|
|
18
18
|
@controller_context = controller_context
|
19
19
|
@watchdog = watchdog
|
20
20
|
@type = type
|
21
21
|
@config = config
|
22
|
+
@editable_height = normalize_editable_height(editable_height)
|
22
23
|
end
|
23
24
|
|
24
25
|
def to_attributes
|
@@ -34,7 +35,7 @@ module CKEditor5::Rails::Editor
|
|
34
35
|
|
35
36
|
private
|
36
37
|
|
37
|
-
attr_reader :controller_context, :watchdog, :type, :config
|
38
|
+
attr_reader :controller_context, :watchdog, :type, :config, :editable_height
|
38
39
|
|
39
40
|
def serialized_attributes
|
40
41
|
{
|
@@ -43,6 +44,7 @@ module CKEditor5::Rails::Editor
|
|
43
44
|
config: serialize_config,
|
44
45
|
watchdog: watchdog
|
45
46
|
}
|
47
|
+
.merge(editable_height ? { 'editable-height' => editable_height } : {})
|
46
48
|
end
|
47
49
|
|
48
50
|
def serialize_translations
|
@@ -59,5 +61,23 @@ module CKEditor5::Rails::Editor
|
|
59
61
|
.tap { |cfg| cfg[:licenseKey] = controller_context[:license_key] if controller_context[:license_key] }
|
60
62
|
.to_json
|
61
63
|
end
|
64
|
+
|
65
|
+
def normalize_editable_height(editable_height)
|
66
|
+
return nil if editable_height.nil?
|
67
|
+
|
68
|
+
unless type == :classic
|
69
|
+
raise InvalidEditableHeightError,
|
70
|
+
'editable_height can be used only with ClassicEditor'
|
71
|
+
end
|
72
|
+
|
73
|
+
case editable_height
|
74
|
+
when String, /^\d+px$/ then editable_height
|
75
|
+
when Integer, /^\d+$/ then "#{editable_height}px"
|
76
|
+
else
|
77
|
+
raise InvalidEditableHeightError,
|
78
|
+
"editable_height must be an integer representing pixels or string ending with 'px'\n" \
|
79
|
+
"(e.g. 500 or '500px'). Got: #{editable_height.inspect}"
|
80
|
+
end
|
81
|
+
end
|
62
82
|
end
|
63
83
|
end
|
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
module CKEditor5::Rails::Editor
|
4
4
|
class PropsInlinePlugin
|
5
|
+
attr_reader :name, :code
|
6
|
+
|
5
7
|
def initialize(name, code)
|
6
8
|
@name = name
|
7
9
|
@code = code
|
@@ -18,8 +20,6 @@ module CKEditor5::Rails::Editor
|
|
18
20
|
|
19
21
|
private
|
20
22
|
|
21
|
-
attr_reader :name, :code
|
22
|
-
|
23
23
|
def validate_code!
|
24
24
|
raise ArgumentError, 'Code must be a String' unless code.is_a?(String)
|
25
25
|
|
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
module CKEditor5::Rails::Editor
|
4
4
|
class PropsPlugin
|
5
|
+
attr_reader :name, :js_import_meta
|
6
|
+
|
5
7
|
delegate :to_h, to: :import_meta
|
6
8
|
|
7
9
|
def initialize(name, premium: false, **js_import_meta)
|
@@ -30,9 +32,5 @@ module CKEditor5::Rails::Editor
|
|
30
32
|
meta.merge!({ type: :external })
|
31
33
|
meta
|
32
34
|
end
|
33
|
-
|
34
|
-
private
|
35
|
-
|
36
|
-
attr_reader :name, :js_import_meta
|
37
35
|
end
|
38
36
|
end
|
@@ -4,6 +4,7 @@ require 'rails/engine'
|
|
4
4
|
|
5
5
|
require_relative 'presets/manager'
|
6
6
|
require_relative 'hooks/form'
|
7
|
+
require_relative 'plugins/simple_upload_adapter'
|
7
8
|
|
8
9
|
module CKEditor5::Rails
|
9
10
|
class Engine < ::Rails::Engine
|
@@ -12,6 +13,7 @@ module CKEditor5::Rails
|
|
12
13
|
|
13
14
|
initializer 'helper' do
|
14
15
|
ActiveSupport.on_load(:action_view) { include Helpers }
|
16
|
+
ActiveSupport.on_load(:action_controller) { include Helpers }
|
15
17
|
end
|
16
18
|
|
17
19
|
initializer 'ckeditor5.simple_form', after: :load_config_initializers do
|
@@ -39,6 +41,12 @@ module CKEditor5::Rails
|
|
39
41
|
proxy = ConfigurationProxy.new(config.ckeditor5)
|
40
42
|
proxy.instance_eval(&block)
|
41
43
|
end
|
44
|
+
|
45
|
+
def find_preset(preset)
|
46
|
+
return preset if preset.is_a?(CKEditor5::Rails::Presets::PresetBuilder)
|
47
|
+
|
48
|
+
Engine.base.presets[preset]
|
49
|
+
end
|
42
50
|
end
|
43
51
|
|
44
52
|
class ConfigurationProxy
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CKEditor5::Rails::Plugins
|
4
|
+
class SimpleUploadAdapter < CKEditor5::Rails::Editor::PropsInlinePlugin
|
5
|
+
PLUGIN_CODE = <<~JAVASCRIPT
|
6
|
+
import { Plugin, FileRepository } from 'ckeditor5';
|
7
|
+
|
8
|
+
export default class SimpleUploadAdapter extends Plugin {
|
9
|
+
static get requires() {
|
10
|
+
return [FileRepository];
|
11
|
+
}
|
12
|
+
|
13
|
+
static get pluginName() {
|
14
|
+
return 'SimpleUploadAdapter';
|
15
|
+
}
|
16
|
+
|
17
|
+
init() {
|
18
|
+
const fileRepository = this.editor.plugins.get(FileRepository);
|
19
|
+
const config = this.editor.config.get('simpleUpload');
|
20
|
+
|
21
|
+
if (!config || !config.uploadUrl) {
|
22
|
+
console.warn('Upload URL is not configured');
|
23
|
+
return;
|
24
|
+
}
|
25
|
+
|
26
|
+
fileRepository.createUploadAdapter = (loader) => ({
|
27
|
+
async upload() {
|
28
|
+
try {
|
29
|
+
const file = await loader.file;
|
30
|
+
const formData = new FormData();
|
31
|
+
formData.append('upload', file);
|
32
|
+
|
33
|
+
return new Promise((resolve, reject) => {
|
34
|
+
const xhr = new XMLHttpRequest();
|
35
|
+
|
36
|
+
xhr.open('POST', config.uploadUrl, true);
|
37
|
+
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
|
38
|
+
|
39
|
+
xhr.upload.onprogress = (evt) => {
|
40
|
+
if (evt.lengthComputable) {
|
41
|
+
loader.uploadTotal = evt.total;
|
42
|
+
loader.uploaded = evt.loaded;
|
43
|
+
}
|
44
|
+
};
|
45
|
+
|
46
|
+
xhr.onload = () => {
|
47
|
+
if (xhr.status >= 200 && xhr.status < 300) {
|
48
|
+
const data = JSON.parse(xhr.response);
|
49
|
+
resolve({ default: data.url });
|
50
|
+
} else {
|
51
|
+
reject(`Upload failed: ${xhr.statusText}`);
|
52
|
+
}
|
53
|
+
};
|
54
|
+
|
55
|
+
xhr.onerror = () => reject('Upload failed');
|
56
|
+
xhr.onabort = () => reject('Upload aborted');
|
57
|
+
|
58
|
+
xhr.send(formData);
|
59
|
+
this._xhr = xhr;
|
60
|
+
});
|
61
|
+
} catch (error) {
|
62
|
+
throw error;
|
63
|
+
}
|
64
|
+
},
|
65
|
+
|
66
|
+
abort() {
|
67
|
+
if (this._xhr) {
|
68
|
+
this._xhr.abort();
|
69
|
+
}
|
70
|
+
}
|
71
|
+
});
|
72
|
+
}
|
73
|
+
}
|
74
|
+
JAVASCRIPT
|
75
|
+
|
76
|
+
def initialize
|
77
|
+
super(:SimpleUpload, PLUGIN_CODE)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CKEditor5::Rails
|
4
|
+
class Presets::PluginsBuilder
|
5
|
+
attr_reader :plugins
|
6
|
+
|
7
|
+
def initialize(plugins)
|
8
|
+
@plugins = plugins
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.create_plugin(name, **kwargs)
|
12
|
+
if name.is_a?(Editor::PropsInlinePlugin) || name.is_a?(Editor::PropsPlugin)
|
13
|
+
name
|
14
|
+
else
|
15
|
+
Editor::PropsPlugin.new(name, **kwargs)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def remove(*names)
|
20
|
+
names.each { |name| plugins.delete_if { |plugin| plugin.name == name } }
|
21
|
+
end
|
22
|
+
|
23
|
+
def prepend(*names, before: nil, **kwargs)
|
24
|
+
new_plugins = names.map { |name| self.class.create_plugin(name, **kwargs) }
|
25
|
+
|
26
|
+
if before
|
27
|
+
index = plugins.index { |p| p.name == before }
|
28
|
+
raise ArgumentError, "Plugin '#{before}' not found" unless index
|
29
|
+
|
30
|
+
plugins.insert(index, *new_plugins)
|
31
|
+
else
|
32
|
+
plugins.insert(0, *new_plugins)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def append(*names, after: nil, **kwargs)
|
37
|
+
new_plugins = names.map { |name| self.class.create_plugin(name, **kwargs) }
|
38
|
+
|
39
|
+
if after
|
40
|
+
index = plugins.index { |p| p.name == after }
|
41
|
+
raise ArgumentError, "Plugin '#{after}' not found" unless index
|
42
|
+
|
43
|
+
plugins.insert(index + 1, *new_plugins)
|
44
|
+
else
|
45
|
+
plugins.push(*new_plugins)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -3,15 +3,15 @@
|
|
3
3
|
module CKEditor5::Rails
|
4
4
|
module Presets
|
5
5
|
class PresetBuilder
|
6
|
-
include Editor::
|
6
|
+
include Editor::Helpers::Config
|
7
7
|
|
8
8
|
attr_reader :config
|
9
9
|
|
10
|
-
def initialize
|
10
|
+
def initialize(&block)
|
11
11
|
@version = nil
|
12
12
|
@premium = false
|
13
13
|
@cdn = :jsdelivr
|
14
|
-
@translations = []
|
14
|
+
@translations = [:en]
|
15
15
|
@license_key = nil
|
16
16
|
@type = :classic
|
17
17
|
@ckbox = nil
|
@@ -20,6 +20,8 @@ module CKEditor5::Rails
|
|
20
20
|
plugins: [],
|
21
21
|
toolbar: []
|
22
22
|
}
|
23
|
+
|
24
|
+
instance_eval(&block) if block_given?
|
23
25
|
end
|
24
26
|
|
25
27
|
def premium?
|
@@ -135,7 +137,7 @@ module CKEditor5::Rails
|
|
135
137
|
|
136
138
|
return unless block
|
137
139
|
|
138
|
-
builder =
|
140
|
+
builder = ArrayBuilder.new(@config[:toolbar][:items])
|
139
141
|
builder.instance_eval(&block)
|
140
142
|
end
|
141
143
|
|
@@ -144,11 +146,21 @@ module CKEditor5::Rails
|
|
144
146
|
end
|
145
147
|
|
146
148
|
def plugin(name, **kwargs)
|
147
|
-
|
149
|
+
plugin_obj = PluginsBuilder.create_plugin(name, **kwargs)
|
150
|
+
|
151
|
+
@config[:plugins] << plugin_obj
|
152
|
+
plugin_obj
|
148
153
|
end
|
149
154
|
|
150
|
-
def plugins(*names, **kwargs)
|
151
|
-
|
155
|
+
def plugins(*names, **kwargs, &block)
|
156
|
+
@config[:plugins] ||= []
|
157
|
+
|
158
|
+
names.each { |name| plugin(name, **kwargs) } unless names.empty?
|
159
|
+
|
160
|
+
return unless block
|
161
|
+
|
162
|
+
builder = PluginsBuilder.new(@config[:plugins])
|
163
|
+
builder.instance_eval(&block)
|
152
164
|
end
|
153
165
|
|
154
166
|
def language(ui = nil, content: ui) # rubocop:disable Naming/MethodParameterName
|
@@ -159,6 +171,15 @@ module CKEditor5::Rails
|
|
159
171
|
content: content
|
160
172
|
}
|
161
173
|
end
|
174
|
+
|
175
|
+
def simple_upload_adapter(upload_url = '/uploads')
|
176
|
+
plugins do
|
177
|
+
remove :Base64UploadAdapter
|
178
|
+
end
|
179
|
+
|
180
|
+
plugin(Plugins::SimpleUploadAdapter.new)
|
181
|
+
configure(:simpleUpload, { uploadUrl: upload_url })
|
182
|
+
end
|
162
183
|
end
|
163
184
|
end
|
164
185
|
end
|
@@ -2,12 +2,10 @@
|
|
2
2
|
|
3
3
|
module CKEditor5::Rails::Presets
|
4
4
|
class ToolbarBuilder
|
5
|
-
|
6
|
-
@toolbar_config = toolbar_config
|
7
|
-
end
|
5
|
+
attr_reader :items
|
8
6
|
|
9
|
-
def items
|
10
|
-
@
|
7
|
+
def initialize(items)
|
8
|
+
@items = items
|
11
9
|
end
|
12
10
|
|
13
11
|
def remove(*removed_items)
|
@@ -17,7 +15,7 @@ module CKEditor5::Rails::Presets
|
|
17
15
|
def prepend(*prepended_items, before: nil)
|
18
16
|
if before
|
19
17
|
index = items.index(before)
|
20
|
-
raise ArgumentError, "Item '#{before}' not found in
|
18
|
+
raise ArgumentError, "Item '#{before}' not found in array" unless index
|
21
19
|
|
22
20
|
items.insert(index, *prepended_items)
|
23
21
|
else
|
@@ -28,7 +26,7 @@ module CKEditor5::Rails::Presets
|
|
28
26
|
def append(*appended_items, after: nil)
|
29
27
|
if after
|
30
28
|
index = items.index(after)
|
31
|
-
raise ArgumentError, "Item '#{after}' not found in
|
29
|
+
raise ArgumentError, "Item '#{after}' not found in array" unless index
|
32
30
|
|
33
31
|
items.insert(index + 1, *appended_items)
|
34
32
|
else
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe CKEditor5::Rails::Cdn::UrlGenerator do
|
6
|
+
let(:test_class) do
|
7
|
+
Class.new do
|
8
|
+
include CKEditor5::Rails::Cdn::UrlGenerator
|
9
|
+
|
10
|
+
attr_writer :cdn
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:instance) { test_class.new }
|
15
|
+
|
16
|
+
shared_examples 'a CDN provider' do |cdn, url_pattern|
|
17
|
+
before { instance.cdn = cdn }
|
18
|
+
|
19
|
+
it 'generates correct URL' do
|
20
|
+
expect(instance.create_cdn_url('ckeditor5', '34.1.0', 'ckeditor.js'))
|
21
|
+
.to eq(format(url_pattern, version: '34.1.0'))
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#create_cdn_url' do
|
26
|
+
context 'with open-source CDNs' do
|
27
|
+
it_behaves_like 'a CDN provider', :jsdelivr,
|
28
|
+
'https://cdn.jsdelivr.net/npm/ckeditor5@%<version>s/dist/browser/ckeditor.js'
|
29
|
+
|
30
|
+
it_behaves_like 'a CDN provider', :unpkg,
|
31
|
+
'https://unpkg.com/ckeditor5@%<version>s/dist/browser/ckeditor.js'
|
32
|
+
|
33
|
+
context 'with translations' do
|
34
|
+
it 'handles translation paths correctly for jsdelivr' do
|
35
|
+
instance.cdn = :jsdelivr
|
36
|
+
expect(instance.create_cdn_url('ckeditor5', '34.1.0', 'translations/pl.js'))
|
37
|
+
.to eq('https://cdn.jsdelivr.net/npm/ckeditor5@34.1.0/dist/translations/pl.js')
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'handles translation paths correctly for unpkg' do
|
41
|
+
instance.cdn = :unpkg
|
42
|
+
expect(instance.create_cdn_url('ckeditor5', '34.1.0', 'translations/pl.js'))
|
43
|
+
.to eq('https://unpkg.com/ckeditor5@34.1.0/dist/translations/pl.js')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'with commercial CDNs' do
|
49
|
+
it_behaves_like 'a CDN provider', :cloud,
|
50
|
+
'https://cdn.ckeditor.com/ckeditor5/%<version>s/ckeditor.js'
|
51
|
+
|
52
|
+
it 'generates correct CKBox URL' do
|
53
|
+
instance.cdn = :ckbox
|
54
|
+
expect(instance.create_cdn_url('ckbox', '34.1.0', 'ckeditor.js'))
|
55
|
+
.to eq('https://cdn.ckbox.io/ckbox/34.1.0/ckeditor.js')
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'with invalid configuration' do
|
60
|
+
it 'raises ArgumentError for unknown CDN provider' do
|
61
|
+
instance.cdn = :invalid_cdn
|
62
|
+
expect { instance.create_cdn_url('ckeditor5', '34.1.0', 'ckeditor.js') }
|
63
|
+
.to raise_error(ArgumentError, 'Unknown provider: invalid_cdn')
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe CKEditor5::Rails::Semver do
|
6
|
+
describe '#initialize' do
|
7
|
+
context 'with valid version string' do
|
8
|
+
it 'accepts version in x.y.z format' do
|
9
|
+
expect { described_class.new('1.2.3') }.not_to raise_error
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'with invalid version' do
|
14
|
+
it 'raises error for numeric input' do
|
15
|
+
expect { described_class.new(123) }
|
16
|
+
.to raise_error(ArgumentError, 'invalid version format')
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'raises error for invalid string format' do
|
20
|
+
invalid_versions = ['1', '1.2', '1.2.3.4', 'x.y.z', '1.2.x', '1.a.3']
|
21
|
+
|
22
|
+
invalid_versions.each do |version|
|
23
|
+
expect { described_class.new(version) }
|
24
|
+
.to raise_error(ArgumentError, 'invalid version format')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '#to_s' do
|
31
|
+
it 'returns the version string' do
|
32
|
+
version = '1.2.3'
|
33
|
+
semver = described_class.new(version)
|
34
|
+
expect(semver.to_s).to eq(version)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '#version' do
|
39
|
+
it 'returns the version string' do
|
40
|
+
version = '1.2.3'
|
41
|
+
semver = described_class.new(version)
|
42
|
+
expect(semver.version).to eq(version)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'simplecov'
|
4
|
+
require 'simplecov_json_formatter'
|
5
|
+
|
6
|
+
SimpleCov.start do
|
7
|
+
enable_coverage :branch
|
8
|
+
enable_coverage :line
|
9
|
+
|
10
|
+
add_filter 'sandbox/'
|
11
|
+
add_group 'Library', 'lib/'
|
12
|
+
|
13
|
+
track_files 'lib/**/*.rb'
|
14
|
+
|
15
|
+
# minimum_coverage 90
|
16
|
+
# minimum_coverage_by_file 80
|
17
|
+
|
18
|
+
formatters = [
|
19
|
+
SimpleCov::Formatter::HTMLFormatter,
|
20
|
+
SimpleCov::Formatter::JSONFormatter
|
21
|
+
]
|
22
|
+
|
23
|
+
formatter SimpleCov::Formatter::MultiFormatter.new(formatters)
|
24
|
+
end
|
25
|
+
|
26
|
+
ENV['RAILS_ENV'] ||= 'test'
|
27
|
+
|
28
|
+
require File.expand_path('../sandbox/config/application', __dir__)
|
29
|
+
|
30
|
+
require 'pry'
|
31
|
+
require 'spec_helper'
|
32
|
+
require 'rspec/rails'
|
33
|
+
require 'rspec/expectations'
|
34
|
+
|
35
|
+
Rails.application.initialize!
|
36
|
+
|
37
|
+
RSpec.configure do |config|
|
38
|
+
config.expect_with :rspec do |expectations|
|
39
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
40
|
+
end
|
41
|
+
|
42
|
+
config.mock_with :rspec do |mocks|
|
43
|
+
mocks.verify_partial_doubles = true
|
44
|
+
end
|
45
|
+
|
46
|
+
config.shared_context_metadata_behavior = :apply_to_host_groups
|
47
|
+
config.filter_run_when_matching :focus
|
48
|
+
config.disable_monkey_patching!
|
49
|
+
|
50
|
+
config.default_formatter = 'doc' if config.files_to_run.one?
|
51
|
+
config.profile_examples = 10
|
52
|
+
|
53
|
+
config.order = :random
|
54
|
+
|
55
|
+
Kernel.rand config.seed
|
56
|
+
|
57
|
+
config.before(:each) do
|
58
|
+
Rails.application.load_seed
|
59
|
+
end
|
60
|
+
end
|
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.
|
4
|
+
version: 1.14.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mateusz Bagiลski
|
@@ -57,8 +57,9 @@ files:
|
|
57
57
|
- lib/ckeditor5/rails/cdn/url_generator.rb
|
58
58
|
- lib/ckeditor5/rails/context/helpers.rb
|
59
59
|
- lib/ckeditor5/rails/context/props.rb
|
60
|
-
- lib/ckeditor5/rails/editor/config_helpers.rb
|
61
60
|
- lib/ckeditor5/rails/editor/helpers.rb
|
61
|
+
- lib/ckeditor5/rails/editor/helpers/config_helpers.rb
|
62
|
+
- lib/ckeditor5/rails/editor/helpers/editor_helpers.rb
|
62
63
|
- lib/ckeditor5/rails/editor/props.rb
|
63
64
|
- lib/ckeditor5/rails/editor/props_inline_plugin.rb
|
64
65
|
- lib/ckeditor5/rails/editor/props_plugin.rb
|
@@ -66,11 +67,16 @@ files:
|
|
66
67
|
- lib/ckeditor5/rails/helpers.rb
|
67
68
|
- lib/ckeditor5/rails/hooks/form.rb
|
68
69
|
- lib/ckeditor5/rails/hooks/simple_form.rb
|
70
|
+
- lib/ckeditor5/rails/plugins/simple_upload_adapter.rb
|
69
71
|
- lib/ckeditor5/rails/presets/manager.rb
|
72
|
+
- lib/ckeditor5/rails/presets/plugins_builder.rb
|
70
73
|
- lib/ckeditor5/rails/presets/preset_builder.rb
|
71
74
|
- lib/ckeditor5/rails/presets/toolbar_builder.rb
|
72
75
|
- lib/ckeditor5/rails/semver.rb
|
73
76
|
- lib/ckeditor5/rails/version.rb
|
77
|
+
- spec/lib/ckeditor5/rails/cdn/url_generator_spec.rb
|
78
|
+
- spec/lib/ckeditor5/rails/semver_spec.rb
|
79
|
+
- spec/spec_helper.rb
|
74
80
|
homepage: https://github.com/Mati365/ckeditor5-rails
|
75
81
|
licenses:
|
76
82
|
- GPL-2.0
|
@@ -94,4 +100,7 @@ rubygems_version: 3.5.22
|
|
94
100
|
signing_key:
|
95
101
|
specification_version: 4
|
96
102
|
summary: CKEditor 5 for Rails
|
97
|
-
test_files:
|
103
|
+
test_files:
|
104
|
+
- spec/lib/ckeditor5/rails/cdn/url_generator_spec.rb
|
105
|
+
- spec/lib/ckeditor5/rails/semver_spec.rb
|
106
|
+
- spec/spec_helper.rb
|