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.
- checksums.yaml +4 -4
- data/README.md +15 -4
- data/lib/ckeditor5/rails/assets/webcomponent_bundle.rb +2 -21
- data/lib/ckeditor5/rails/version.rb +1 -1
- data/npm_package/dist/index.cjs +2 -0
- data/npm_package/dist/index.cjs.map +1 -0
- data/npm_package/dist/index.d.ts +1 -0
- data/npm_package/dist/index.mjs +723 -0
- data/npm_package/dist/index.mjs.map +1 -0
- data/npm_package/dist/src/components/context.d.ts +24 -0
- data/npm_package/dist/src/components/context.d.ts.map +1 -0
- data/npm_package/dist/src/components/editable.d.ts +34 -0
- data/npm_package/dist/src/components/editable.d.ts.map +1 -0
- data/npm_package/dist/src/components/editor/editor.d.ts +79 -0
- data/npm_package/dist/src/components/editor/editor.d.ts.map +1 -0
- data/npm_package/dist/src/components/editor/index.d.ts +3 -0
- data/npm_package/dist/src/components/editor/index.d.ts.map +1 -0
- data/npm_package/dist/src/components/editor/multiroot-editables-tracker.d.ts +36 -0
- data/npm_package/dist/src/components/editor/multiroot-editables-tracker.d.ts.map +1 -0
- data/npm_package/dist/src/components/index.d.ts +5 -0
- data/npm_package/dist/src/components/index.d.ts.map +1 -0
- data/npm_package/dist/src/components/ui-part.d.ts +2 -0
- data/npm_package/dist/src/components/ui-part.d.ts.map +1 -0
- data/npm_package/dist/src/helpers/exec-if-dom-ready.d.ts +7 -0
- data/npm_package/dist/src/helpers/exec-if-dom-ready.d.ts.map +1 -0
- data/npm_package/dist/src/helpers/index.d.ts +8 -0
- data/npm_package/dist/src/helpers/index.d.ts.map +1 -0
- data/npm_package/dist/src/helpers/inject-script.d.ts +8 -0
- data/npm_package/dist/src/helpers/inject-script.d.ts.map +1 -0
- data/npm_package/dist/src/helpers/is-safe-key.d.ts +8 -0
- data/npm_package/dist/src/helpers/is-safe-key.d.ts.map +1 -0
- data/npm_package/dist/src/helpers/load-async-css.d.ts +9 -0
- data/npm_package/dist/src/helpers/load-async-css.d.ts.map +1 -0
- data/npm_package/dist/src/helpers/load-async-imports.d.ts +25 -0
- data/npm_package/dist/src/helpers/load-async-imports.d.ts.map +1 -0
- data/npm_package/dist/src/helpers/resolve-config-element-references.d.ts +9 -0
- data/npm_package/dist/src/helpers/resolve-config-element-references.d.ts.map +1 -0
- data/npm_package/dist/src/helpers/uid.d.ts +7 -0
- data/npm_package/dist/src/helpers/uid.d.ts.map +1 -0
- data/npm_package/dist/src/index.d.ts +1 -0
- data/npm_package/dist/src/index.d.ts.map +1 -0
- data/npm_package/dist/vite.config.d.ts +3 -0
- data/npm_package/dist/vite.config.d.ts.map +1 -0
- data/npm_package/package.json +37 -0
- metadata +41 -6
- data/lib/ckeditor5/rails/assets/webcomponents/components/context.mjs +0 -123
- data/lib/ckeditor5/rails/assets/webcomponents/components/editable.mjs +0 -113
- data/lib/ckeditor5/rails/assets/webcomponents/components/editor.mjs +0 -778
- data/lib/ckeditor5/rails/assets/webcomponents/components/ui-part.mjs +0 -26
- 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
|