ckeditor5 0.0.1 → 1.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a3f3b6f1bee0c89fcabe50c6fa0597cd2b817967d381a9459f9bf8941d0df75e
4
- data.tar.gz: 5fafb6320e6475b8dcbedc3228010f2b1d9da07a6b37004e3cbef2158700b480
3
+ metadata.gz: 1a430aeac80e44b802a01fd61104356f2a18e401dc6650b14c7c3e5ed8a95f9a
4
+ data.tar.gz: 16f0147ad4faf2a26224236af5a54875a8fbf86139ce945b2f01c350524bc7df
5
5
  SHA512:
6
- metadata.gz: f3cf0dd3c9c5fd7c5ce7b234c961a0c807fbe2ddbc0a4b321ce14121dcc72acc122e8351a7d01f283c8efebfeb599d5cd5d25edb0193999682f55ffc186c9a9c
7
- data.tar.gz: bd2da5b11be2b6a7011256a1d4bc6af5acad330c4e1b102ee8b01ee786dc97eeb2e89ef71853a6f169ab941e4f95cd1e8ffdb66cfbf52aa10848383afed01c7a
6
+ metadata.gz: 82860b61ad2da6eba0cf1969c6d1190c7d90e3ce5bfabd5c9c1ad8a9b9449a12c03d83ef65563fe37c0f74c4f75078c7ba867f377186bc35341ccf5fdff97bd7
7
+ data.tar.gz: 43bdc1f9313154c6c7255a3621523ae1f4bb51d475d381eeece7515464d7bab059a64dd480d9d7e32d9d0a94c177ecb41d4998b47dbb41e5f35880b643966b1f
data/Gemfile CHANGED
@@ -1,3 +1,23 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
5
+ gem 'bundler', '~> 2.5', '>= 2.5.21'
6
+
7
+ group :development do
8
+ gem 'brakeman', '~> 6.1', '>= 6.1.1', require: false
9
+ gem 'guard'
10
+ gem 'guard-bundler'
11
+ gem 'guard-rails'
12
+ gem 'rake', '~> 13.2', '>= 13.2.1'
13
+ gem 'rspec', '~> 3.13'
14
+ gem 'rubocop', '~> 1.66', require: false
15
+ gem 'rubocop-rails', '~> 2.26', '>= 2.26.2', require: false
16
+ gem 'rubocop-rails-omakase', '~> 1.0.0', require: false
17
+ end
18
+
19
+ group :test, :development do
20
+ gem 'capybara', '~> 3.40'
21
+ end
22
+
3
23
  gemspec
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # ckeditor5
1
+ # CKEditor 5 Rails Integration
2
2
 
