ckeditor5 1.31.8 → 1.32.2

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.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +15 -4
  3. data/lib/ckeditor5/rails/assets/webcomponent_bundle.rb +2 -21
  4. data/lib/ckeditor5/rails/version.rb +1 -1
  5. data/npm_package/dist/index.cjs +2 -0
  6. data/npm_package/dist/index.cjs.map +1 -0
  7. data/npm_package/dist/index.d.ts +1 -0
  8. data/npm_package/dist/index.mjs +723 -0
  9. data/npm_package/dist/index.mjs.map +1 -0
  10. data/npm_package/dist/src/components/context.d.ts +24 -0
  11. data/npm_package/dist/src/components/context.d.ts.map +1 -0
  12. data/npm_package/dist/src/components/editable.d.ts +34 -0
  13. data/npm_package/dist/src/components/editable.d.ts.map +1 -0
  14. data/npm_package/dist/src/components/editor/editor.d.ts +79 -0
  15. data/npm_package/dist/src/components/editor/editor.d.ts.map +1 -0
  16. data/npm_package/dist/src/components/editor/index.d.ts +3 -0
  17. data/npm_package/dist/src/components/editor/index.d.ts.map +1 -0
  18. data/npm_package/dist/src/components/editor/multiroot-editables-tracker.d.ts +36 -0
  19. data/npm_package/dist/src/components/editor/multiroot-editables-tracker.d.ts.map +1 -0
  20. data/npm_package/dist/src/components/index.d.ts +5 -0
  21. data/npm_package/dist/src/components/index.d.ts.map +1 -0
  22. data/npm_package/dist/src/components/ui-part.d.ts +2 -0
  23. data/npm_package/dist/src/components/ui-part.d.ts.map +1 -0
  24. data/npm_package/dist/src/helpers/exec-if-dom-ready.d.ts +7 -0
  25. data/npm_package/dist/src/helpers/exec-if-dom-ready.d.ts.map +1 -0
  26. data/npm_package/dist/src/helpers/index.d.ts +8 -0
  27. data/npm_package/dist/src/helpers/index.d.ts.map +1 -0
  28. data/npm_package/dist/src/helpers/inject-script.d.ts +8 -0
  29. data/npm_package/dist/src/helpers/inject-script.d.ts.map +1 -0
  30. data/npm_package/dist/src/helpers/is-safe-key.d.ts +8 -0
  31. data/npm_package/dist/src/helpers/is-safe-key.d.ts.map +1 -0
  32. data/npm_package/dist/src/helpers/load-async-css.d.ts +9 -0
  33. data/npm_package/dist/src/helpers/load-async-css.d.ts.map +1 -0
  34. data/npm_package/dist/src/helpers/load-async-imports.d.ts +25 -0
  35. data/npm_package/dist/src/helpers/load-async-imports.d.ts.map +1 -0
  36. data/npm_package/dist/src/helpers/resolve-config-element-references.d.ts +9 -0
  37. data/npm_package/dist/src/helpers/resolve-config-element-references.d.ts.map +1 -0
  38. data/npm_package/dist/src/helpers/uid.d.ts +7 -0
  39. data/npm_package/dist/src/helpers/uid.d.ts.map +1 -0
  40. data/npm_package/dist/src/index.d.ts +1 -0
  41. data/npm_package/dist/src/index.d.ts.map +1 -0
  42. data/npm_package/dist/vite.config.d.ts +3 -0
  43. data/npm_package/dist/vite.config.d.ts.map +1 -0
  44. data/npm_package/package.json +37 -0
  45. metadata +41 -6
  46. data/lib/ckeditor5/rails/assets/webcomponents/components/context.mjs +0 -123
  47. data/lib/ckeditor5/rails/assets/webcomponents/components/editable.mjs +0 -113
  48. data/lib/ckeditor5/rails/assets/webcomponents/components/editor.mjs +0 -778
  49. data/lib/ckeditor5/rails/assets/webcomponents/components/ui-part.mjs +0 -26
  50. data/lib/ckeditor5/rails/assets/webcomponents/utils.mjs +0 -235
