ckeditor5 1.7.0 → 1.8.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: 4325c958e2805d971859c841f0b2694490e35a7e4600e2b8bb60f35672493146
4
- data.tar.gz: 23aa528bcbfbec102647898aee0fb4c064e7d16bd051fc4bf45ae94b9ed16fb6
3
+ metadata.gz: 18736efccfe3547f18ff9df5418fd5f93aafa426423c3ca8daca99de481c6c60
4
+ data.tar.gz: 6be07d38f24ba131e3a8444175b8416561706a97d74bd581d8568703ef3544f2
5
5
  SHA512:
6
- metadata.gz: 7e12e3e13824889463c2500e5d26874c1dd7c1dac6c5dbf1d41b37e5bd66e25b642b92fdbcb943b4f99219302e9184bacc5c8b16902559511c69db2392e2d569
7
- data.tar.gz: '090b221f5bebaedac65be2db6a230409537b891bce481258106a575a58555b59fa2a0f55b125ea114115554ecba1b2d0f80845e3b1bea14f6f743af627972810'
6
+ metadata.gz: c40e50c2093c7f8c311b8565a54ddc4835aba887ced1e36b4802c6681769a8f2e4f39812443e688f6e31ff4932eef76282664be82d7cdbb4b667c9febe76374f
7
+ data.tar.gz: f9a999fb8a325323e497b225f3c8bed54cc24befc5bcd2cc90a93a25dece1d539e5e33a34fbe2a4f9570e462527492e061819563b7fad19e61d24fae8a39953e
data/README.md CHANGED
@@ -84,6 +84,7 @@ Voilà! You have CKEditor 5 integrated with your Rails application. 🎉
84
84
  - [`plugin(name, premium:, import_name:)` method](#pluginname-premium-import_name-method)
85
85
  - [`plugins(*names, **kwargs)` method](#pluginsnames-kwargs-method)
86
86
  - [`inline_plugin(name, code)` method](#inline_pluginname-code-method)
87
+ - [`ckeditor5_element_ref(selector)` method](#ckeditor5_element_refselector-method)
87
88
  - [Including CKEditor 5 assets 📦](#including-ckeditor-5-assets-)
88
89
  - [Format 📝](#format-)
89
90
  - [Using default preset](#using-default-preset)
@@ -445,7 +446,9 @@ end
445
446
 
446
447
  #### `configure(name, value)` method
447
448
 
448
- Allows you to set custom configuration options. You can pass the name of the option and its value as arguments. The example below show how to set the default protocol for the link plugin to `https://`:
449
+ Allows you to set custom configuration options. You can pass the name of the option and its value as arguments. The [`ckeditor5_element_ref(selector)` helper](#ckeditor5_element_refselector-method) 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.
450
+
451
+ For example, you can use it to configure font family dropdown to show only fonts available in specific elements:
449
452
 
450
453
  ```rb
451
454
  # config/initializers/ckeditor5.rb
@@ -453,8 +456,19 @@ Allows you to set custom configuration options. You can pass the name of the opt
453
456
  CKEditor5::Rails.configure do
454
457
  # ... other configuration
455
458
 
456
- configure :link, {
457
- defaultProtocol: 'https://'
459
+ configure :fontFamily, {
460
+ supportAllValues: true,
461
+ options: [
462
+ 'default',
463
+ 'Arial, Helvetica, sans-serif',
464
+ 'Courier New, Courier, monospace',
465
+ 'Georgia, serif',
466
+ 'Lucida Sans Unicode, Lucida Grande, sans-serif',
467
+ 'Tahoma, Geneva, sans-serif',
468
+ 'Times New Roman, Times, serif',
469
+ 'Trebuchet MS, Helvetica, sans-serif',
470
+ 'Verdana, Geneva, sans-serif'
471
+ ]
458
472
  }
459
473
  end
460
474
  ```
@@ -538,6 +552,23 @@ CKEditor5::Rails.configure do
538
552
  JS
539
553
  end
540
554
  ```
555
+
556
+ #### `ckeditor5_element_ref(selector)` method
557
+
558
+ 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.
559
+
560
+ ```rb
561
+ # config/initializers/ckeditor5.rb
562
+
563
+ CKEditor5::Rails.configure do
564
+ # ... other configuration
565
+
566
+ configure :yourPlugin, {
567
+ element: ckeditor5_element_ref("body")
568
+ }
569
+ end
570
+ ```
571
+
541
572
  </details>
542
573
 
543
574
  ## Including CKEditor 5 assets 📦
@@ -132,6 +132,72 @@ class CKEditorComponent extends HTMLElement {
132
132
  }
133
133
  }
134
134
 
135
+ /**
136
+ * Resolves element references in configuration object.
137
+ * Looks for objects with { $element: "selector" } format and replaces them with actual elements.
138
+ *
139
+ * @private
140
+ * @param {Object} obj - Configuration object to process
141
+ * @returns {Object} Processed configuration object with resolved element references
142
+ */
143
+ #resolveElementReferences(obj) {
144
+ if (!obj || typeof obj !== 'object') {
145
+ return obj;
146
+ }
147
+
148
+ if (Array.isArray(obj)) {
149
+ return obj.map(item => this.#resolveElementReferences(item));
150
+ }
151
+
152
+ const result = Object.create(null);
153
+
154
+ for (const key of Object.getOwnPropertyNames(obj)) {
155
+ if (!isSafeKey(key)) {
156
+ console.warn(`Suspicious key "${key}" detected in config, skipping`);
157
+ continue;
158
+ }
159
+
160
+ const value = obj[key];
161
+
162
+ if (value && typeof value === 'object') {
163
+ if (value.$element) {
164
+ const selector = value.$element;
165
+
166
+ if (typeof selector !== 'string') {
167
+ console.warn(`Invalid selector type for "${key}", expected string`);
168
+ continue;
169
+ }
170
+
171
+ const element = document.querySelector(selector);
172
+
173
+ if (!element) {
174
+ console.warn(`Element not found for selector: ${selector}`);
175
+ }
176
+
177
+ result[key] = element || null;
178
+ } else {
179
+ result[key] = this.#resolveElementReferences(value);
180
+ }
181
+ } else {
182
+ result[key] = value;
183
+ }
184
+ }
185
+
186
+ return result;
187
+ }
188
+
189
+ /**
190
+ * Gets editor configuration with resolved element references
191
+ *
192
+ * @private
193
+ * @returns {EditorConfig}
194
+ */
195
+ #getConfig() {
196
+ const config = JSON.parse(this.getAttribute('config') || '{}');
197
+
198
+ return this.#resolveElementReferences(config);
199
+ }
200
+
135
201
  /**
136
202
  * Creates a new CKEditor instance
137
203
  *
@@ -273,16 +339,6 @@ class CKEditorComponent extends HTMLElement {
273
339
  return this.getAttribute('watchdog') === 'true';
274
340
  }
275
341
 
276
- /**
277
- * Parses editor configuration from config attribute
278
- *
279
- * @private
280
- * @returns {EditorConfig}
281
- */
282
- #getConfig() {
283
- return JSON.parse(this.getAttribute('config') || '{}');
284
- }
285
-
286
342
  /**
287
343
  * Queries and validates editable elements
288
344
  *
@@ -824,6 +880,20 @@ function loadAsyncImports(imports = []) {
824
880
  }));
825
881
  }
826
882
 
883
+
884
+ /**
885
+ * Checks if a key is safe to use in configuration objects to prevent prototype pollution.
886
+ *
887
+ * @param {string} key - Key name to check
888
+ * @returns {boolean} True if key is safe to use.
889
+ */
890
+ function isSafeKey(key) {
891
+ return typeof key === 'string' &&
892
+ key !== '__proto__' &&
893
+ key !== 'constructor' &&
894
+ key !== 'prototype';
895
+ }
896
+
827
897
  customElements.define('ckeditor-component', CKEditorComponent);
828
898
  customElements.define('ckeditor-editable-component', CKEditorEditableComponent);
829
899
  customElements.define('ckeditor-ui-part-component', CKEditorUIPartComponent);
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CKEditor5::Rails
4
+ module Editor::ConfigHelpers
5
+ def ckeditor5_element_ref(selector)
6
+ { '$element': selector }
7
+ end
8
+ end
9
+ end
@@ -3,9 +3,12 @@
3
3
  require_relative 'props_plugin'
4
4
  require_relative 'props_inline_plugin'
5
5
  require_relative 'props'
6
+ require_relative 'config_helpers'
6
7
 
7
8
  module CKEditor5::Rails
8
9
  module Editor::Helpers
10
+ include Editor::ConfigHelpers
11
+
9
12
  class EditorContextError < StandardError; end
10
13
  class PresetNotFoundError < ArgumentError; end
11
14
  class InvalidEditableHeightError < ArgumentError; end
@@ -3,6 +3,8 @@
3
3
  module CKEditor5::Rails
4
4
  module Presets
5
5
  class PresetBuilder
6
+ include Editor::ConfigHelpers
7
+
6
8
  attr_reader :config
7
9
 
8
10
  def initialize
@@ -2,6 +2,6 @@
2
2
 
3
3
  module CKEditor5
4
4
  module Rails
5
- VERSION = '1.7.0'
5
+ VERSION = '1.8.0'
6
6
  end
7
7
  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.7.0
4
+ version: 1.8.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-11-12 00:00:00.000000000 Z
12
+ date: 2024-11-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -51,6 +51,7 @@ files:
51
51
  - lib/ckeditor5/rails/cdn/helpers.rb
52
52
  - lib/ckeditor5/rails/cdn/url_generator.rb
53
53
  - lib/ckeditor5/rails/cloud/helpers.rb
54
+ - lib/ckeditor5/rails/editor/config_helpers.rb
54
55
  - lib/ckeditor5/rails/editor/helpers.rb
55
56
  - lib/ckeditor5/rails/editor/props.rb
56
57
  - lib/ckeditor5/rails/editor/props_inline_plugin.rb