3
3
  [![License: MIT](https://img.shields.io/badge/License-MIT-orange.svg?style=flat-square)](https://opensource.org/licenses/MIT)
4
4
  ![Gem Version](https://img.shields.io/gem/v/ckeditor5-rails?style=flat-square)
@@ -6,9 +6,9 @@
6
6
  ![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/mati365/ckeditor5-rails?style=flat-square)
7
7
  [![GitHub issues](https://img.shields.io/github/issues/mati365/ckeditor5-rails?style=flat-square)](https://github.com/Mati365/ckeditor5-rails/issues)
8
8
 
9
- Unofficial CKEditor 5 Ruby on Rails integration.
9
+ Unofficial CKEditor 5 Ruby on Rails integration gem. Provides seamless integration of CKEditor 5 with Rails applications through web components and helper methods.
10
10
 
11
- ## Install
11
+ ## Installation
12
12
 
13
13
  Add this line to your application's Gemfile:
14
14
 
@@ -16,20 +16,101 @@ Add this line to your application's Gemfile:
16
16
  gem 'ckeditor5'
17
17
  ```
18
18
 
19
- ## :construction: Planned features
19
+ ## Basic Usage
20
20
 
21
- - [ ] Add support for CKEditor 5 `Classic` / `Multi-Root` / `Balloon` / `Inline` / `Document editors`.
22
- - [ ] Add support for CKEditor 5 Watchdog and Context.
23
- - [ ] Add support for CKEditor 5 CDN and NPM packages.
24
- - [ ] Add support for CKEditor 5 Collaboration.
25
- - [ ] Add support for SSR.
21
+ ### Presets
26
22
 
27
- ## :construction: Planned usage
23
+ Override default preset configuration:
28
24
 
29
- Classic editor:
25
+ ```rb
26
+ # config/initializers/ckeditor5.rb
27
+
28
+ CKEditor5::Rails::Engine.configure do |config|
29
+ config.presets.override :default do |preset|
30
+ preset.menubar visible: false
31
+ end
32
+ end
33
+ ```
34
+
35
+ Create new preset:
36
+
37
+ ```rb
38
+ # config/initializers/ckeditor5.rb
39
+
40
+ CKEditor5::Rails::Engine.configure do |config|
41
+ config.presets.define :custom do |preset|
42
+ shape :classic
43
+
44
+ menubar
45
+
46
+ toolbar :undo, :redo, :|, :heading, :|, :bold, :italic, :underline, :|,
47
+ :link, :insertImage, :ckbox, :mediaEmbed, :insertTable, :blockQuote, :|,
48
+ :bulletedList, :numberedList, :todoList, :outdent, :indent
49
+
50
+ plugins :AccessibilityHelp, :Autoformat, :AutoImage, :Autosave,
51
+ :BlockQuote, :Bold, :CKBox, :CKBoxImageEdit, :CloudServices,
52
+ :Essentials, :Heading, :ImageBlock, :ImageCaption, :ImageInline,
53
+ :ImageInsert, :ImageInsertViaUrl, :ImageResize, :ImageStyle,
54
+ :ImageTextAlternative, :ImageToolbar, :ImageUpload, :Indent,
55
+ :IndentBlock, :Italic, :Link, :LinkImage, :List, :ListProperties,
56
+ :MediaEmbed, :Paragraph, :PasteFromOffice, :PictureEditing,
57
+ :SelectAll, :Table, :TableCaption, :TableCellProperties,
58
+ :TableColumnResize, :TableProperties, :TableToolbar,
59
+ :TextTransformation, :TodoList, :Underline, :Undo, :Base64UploadAdapter
60
+ end
61
+ end
62
+
63
+ # Somewhere in your view
64
+
65
+ = ckeditor5_editor preset: :custom
66
+ ```
67
+
68
+ ### CDN Configuration
69
+
70
+ #### jsDelivr (Default)
71
+
72
+ ```slim
73
+ - content_for :head
74
+ = ckeditor5_assets version: '43.2.0'
75
+ ```
76
+
77
+ #### unpkg
78
+
79
+ ```slim
80
+ - content_for :head
81
+ = ckeditor5_unpkg_assets version: '43.2.0'
82
+ ```
83
+
84
+ #### CKEditor Cloud
85
+
86
+ It's available only for licensed users.
87
+
88
+ ```slim
89
+ - content_for :head
90
+ = ckeditor5_assets version: '43.2.0', license_key: 'YOUR-LICENSE-KEY'
91
+ ```
92
+
93
+ ### Editor type
94
+
95
+ #### Classic Editor
96
+
97
+ ```slim
98
+ - content_for :head
99
+ = ckeditor5_assets version: '43.2.0' # Optional: translations: [ :pl, :es ]
100
+
101
+ = ckeditor5_editor
102
+ ```
103
+
104
+ #### Multiroot Editor
30
105
 
31
106
  ```slim
32
- = render ckeditor5 :classic, id: 'editor', config: { toolbar: 'bold italic | link' }
107
+ = ckeditor5_editor type: :multiroot do
108
+ = ckeditor5_toolbar
109
+ br
110
+ = ckeditor5_editable 'editable-a' do
111
+ | This is a toolbar editable
112
+ br
113
+ = ckeditor5_editable 'editable-b'
33
114
  ```
34
115
 
35
116
  ## License
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/module'
4
+
5
+ module CKEditor5::Rails::Assets
6
+ class AssetsBundle
7
+ def initialize
8
+ validate_implementation!
9
+ end
10
+
11
+ def empty?
12
+ scripts.empty? && stylesheets.empty?
13
+ end
14
+
15
+ def translations_scripts
16
+ scripts.select(&:translation?)
17
+ end
18
+
19
+ def preloads
20
+ stylesheets + scripts.map(&:url)
21
+ end
22
+
23
+ def <<(other)
24
+ raise TypeError, 'other must be an instance of AssetsBundle' unless other.is_a?(AssetsBundle)
25
+
26
+ @scripts = scripts + other.scripts
27
+ @stylesheets = stylesheets + other.stylesheets
28
+ end
29
+
30
+ private
31
+
32
+ def validate_implementation!
33
+ %i[scripts stylesheets].each do |method|
34
+ unless respond_to?(method, true)
35
+ raise NotImplementedError, "#{self.class} must implement the ##{method} method"
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+ class JSExportsMeta
42
+ attr_reader :url, :import_meta
43
+
44
+ delegate :esm?, :window?, :import_name, :window_name, :import_as, to: :import_meta
45
+
46
+ def initialize(url, translation: false, **import_options)
47
+ @url = url
48
+ @import_meta = JSImportMeta.new(**import_options)
49
+ @translation = translation
50
+ end
51
+
52
+ def translation?
53
+ @translation
54
+ end
55
+ end
56
+
57
+ class JSImportMeta
58
+ attr_reader :import_as, :import_name, :window_name
59
+
60
+ def initialize(import_as: nil, import_name: nil, window_name: nil)
61
+ validate_arguments!(import_as, import_name, window_name)
62
+ @import_as = import_as
63
+ @import_name = import_name
64
+ @window_name = window_name
65
+ end
66
+
67
+ def esm?
68
+ import_name.present?
69
+ end
70
+
71
+ def window?
72
+ window_name.present?
73
+ end
74
+
75
+ def to_h
76
+ {
77
+ import_as: import_as,
78
+ import_name: import_name,
79
+ window_name: window_name
80
+ }.compact
81
+ end
82
+
83
+ private
84
+
85
+ def validate_arguments!(import_as, import_name, window_name)
86
+ if import_name.nil? && window_name.nil?
87
+ raise ArgumentError,
88
+ 'import_name or window_name must be present'
89
+ end
90
+
91
+ raise ArgumentError, 'import_name required when import_as is present' if import_as && import_name.nil?
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'action_view'
4
+
5
+ module CKEditor5::Rails::Assets
6
+ WEBCOMPONENT_SOURCE = File.read(File.join(__dir__, 'webcomponent.mjs')).html_safe
7
+
8
+ class AssetsBundleHtmlSerializer
9
+ include ActionView::Helpers::TagHelper
10
+
11
+ attr_reader :bundle
12
+
13
+ def initialize(bundle)
14
+ raise TypeError, 'bundle must be an instance of AssetsBundle' unless bundle.is_a?(AssetsBundle)
15
+
16
+ @bundle = bundle
17
+ end
18
+
19
+ def to_html
20
+ safe_join([
21
+ preload_tags,
22
+ styles_tags,
23
+ window_scripts_tags,
24
+ scripts_import_map_tag,
25
+ web_component_tag
26
+ ])
27
+ end
28
+
29
+ def self.url_resource_preload_type(url)
30
+ case File.extname(url)
31
+ when '.js' then 'script'
32
+ when '.css' then 'style'
33
+ else 'fetch'
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ def web_component_tag
40
+ @web_component_tag ||= tag.script(WEBCOMPONENT_SOURCE, type: 'module', nonce: true)
41
+ end
42
+
43
+ def window_scripts_tags
44
+ @window_scripts_tags ||= safe_join(bundle.scripts.filter_map do |script|
45
+ tag.script(src: script.url, nonce: true, async: true) if script.window?
46
+ end)
47
+ end
48
+
49
+ def scripts_import_map_tag
50
+ return @scripts_import_map_tag if defined?(@scripts_import_map_tag)
51
+
52
+ import_map = bundle.scripts.each_with_object({}) do |script, map|
53
+ map[script.import_name] = script.url if script.esm?
54
+ end
55
+
56
+ @scripts_import_map_tag = tag.script(
57
+ { imports: import_map }.to_json.html_safe,
58
+ type: 'importmap',
59
+ nonce: true
60
+ )
61
+ end
62
+
63
+ def styles_tags
64
+ @styles_tags ||= safe_join(bundle.stylesheets.map do |url|
65
+ tag.link(href: url, rel: 'stylesheet')
66
+ end)
67
+ end
68
+
69
+ def preload_tags
70
+ @preload_tags ||= safe_join(bundle.preloads.map do |url|
71
+ tag.link(href: url, rel: 'preload', as: self.class.url_resource_preload_type(url))
72
+ end)
73
+ end
74
+ end
75
+ end