@@ -0,0 +1,723 @@
1
+ function p(s) {
2
+ switch (document.readyState) {
3
+ case "loading":
4
+ document.addEventListener("DOMContentLoaded", s, { once: !0 });
5
+ break;
6
+ case "interactive":
7
+ case "complete":
8
+ setTimeout(s, 0);
9
+ break;
10
+ default:
11
+ console.warn("Unexpected document.readyState:", document.readyState), setTimeout(s, 0);
12
+ }
13
+ }
14
+ const g = /* @__PURE__ */ new Map();
15
+ function y(s) {
16
+ if (g.has(s))
17
+ return g.get(s);
18
+ const t = new Promise((e, i) => {
19
+ const n = document.createElement("script");
20
+ n.src = s, n.onload = e, n.onerror = i, document.head.appendChild(n);
21
+ });
22
+ return g.set(s, t), t;
23
+ }
24
+ function v(s) {
25
+ return typeof s == "string" && s !== "__proto__" && s !== "constructor" && s !== "prototype";
26
+ }
27
+ function C(s) {
28
+ return Array.from(document.styleSheets).some(
29
+ (t) => t.href === s || t.href === new URL(s, window.location.href).href
30
+ );
31
+ }
32
+ function w(s = []) {
33
+ const t = s.map(
34
+ (e) => new Promise((i, n) => {
35
+ if (C(e)) {
36
+ i();
37
+ return;
38
+ }
39
+ const r = document.createElement("link");
40
+ r.rel = "stylesheet", r.href = e, r.onerror = n, r.onload = () => i(), document.head.appendChild(r);
41
+ })
42
+ );
43
+ return Promise.all(t);
44
+ }
45
+ function h(s = []) {
46
+ const t = async ({ url: i, import_name: n, import_as: r, window_name: o, stylesheets: a }) => {
47
+ if (a?.length && await w(a), o) {
48
+ let l = function() {
49
+ return Object.prototype.hasOwnProperty.call(window, o);
50
+ };
51
+ if (i && !l() && await y(i), l() || window.dispatchEvent(
52
+ new CustomEvent(`ckeditor:request-cjs-plugin:${o}`)
53
+ ), !l())
54
+ throw new Error(
55
+ `Plugin window['${o}'] not found in global scope. Please ensure the plugin is loaded before CKEditor initialization.`
56
+ );
57
+ return window[o];
58
+ }
59
+ const c = await import(n), d = c[r || "default"];
60
+ if (!d)
61
+ throw new Error(
62
+ `Plugin "${r || "default"}" not found in the ESM module "${n}"! Available imports: ${Object.keys(c).join(", ")}! Consider changing "import_as" value.`
63
+ );
64
+ return d;
65
+ };
66
+ function e(i) {
67
+ return t(typeof i == "string" ? { import_name: "ckeditor5", import_as: i } : i);
68
+ }
69
+ return Promise.all(s.map(e));
70
+ }
71
+ function u(s) {
72
+ if (!s || typeof s != "object")
73
+ return s;
74
+ if (Array.isArray(s))
75
+ return s.map((i) => u(i));
76
+ const t = s;
77
+ if (t.$element && typeof t.$element == "string") {
78
+ const i = document.querySelector(t.$element);
79
+ return i || console.warn(`Element not found for selector: ${t.$element}`), i || null;
80
+ }
81
+ const e = /* @__PURE__ */ Object.create(null);
82
+ for (const [i, n] of Object.entries(s))
83
+ e[i] = u(n);
84
+ return e;
85
+ }
86
+ function A() {
87
+ return Math.random().toString(36).substring(2);
88
+ }
89
+ class x extends HTMLElement {
90
+ instance = null;
91
+ instancePromise = Promise.withResolvers();
92
+ #e = /* @__PURE__ */ new Set();
93
+ static get observedAttributes() {
94
+ return ["plugins", "config"];
95
+ }
96
+ async connectedCallback() {
97
+ try {
98
+ p(() => this.#t());
99
+ } catch (t) {
100
+ console.error("Failed to initialize context:", t), this.dispatchEvent(new CustomEvent("context-error", { detail: t }));
101
+ }
102
+ }
103
+ async attributeChangedCallback(t, e, i) {
104
+ e !== null && e !== i && await this.#t();
105
+ }
106
+ async disconnectedCallback() {
107
+ this.instance && (await this.instance.destroy(), this.instance = null);
108
+ }
109
+ /**
110
+ * Register editor component with this context
111
+ *
112
+ * @param editor - Editor component to register.
113
+ */
114
+ registerEditor(t) {
115
+ this.#e.add(t);
116
+ }
117
+ /**
118
+ * Unregister editor component from this context
119
+ *
120
+ * @param editor - Editor component to unregister
121
+ */
122
+ unregisterEditor(t) {
123
+ this.#e.delete(t);
124
+ }
125
+ /**
126
+ * Initialize CKEditor context with shared configuration
127
+ *
128
+ * @private
129
+ */
130
+ async #t() {
131
+ this.instance && (this.instancePromise = Promise.withResolvers(), await this.instance.destroy(), this.instance = null), window.dispatchEvent(
132
+ new CustomEvent("ckeditor:context:attach:before", { detail: { element: this } })
133
+ );
134
+ const { Context: t, ContextWatchdog: e } = await import("ckeditor5"), i = await this.#i(), n = this.#s();
135
+ window.dispatchEvent(
136
+ new CustomEvent("ckeditor:context:attach", { detail: { config: n, element: this } })
137
+ ), this.instance = new e(t, {
138
+ crashNumberLimit: 10
139
+ }), await this.instance.create({
140
+ ...n,
141
+ plugins: i
142
+ }), this.instance.on("itemError", (...r) => {
143
+ console.error("Context item error:", ...r);
144
+ }), this.instancePromise.resolve(this.instance), this.dispatchEvent(new CustomEvent("context-ready", { detail: this.instance })), await Promise.all(
145
+ [...this.#e].map((r) => r.reinitializeEditor())
146
+ );
147
+ }
148
+ async #i() {
149
+ const t = this.getAttribute("plugins");
150
+ return h(t ? JSON.parse(t) : []);
151
+ }
152
+ /**
153
+ * Gets context configuration with resolved element references.
154
+ *
155
+ * @private
156
+ */
157
+ #s() {
158
+ const t = JSON.parse(this.getAttribute("config") || "{}");
159
+ return u(t);
160
+ }
161
+ }
162
+ customElements.define("ckeditor-context-component", x);
163
+ class P extends HTMLElement {
164
+ /**
165
+ * List of attributes that trigger updates when changed
166
+ *
167
+ * @static
168
+ * @returns {string[]} Array of attribute names to observe
169
+ */
170
+ static get observedAttributes() {
171
+ return ["name"];
172
+ }
173
+ /**
174
+ * Gets the name of this editable region
175
+ */
176
+ get name() {
177
+ return this.getAttribute("name") || "editable";
178
+ }
179
+ /**
180
+ * Gets the actual editable DOM element.
181
+ */
182
+ get editableElement() {
183
+ return this.querySelector("div");
184
+ }
185
+ /**
186
+ * Lifecycle callback when element is added to DOM
187
+ * Sets up the editable element and registers it with the parent editor
188
+ */
189
+ connectedCallback() {
190
+ p(() => {
191
+ const t = this.#e();
192
+ if (!t)
193
+ throw new Error("ckeditor-editable-component must be a child of ckeditor-component");
194
+ if (this.innerHTML = `<div>${this.innerHTML}</div>`, this.style.display = "block", t.isDecoupled())
195
+ t.runAfterEditorReady((e) => {
196
+ this.appendChild(e.ui.view[this.name].element);
197
+ });
198
+ else {
199
+ if (!this.name)
200
+ throw new Error('Editable component missing required "name" attribute');
201
+ t.editables[this.name] = this;
202
+ }
203
+ });
204
+ }
205
+ /**
206
+ * Lifecycle callback for attribute changes
207
+ * Handles name changes and propagates other attributes to editable element
208
+ */
209
+ attributeChangedCallback(t, e, i) {
210
+ if (e !== i)
211
+ if (t === "name") {
212
+ if (!e)
213
+ return;
214
+ const n = this.#e();
215
+ n && (n.editables[i] = n.editables[e], delete n.editables[e]);
216
+ } else
217
+ this.editableElement.setAttribute(t, i);
218
+ }
219
+ /**
220
+ * Lifecycle callback when element is removed
221
+ * Un-registers this editable from the parent editor
222
+ */
223
+ disconnectedCallback() {
224
+ const t = this.#e();
225
+ t && delete t.editables[this.name];
226
+ }
227
+ /**
228
+ * Finds the parent editor component
229
+ */
230
+ #e() {
231
+ return this.closest("ckeditor-component") || document.body.querySelector("ckeditor-component");
232
+ }
233
+ }
234
+ customElements.define("ckeditor-editable-component", P);
235
+ class b {
236
+ #e;
237
+ #t;
238
+ /**
239
+ * Creates new tracker instance wrapped in a Proxy for dynamic property access
240
+ *
241
+ * @param editorElement - Parent editor component reference
242
+ * @param initialEditables - Initial editable elements
243
+ * @returns Proxy wrapping the tracker
244
+ */
245
+ constructor(t, e = {}) {
246
+ return this.#e = t, this.#t = e, new Proxy(this, {
247
+ /**
248
+ * Handles property access, returns class methods or editable elements
249
+ *
250
+ * @param target - The tracker instance
251
+ * @param name - Property name being accessed
252
+ */
253
+ get(i, n) {
254
+ return typeof i[n] == "function" ? i[n].bind(i) : i.#t[n];
255
+ },
256
+ /**
257
+ * Handles setting new editable elements, triggers root attachment
258
+ *
259
+ * @param target - The tracker instance
260
+ * @param name - Name of the editable root
261
+ * @param element - Element to attach as editable
262
+ */
263
+ set(i, n, r) {
264
+ return i.#t[n] !== r && (i.attachRoot(n, r), i.#t[n] = r), !0;
265
+ },
266
+ /**
267
+ * Handles removing editable elements, triggers root detachment
268
+ *
269
+ * @param target - The tracker instance
270
+ * @param name - Name of the root to remove
271
+ */
272
+ deleteProperty(i, n) {
273
+ return i.detachRoot(n), delete i.#t[n], !0;
274
+ }
275
+ });
276
+ }
277
+ /**
278
+ * Attaches a new editable root to the editor.
279
+ * Creates new editor root and binds UI elements.
280
+ *
281
+ * @param name - Name of the editable root
282
+ * @param element - DOM element to use as editable
283
+ * @returns Resolves when root is attached
284
+ */
285
+ async attachRoot(t, e) {
286
+ return await this.detachRoot(t), this.#e.runAfterEditorReady((i) => {
287
+ const { ui: n, editing: r, model: o } = i;
288
+ i.addRoot(t, {
289
+ isUndoable: !1,
290
+ data: e.innerHTML
291
+ });
292
+ const a = o.document.getRoot(t);
293
+ n.getEditableElement(t) && i.detachEditable(a);
294
+ const c = n.view.createEditable(t, e);
295
+ n.addEditable(c), r.view.forceRender();
296
+ });
297
+ }
298
+ /**
299
+ * Detaches an editable root from the editor.
300
+ * Removes editor root and cleans up UI bindings.
301
+ *
302
+ * @param name - Name of root to detach
303
+ * @returns Resolves when root is detached
304
+ */
305
+ async detachRoot(t) {
306
+ return this.#e.runAfterEditorReady((e) => {
307
+ const i = e.model.document.getRoot(t);
308
+ i && (e.detachEditable(i), e.detachRoot(t, !0));
309
+ });
310
+ }
311
+ /**
312
+ * Gets all currently tracked editable elements
313
+ *
314
+ * @returns Map of all editable elements
315
+ */
316
+ getAll() {
317
+ return this.#t;
318
+ }
319
+ }
320
+ class m extends HTMLElement {
321
+ instancePromise = Promise.withResolvers();
322
+ watchdog = null;
323
+ instance = null;
324
+ editables = /* @__PURE__ */ Object.create({});
325
+ #e = "";
326
+ #t = null;
327
+ #i = null;
328
+ #s = null;
329
+ /**
330
+ * List of attributes that trigger updates when changed.
331
+ */
332
+ static get observedAttributes() {
333
+ return ["config", "plugins", "translations", "type"];
334
+ }
335
+ /**
336
+ * List of input attributes that trigger updates when changed.
337
+ */
338
+ static get inputAttributes() {
339
+ return ["name", "required", "value"];
340
+ }
341
+ get oneditorchange() {
342
+ return this.#r("editorchange");
343
+ }
344
+ set oneditorchange(t) {
345
+ this.#o("editorchange", t);
346
+ }
347
+ get oneditorready() {
348
+ return this.#r("editorready");
349
+ }
350
+ set oneditorready(t) {
351
+ this.#o("editorready", t);
352
+ }
353
+ get oneditorerror() {
354
+ return this.#r("editorerror");
355
+ }
356
+ set oneditorerror(t) {
357
+ this.#o("editorerror", t);
358
+ }
359
+ /**
360
+ * Gets event handler function from attribute or property
361
+ *
362
+ * @private
363
+ * @param name - Event name without 'on' prefix
364
+ * @returns Event handler or null
365
+ */
366
+ #r(t) {
367
+ if (this.hasAttribute(`on${t}`)) {
368
+ const e = this.getAttribute(`on${t}`);
369
+ if (!v(e))
370
+ throw new Error(`Unsafe event handler attribute value: ${e}`);
371
+ return window[e] || new Function("event", e);
372
+ }
373
+ return this[`#${t}Handler`];
374
+ }
375
+ /**
376
+ * Sets event handler function
377
+ *
378
+ * @private
379
+ * @param name - Event name without 'on' prefix
380
+ * @param handler - Event handler
381
+ */
382
+ #o(t, e) {
383
+ typeof e == "string" ? this.setAttribute(`on${t}`, e) : (this.removeAttribute(`on${t}`), this[`#${t}Handler`] = e);
384
+ }
385
+ /**
386
+ * Lifecycle callback when element is connected to DOM
387
+ * Initializes the editor when DOM is ready
388
+ *
389
+ * @protected
390
+ */
391
+ connectedCallback() {
392
+ this.#t = this.closest("ckeditor-context-component"), this.#e = this.innerHTML;
393
+ try {
394
+ p(async () => {
395
+ this.#t && (await this.#t.instancePromise.promise, this.#t.registerEditor(this)), await this.reinitializeEditor();
396
+ });
397
+ } catch (t) {
398
+ console.error("Failed to initialize editor:", t);
399
+ const e = new CustomEvent("editor-error", { detail: t });
400
+ this.dispatchEvent(e), this.oneditorerror?.(e);
401
+ }
402
+ }
403
+ /**
404
+ * Handles attribute changes and reinitializes editor if needed
405
+ *
406
+ * @protected
407
+ * @param name - Name of changed attribute
408
+ * @param oldValue - Previous attribute value
409
+ * @param newValue - New attribute value
410
+ */
411
+ async attributeChangedCallback(t, e, i) {
412
+ e !== null && e !== i && m.observedAttributes.includes(t) && this.isConnected && await this.reinitializeEditor();
413
+ }
414
+ /**
415
+ * Lifecycle callback when element is removed from DOM
416
+ * Destroys the editor instance
417
+ * @protected
418
+ */
419
+ async disconnectedCallback() {
420
+ this.#t && this.#t.unregisterEditor(this);
421
+ try {
422
+ await this.#d();
423
+ } catch (t) {
424
+ console.error("Failed to destroy editor:", t);
425
+ }
426
+ }
427
+ /**
428
+ * Runs a callback after the editor is ready. It waits for editor
429
+ * initialization if needed.
430
+ *
431
+ * @param callback - Callback to run
432
+ */
433
+ runAfterEditorReady(t) {
434
+ return this.instance ? Promise.resolve(t(this.instance)) : this.instancePromise.promise.then(t);
435
+ }
436
+ /**
437
+ * Determines appropriate editor element tag based on editor type
438
+ */
439
+ get #n() {
440
+ switch (this.getAttribute("type")) {
441
+ case "ClassicEditor":
442
+ return "textarea";
443
+ default:
444
+ return "div";
445
+ }
446
+ }
447
+ /**
448
+ * Gets the CKEditor context instance if available.
449
+ */
450
+ get #a() {
451
+ return this.#t?.instance;
452
+ }
453
+ /**
454
+ * Destroys the editor instance and watchdog if available
455
+ */
456
+ async #d() {
457
+ this.#i && await this.#a.remove(this.#i), await this.instance?.destroy(), this.watchdog?.destroy();
458
+ }
459
+ /**
460
+ * Gets editor configuration with resolved element references
461
+ */
462
+ #l() {
463
+ const t = JSON.parse(this.getAttribute("config") || "{}");
464
+ return u(t);
465
+ }
466
+ /**
467
+ * Creates a new CKEditor instance
468
+ */
469
+ async #u(t) {
470
+ await Promise.all([
471
+ this.#b(),
472
+ this.#w()
473
+ ]);
474
+ let e = t;
475
+ t instanceof b ? e = t.getAll() : typeof t != "string" && (e = t.main);
476
+ const i = {
477
+ ...e instanceof HTMLElement && { element: e },
478
+ ...typeof e == "string" && { data: e },
479
+ ...e instanceof Object && { editables: e }
480
+ };
481
+ window.dispatchEvent(
482
+ new CustomEvent("ckeditor:attach:before", { detail: i })
483
+ );
484
+ const n = await this.#v(), [r, o] = await Promise.all([
485
+ this.#y(),
486
+ this.#E()
487
+ ]), a = {
488
+ ...this.#l(),
489
+ ...o.length && {
490
+ translations: o
491
+ },
492
+ plugins: r
493
+ };
494
+ window.dispatchEvent(
495
+ new CustomEvent("ckeditor:attach", { detail: { config: a, ...i } })
496
+ ), console.warn("Initializing CKEditor with:", { config: a, watchdog: this.hasWatchdog(), context: this.#t });
497
+ let c = null, d = null, l = null;
498
+ if (this.#t)
499
+ l = A(), await this.#a.add({
500
+ creator: (f, E) => n.create(f, E),
501
+ id: l,
502
+ sourceElementOrData: e,
503
+ type: "editor",
504
+ config: a
505
+ }), d = this.#a.getItem(l);
506
+ else if (this.hasWatchdog()) {
507
+ const { EditorWatchdog: f } = await import("ckeditor5");
508
+ c = new f(n), await c.create(e, a), d = c.editor;
509
+ } else
510
+ d = await n.create(e, a);
511
+ return console.warn("CKEditor initialized:", {
512
+ instance: d,
513
+ watchdog: c,
514
+ config: d.config._config
515
+ }), {
516
+ contextId: l,
517
+ instance: d,
518
+ watchdog: c
519
+ };
520
+ }
521
+ /**
522
+ * Re-initializes the editor by destroying existing instance and creating new one
523
+ *
524
+ * @private
525
+ * @returns {Promise<void>}
526
+ */
527
+ async reinitializeEditor() {
528
+ this.instance && (this.instancePromise = Promise.withResolvers(), await this.#d(), this.instance = null), this.style.display = "block", !this.isMultiroot() && !this.isDecoupled() && (this.innerHTML = `<${this.#n}>${this.#e}</${this.#n}>`, this.#p()), this.isMultiroot() ? this.editables = new b(this, this.#h()) : this.isDecoupled() ? this.editables = null : this.editables = this.#h();
529
+ try {
530
+ const { watchdog: t, instance: e, contextId: i } = await this.#u(this.editables || this.#l().initialData || "");
531
+ this.watchdog = t, this.instance = e, this.#i = i, this.#f(), this.#g(), this.#m(), this.instancePromise.resolve(this.instance);
532
+ const n = new CustomEvent("editor-ready", { detail: this.instance });
533
+ this.dispatchEvent(n), this.oneditorready?.(n);
534
+ } catch (t) {
535
+ throw this.instancePromise.reject(t), t;
536
+ }
537
+ }
538
+ /**
539
+ * Sets up data change listener that broadcasts content changes
540
+ */
541
+ #m() {
542
+ const t = (i) => this.instance.getData({ rootName: i }), e = () => this.instance?.model.document.getRootNames().reduce((i, n) => ({
543
+ ...i,
544
+ [n]: t(n)
545
+ }), {});
546
+ this.instance?.model.document.on("change:data", () => {
547
+ const i = new CustomEvent("editor-change", {
548
+ detail: {
549
+ editor: this.instance,
550
+ data: e()
551
+ },
552
+ bubbles: !0
553
+ });
554
+ this.dispatchEvent(i), this.oneditorchange?.(i);
555
+ });
556
+ }
557
+ /**
558
+ * Checks if current editor is classic type
559
+ */
560
+ isClassic() {
561
+ return this.getAttribute("type") === "ClassicEditor";
562
+ }
563
+ /**
564
+ * Checks if current editor is balloon type
565
+ */
566
+ isBallon() {
567
+ return this.getAttribute("type") === "BalloonEditor";
568
+ }
569
+ /**
570
+ * Checks if current editor is multiroot type
571
+ */
572
+ isMultiroot() {
573
+ return this.getAttribute("type") === "MultiRootEditor";
574
+ }
575
+ /**
576
+ * Checks if current editor is decoupled type
577
+ */
578
+ isDecoupled() {
579
+ return this.getAttribute("type") === "DecoupledEditor";
580
+ }
581
+ /**
582
+ * Checks if current editor has watchdog enabled
583
+ */
584
+ hasWatchdog() {
585
+ return this.getAttribute("watchdog") === "true";
586
+ }
587
+ /**
588
+ * Queries and validates editable elements
589
+ */
590
+ #h() {
591
+ if (this.isDecoupled())
592
+ return {};
593
+ if (this.isMultiroot())
594
+ return [...this.querySelectorAll("ckeditor-editable-component")].reduce((i, n) => {
595
+ if (!n.name)
596
+ throw new Error('Editable component missing required "name" attribute');
597
+ return i[n.name] = n, i;
598
+ }, /* @__PURE__ */ Object.create(null));
599
+ const t = this.querySelector(this.#n);
600
+ if (!t)
601
+ throw new Error(`No ${this.#n} element found`);
602
+ return { main: t };
603
+ }
604
+ /**
605
+ * Copies input-related attributes from component to the main editable element
606
+ *
607
+ * @private
608
+ */
609
+ #p() {
610
+ const t = this.querySelector("textarea");
611
+ if (t)
612
+ for (const e of m.inputAttributes)
613
+ this.hasAttribute(e) && t.setAttribute(e, this.getAttribute(e));
614
+ }
615
+ /**
616
+ * Sets up content sync between editor and textarea element.
617
+ *
618
+ * @private
619
+ */
620
+ #f() {
621
+ if (!this.instance)
622
+ return;
623
+ const t = this.querySelector("textarea");
624
+ if (!t)
625
+ return;
626
+ const e = () => {
627
+ this.style.position = "relative", t.innerHTML = "", t.value = this.instance.getData(), t.tabIndex = -1, Object.assign(t.style, {
628
+ display: "flex",
629
+ position: "absolute",
630
+ bottom: "0",
631
+ left: "50%",
632
+ width: "1px",
633
+ height: "1px",
634
+ opacity: "0",
635
+ pointerEvents: "none",
636
+ margin: "0",
637
+ padding: "0",
638
+ border: "none"
639
+ });
640
+ };
641
+ e(), this.instance.model.document.on("change:data", () => {
642
+ t.dispatchEvent(new Event("input", { bubbles: !0 })), t.dispatchEvent(new Event("change", { bubbles: !0 })), e();
643
+ });
644
+ }
645
+ /**
646
+ * Sets up editable height for ClassicEditor
647
+ *
648
+ * @private
649
+ */
650
+ #g() {
651
+ if (!this.isClassic() && !this.isBallon())
652
+ return;
653
+ const { instance: t } = this, e = Number.parseInt(this.getAttribute("editable-height"), 10);
654
+ Number.isNaN(e) || t.editing.view.change((i) => {
655
+ i.setStyle("height", `${e}px`, t.editing.view.document.getRoot());
656
+ });
657
+ }
658
+ /**
659
+ * Gets bundle JSON description from translations attribute
660
+ */
661
+ #c() {
662
+ return this.#s ||= JSON.parse(this.getAttribute("bundle"));
663
+ }
664
+ /**
665
+ * Checks if all required stylesheets are injected. If not, inject.
666
+ */
667
+ async #b() {
668
+ await w(this.#c().stylesheets || []);
669
+ }
670
+ /**
671
+ * Checks if all required scripts are injected. If not, inject.
672
+ */
673
+ async #w() {
674
+ const t = (this.#c().scripts || []).filter((e) => !!e.window_name);
675
+ await h(t);
676
+ }
677
+ /**
678
+ * Loads translation modules
679
+ */
680
+ async #E() {
681
+ const t = this.#c().scripts.filter((e) => e.translation);
682
+ return h(t);
683
+ }
684
+ /**
685
+ * Loads plugin modules
686
+ */
687
+ async #y() {
688
+ const t = this.getAttribute("plugins"), i = (t ? JSON.parse(t) : []).map(
689
+ (n) => typeof n == "string" ? { import_name: "ckeditor5", import_as: n } : n
690
+ );
691
+ return h(i);
692
+ }
693
+ /**
694
+ * Gets editor constructor based on type attribute
695
+ */
696
+ async #v() {
697
+ const t = await import("ckeditor5"), e = this.getAttribute("type");
698
+ if (!e || !Object.prototype.hasOwnProperty.call(t, e))
699
+ throw new Error(`Invalid editor type: ${e}`);
700
+ return t[e];
701
+ }
702
+ }
703
+ customElements.define("ckeditor-component", m);
704
+ class S extends HTMLElement {
705
+ /**
706
+ * Lifecycle callback when element is added to DOM.
707
+ * Adds the toolbar to the editor UI.
708
+ */
709
+ connectedCallback() {
710
+ p(async () => {
711
+ const t = this.getAttribute("name"), e = await this.#e().instancePromise.promise;
712
+ this.appendChild(e.ui.view[t].element);
713
+ });
714
+ }
715
+ /**
716
+ * Finds the parent editor component.
717
+ */
718
+ #e() {
719
+ return this.closest("ckeditor-component") || document.body.querySelector("ckeditor-component");
720
+ }
721
+ }
722
+ customElements.define("ckeditor-ui-part-component", S);
723
+ //# sourceMappingURL=index.mjs.map