ckeditor5 0.0.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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