ckeditor5 1.21.0 → 1.23.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: c524ae4eac93eeecf2e8aa8905044faeb0d3d1496e418f22c7abe3863f0538e3
4
- data.tar.gz: faf447ab629a6a2ed95106461d2bcc6f4a75aef14e9e6e3b4c0da0cfcc2f7dd4
3
+ metadata.gz: a6209f7ab70666ad0c3e5c368f47832871d740429238bb62199c5956ca73fe77
4
+ data.tar.gz: 3e3af0099b5150b6c2df7bb578a11cd63b81f88cb9ded596806e5ea980ebf90a
5
5
  SHA512:
6
- metadata.gz: 83c7332860095fbfdb127a3202a1c38ac2383f671e828a9258ed01e0daff1f232583d77ed3b17badf467f65999c1bc97a068f35df915cd1eb35ef4ee54f569cc
7
- data.tar.gz: 54bef9bf69740d134937aa5e6dd16d7ca8190a5da4fb36dde81db695ab571449036f9628c88321f2c12dbc6092b3adc6a9173ded26d363694686eaec5f3e71b4
6
+ metadata.gz: 1d7f113a286468066aa941cba9d735c5312d8558ed83a1d3f9fa7e4a2959d7c58a843f6b0bf8fd4e296b0ab34dedc303f0a6533c5adf6af1c60a1a77dbe4c5e9
7
+ data.tar.gz: c4304b80a54b9bf94629b9aa8c27d640e2ff0783e3d78d2a577400d3cd29df337aa1a8b40fc7bc8f050bc3ee3c528becfa0a12b68158fdb980df5ea2b897b6f8
data/Gemfile CHANGED
@@ -21,6 +21,7 @@ group :development do
21
21
  gem 'slim', '~> 5.2', '>= 5.2.0'
22
22
  gem 'sqlite3', '>= 1.4'
23
23
  gem 'stimulus-rails'
24
+ gem 'terser', '~> 1.1', '>= 1.1.1'
24
25
  gem 'turbo-rails'
25
26
  end
26
27
 
data/README.md CHANGED
@@ -610,6 +610,39 @@ CKEditor5::Rails.configure do
610
610
  end
611
611
  end
