ckeditor5 1.21.0 → 1.23.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: 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: []