612
612
  ```
613
+
614
+ If you want to append groups of items, you can use the `group` method:
615
+
616
+ ```rb
617
+ # config/initializers/ckeditor5.rb
618
+
619
+ CKEditor5::Rails.configure do
620
+ # ... other configuration
621
+
622
+ toolbar do
623
+ group :text_formatting, label: 'Text Formatting', icon: 'threeVerticalDots' do
624
+ append :bold, :italic, :underline, :strikethrough, separator,
625
+ :subscript, :superscript, :removeFormat
626
+ end
627
+ end
628
+ end
629
+ ```
630
+
631
+ If you want add new line or the separator, you can use the `break_line` or `separator` methods:
632
+
633
+ ```rb
634
+ # config/initializers/ckeditor5.rb
635
+
636
+ CKEditor5::Rails.configure do
637
+ # ... other configuration
638
+
639
+ toolbar do
640
+ append :bold, break_line
641
+ append separator, :italic
642
+ end
643
+ end
644
+ ```
645
+
613
646
  </details>
614
647
 
615
648
  #### `menubar(visible: true)` method
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'singleton'
4
+ require 'terser'
4
5
 
5
6
  module CKEditor5::Rails::Assets
6
7
  class WebComponentBundle
@@ -17,13 +18,23 @@ module CKEditor5::Rails::Assets
17
18
  ].freeze
18
19
 
19
20
  def source
20
- @source ||= WEBCOMPONENTS_MODULES.map do |file|
21
- File.read(File.join(WEBCOMPONENTS_PATH, file))
22
- end.join("\n").html_safe
21
+ @source ||= compress_source(raw_source)
23
22
  end
24
23
 
25
24
  def to_html
26
25
  @to_html ||= tag.script(source, type: 'module', nonce: true)
27
26
  end
27
+
28
+ private
29
+
30
+ def raw_source
31
+ @raw_source ||= WEBCOMPONENTS_MODULES.map do |file|
32
+ File.read(File.join(WEBCOMPONENTS_PATH, file))
33
+ end.join("\n")
34
+ end
35
+
36
+ def compress_source(code)
37
+ Terser.new(compress: true, mangle: true).compile(code).html_safe
38
+ end
28
39
  end
29
40
  end
@@ -1,13 +1,46 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CKEditor5::Rails::Presets
4
+ # Builder class for configuring CKEditor5 toolbar items.
5
+ #
6
+ # @example Basic toolbar configuration
7
+ # toolbar = ToolbarBuilder.new([:bold, :italic])
8
+ # toolbar.append(:link)
9
+ # toolbar.prepend(:heading)
4
10
  class ToolbarBuilder
5
11
  attr_reader :items
6
12
 
13
+ # Initialize a new toolbar builder with given items.
14
+ #
15
+ # @param items [Array<Symbol>] Initial toolbar items
16
+ # @example Create new toolbar
17
+ # ToolbarBuilder.new([:bold, :italic, :|, :link])
7
18
  def initialize(items)
8
19
  @items = items
9
20
  end
10
21
 
22
+ # Returns toolbar line break symbol
23
+ #
24
+ # @return [Symbol] Line break symbol (-)
25
+ # @example Add line break to toolbar
26
+ # toolbar do
27
+ # append :bold, break_line, :italic
28
+ # end
29
+ def break_line
30
+ :-
31
+ end
32
+
33
+ # Returns toolbar separator symbol
34
+ #
35
+ # @return [Symbol] Separator symbol (|)
36
+ # @example Add separator to toolbar
37
+ # toolbar do
38
+ # append :bold, separator, :italic
39
+ # end
40
+ def separator
41
+ :|
42
+ end
43
+
11
44
  # Remove items from the editor toolbar.
12
45
  #
13
46
  # @param removed_items [Array<Symbol>] Toolbar items to be removed
@@ -16,7 +49,9 @@ module CKEditor5::Rails::Presets
16
49
  # remove :underline, :heading
17
50
  # end
18
51
  def remove(*removed_items)
19
- removed_items.each { |item| items.delete(item) }
52
+ items.delete_if do |existing_item|
53
+ removed_items.any? { |item_to_remove| item_matches?(existing_item, item_to_remove) }
54
+ end
20
55
  end
21
56
 
22
57
  # Prepend items to the editor toolbar.
@@ -34,7 +69,7 @@ module CKEditor5::Rails::Presets
34
69
  # @raise [ArgumentError] When the specified 'before' item is not found
35
70
  def prepend(*prepended_items, before: nil)
36
71
  if before
37
- index = items.index(before)
72
+ index = find_item_index(before)
38
73
  raise ArgumentError, "Item '#{before}' not found in array" unless index
39
74
 
40
75
  items.insert(index, *prepended_items)
@@ -58,7 +93,7 @@ module CKEditor5::Rails::Presets
58
93
  # @raise [ArgumentError] When the specified 'after' item is not found
59
94
  def append(*appended_items, after: nil)
60
95
  if after
61
- index = items.index(after)
96
+ index = find_item_index(after)
62
97
  raise ArgumentError, "Item '#{after}' not found in array" unless index
63
98
 
64
99
  items.insert(index + 1, *appended_items)
@@ -66,5 +101,84 @@ module CKEditor5::Rails::Presets
66
101
  items.push(*appended_items)
67
102
  end
68
103
  end
104
+
105
+ # Find group by name in toolbar items
106
+ #
107
+ # @param name [Symbol] Group name to find
108
+ # @return [ToolbarGroupItem, nil] Found group or nil
109
+ def find_group(name)
110
+ items.find { |item| item.is_a?(ToolbarGroupItem) && item.name == name }
111
+ end
112
+
113
+ # Remove group by name from toolbar items
114
+ #
115
+ # @param name [Symbol] Group name to remove
116
+ def remove_group(name)
117
+ items.delete_if { |item| item.is_a?(ToolbarGroupItem) && item.name == name }
118
+ end
119
+
120
+ # Create and add new group to toolbar
121
+ #
122
+ # @param name [Symbol] Group name
123
+ # @param options [Hash] Group options (label:, icons:)
124
+ # @param block [Proc] Configuration block
125
+ # @return [ToolbarGroupItem] Created group
126
+ def group(name, **options, &block)
127
+ group = ToolbarGroupItem.new(name, [], **options)
128
+ group.instance_eval(&block) if block_given?
129
+ items << group
130
+ group
131
+ end
132
+
133
+ private
134
+
135
+ # Find index of an item or group by name
136
+ #
137
+ # @param item [Symbol] Item or group name to find
138
+ # @return [Integer, nil] Index of the found item or nil
139
+ def find_item_index(item)
140
+ items.find_index { |existing_item| item_matches?(existing_item, item) }
141
+ end
142
+
143
+ # Checks if the existing item matches the given item or group name
144
+ #
145
+ # @param existing_item [Symbol, ToolbarGroupItem] Item to check
146
+ # @param item [Symbol] Item or group name to match against
147
+ # @return [Boolean] true if items match, false otherwise
148
+ # @example Check if items match
149
+ # item_matches?(:bold, :bold) # => true
150
+ # item_matches?(group(:text), :text) # => true
151
+ def item_matches?(existing_item, item)
152
+ if existing_item.is_a?(ToolbarGroupItem)
153
+ existing_item.name == item
154
+ else
155
+ existing_item == item
156
+ end
157
+ end
158
+ end
159
+
160
+ # Builder class for configuring CKEditor5 toolbar groups.
161
+ # Allows creating named groups of toolbar items with optional labels and icons.
162
+ #
163
+ # @example Creating a text formatting group
164
+ # group = ToolbarGroupItem.new(:text_formatting, [:bold, :italic], label: 'Text')
165
+ # group.append(:underline)
166
+ class ToolbarGroupItem < ToolbarBuilder
167
+ attr_reader :name, :label, :icon
168
+
169
+ # Initialize a new toolbar group item.
170
+ #
171
+ # @param name [Symbol] Name of the toolbar group
172
+ # @param items [Array<Symbol>, ToolbarBuilder] Items to be included in the group
173
+ # @param label [String, nil] Optional label for the group
174
+ # @param icon [String, nil] Optional icon for the group
175
+ # @example Create a new toolbar group
176
+ # ToolbarGroupItem.new(:text, [:bold, :italic], label: 'Text formatting')
177
+ def initialize(name, items = [], label: nil, icon: nil)
178
+ super(items)
179
+ @name = name
180
+ @label = label
181
+ @icon = icon
182
+ end
69
183
  end
70
184
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module CKEditor5
4
4
  module Rails
5
- VERSION = '1.21.0'
5
+ VERSION = '1.23.0'
6
6
 
7
7
  DEFAULT_CKEDITOR_VERSION = '44.0.0'
8
8
  end
@@ -67,4 +67,123 @@ RSpec.describe CKEditor5::Rails::Presets::ToolbarBuilder do
67
67
  end
68
68
  end
69
69
  end
70
+
71
+ describe '#break_line' do
72
+ it 'returns line break symbol' do
73
+ expect(builder.break_line).to eq(:-)
74
+ end
75
+ end
76
+
77
+ describe '#separator' do
78
+ it 'returns separator symbol' do
79
+ expect(builder.separator).to eq(:|)
80
+ end
81
+ end
82
+
83
+ describe '#group' do
84
+ it 'creates and adds a new group' do
85
+ builder.group(:text, label: 'Text') do
86
+ append(:bold, :italic)
87
+ end
88
+
89
+ group = builder.items.last
90
+ expect(group).to be_a(CKEditor5::Rails::Presets::ToolbarGroupItem)
91
+ expect(group.name).to eq(:text)
92
+ expect(group.items).to eq(%i[bold italic])
93
+ expect(group.label).to eq('Text')
94
+ end
95
+
96
+ it 'creates group without configuration block' do
97
+ group = builder.group(:text, label: 'Text')
98
+
99
+ expect(group).to be_a(CKEditor5::Rails::Presets::ToolbarGroupItem)
100
+ expect(group.items).to be_empty
101
+ end
102
+ end
103
+
104
+ describe '#find_group' do
105
+ it 'returns group by name' do
106
+ builder.group(:text, label: 'Text')
107
+ builder.group(:formatting, label: 'Format')
108
+
109
+ group = builder.find_group(:formatting)
110
+ expect(group).to be_a(CKEditor5::Rails::Presets::ToolbarGroupItem)
111
+ expect(group.name).to eq(:formatting)
112
+ end
113
+
114
+ it 'returns nil when group not found' do
115
+ expect(builder.find_group(:nonexistent)).to be_nil
116
+ end
117
+ end
118
+
119
+ describe '#remove_group' do
120
+ it 'removes group by name' do
121
+ builder.group(:text, label: 'Text')
122
+ builder.group(:formatting, label: 'Format')
123
+
124
+ builder.remove_group(:text)
125
+ expect(builder.find_group(:text)).to be_nil
126
+ expect(builder.find_group(:formatting)).to be_present
127
+ end
128
+
129
+ it 'ignores non-existent groups' do
130
+ builder.group(:text, label: 'Text')
131
+
132
+ expect { builder.remove_group(:nonexistent) }.not_to(change { builder.items.count })
133
+ end
134
+ end
135
+
136
+ describe 'interacting with groups' do
137
+ let(:text_group) do
138
+ builder.group(:text, label: 'Text') do
139
+ append(:bold, :italic)
140
+ end
141
+ end
142
+
143
+ before do
144
+ text_group
145
+ end
146
+
147
+ it 'prepends items before group' do
148
+ builder.prepend(:undo, :redo, before: :text)
149
+ expect(builder.items.map { |i| i.is_a?(CKEditor5::Rails::Presets::ToolbarGroupItem) ? i.name : i })
150
+ .to eq(%i[bold italic | link undo redo text])
151
+ end
152
+
153
+ it 'appends items after group' do
154
+ builder.append(:undo, :redo, after: :text)
155
+ expect(builder.items.map { |i| i.is_a?(CKEditor5::Rails::Presets::ToolbarGroupItem) ? i.name : i })
156
+ .to eq(%i[bold italic | link text undo redo])
157
+ end
158
+
159
+ it 'removes group using remove method' do
160
+ builder.remove(:text)
161
+ expect(builder.items).to eq(%i[bold italic | link])
162
+ end
163
+ end
164
+ end
165
+
166
+ RSpec.describe CKEditor5::Rails::Presets::ToolbarGroupItem do
167
+ let(:items) { %i[bold italic] }
168
+ let(:group) { described_class.new(:formatting, items, label: 'Format', icon: 'format') }
169
+
170
+ describe '#initialize' do
171
+ it 'creates a group with given parameters' do
172
+ expect(group.name).to eq(:formatting)
173
+ expect(group.items).to eq(items)
174
+ expect(group.label).to eq('Format')
175
+ expect(group.icon).to eq('format')
176
+ end
177
+ end
178
+
179
+ it 'inherits toolbar manipulation methods' do
180
+ group.append(:underline)
181
+ expect(group.items).to eq(%i[bold italic underline])
182
+
183
+ group.prepend(:heading)
184
+ expect(group.items).to eq(%i[heading bold italic underline])
185
+
186
+ group.remove(:italic)
187
+ expect(group.items).to eq(%i[heading bold underline])
188
+ end
70
189
  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.21.0
4
+ version: 1.23.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mateusz Bagiński
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2024-12-03 00:00:00.000000000 Z
12
+ date: 2024-12-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -31,6 +31,20 @@ dependencies:
31
31
  - - "<"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '9.0'
34
+ - !ruby/object:Gem::Dependency
35
+ name: terser
36
+ requirement: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.0'
41
+ type: :runtime
42
+ prerelease: false
43
+ version_requirements: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.0'
34
48
  description:
35
49
  email: cziken58@gmail.com
36
50
  executables: []