ckeditor5-livewire 1.9.0 → 1.11.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.
Files changed (46) hide show
  1. package/dist/hooks/editable.d.ts +3 -5
  2. package/dist/hooks/editable.d.ts.map +1 -1
  3. package/dist/hooks/editor/editor.d.ts +0 -4
  4. package/dist/hooks/editor/editor.d.ts.map +1 -1
  5. package/dist/hooks/editor/plugins/livewire-sync.d.ts.map +1 -1
  6. package/dist/hooks/editor/utils/cleanup-orphan-editor-elements.d.ts +8 -0
  7. package/dist/hooks/editor/utils/cleanup-orphan-editor-elements.d.ts.map +1 -0
  8. package/dist/hooks/editor/utils/create-editor-in-context.d.ts +6 -1
  9. package/dist/hooks/editor/utils/create-editor-in-context.d.ts.map +1 -1
  10. package/dist/hooks/editor/utils/index.d.ts +2 -0
  11. package/dist/hooks/editor/utils/index.d.ts.map +1 -1
  12. package/dist/hooks/editor/utils/is-multiroot-editor-instance.d.ts +6 -0
  13. package/dist/hooks/editor/utils/is-multiroot-editor-instance.d.ts.map +1 -0
  14. package/dist/hooks/editor/utils/wrap-with-watchdog.d.ts +7 -16
  15. package/dist/hooks/editor/utils/wrap-with-watchdog.d.ts.map +1 -1
  16. package/dist/hooks/ui-part.d.ts +2 -6
  17. package/dist/hooks/ui-part.d.ts.map +1 -1
  18. package/dist/index.cjs +2 -2
  19. package/dist/index.cjs.map +1 -1
  20. package/dist/index.mjs +297 -220
  21. package/dist/index.mjs.map +1 -1
  22. package/dist/shared/are-maps-equal.d.ts +11 -0
  23. package/dist/shared/are-maps-equal.d.ts.map +1 -0
  24. package/dist/shared/async-registry.d.ts +43 -10
  25. package/dist/shared/async-registry.d.ts.map +1 -1
  26. package/dist/shared/index.d.ts +1 -0
  27. package/dist/shared/index.d.ts.map +1 -1
  28. package/package.json +3 -3
  29. package/src/hooks/context/context.test.ts +3 -1
  30. package/src/hooks/editable.ts +73 -46
  31. package/src/hooks/editor/editor.test.ts +44 -9
  32. package/src/hooks/editor/editor.ts +159 -149
  33. package/src/hooks/editor/plugins/livewire-sync.ts +17 -8
  34. package/src/hooks/editor/utils/cleanup-orphan-editor-elements.test.ts +285 -0
  35. package/src/hooks/editor/utils/cleanup-orphan-editor-elements.ts +60 -0
  36. package/src/hooks/editor/utils/create-editor-in-context.ts +6 -2
  37. package/src/hooks/editor/utils/index.ts +2 -0
  38. package/src/hooks/editor/utils/is-multiroot-editor-instance.ts +8 -0
  39. package/src/hooks/editor/utils/wrap-with-watchdog.test.ts +34 -14
  40. package/src/hooks/editor/utils/wrap-with-watchdog.ts +16 -26
  41. package/src/hooks/ui-part.ts +10 -16
  42. package/src/shared/are-maps-equal.test.ts +56 -0
  43. package/src/shared/are-maps-equal.ts +22 -0
  44. package/src/shared/async-registry.test.ts +212 -31
  45. package/src/shared/async-registry.ts +178 -61
  46. package/src/shared/index.ts +1 -0
package/dist/index.mjs CHANGED
@@ -42,12 +42,22 @@ function t(e, t) {
42
42
  });
43
43
  }
44
44
  //#endregion
45
+ //#region src/shared/are-maps-equal.ts
46
+ function n(e, t) {
47
+ if (!e || e.size !== t.size) return !1;
48
+ for (let [n, r] of e) if (!t.has(n) || t.get(n) !== r) return !1;
49
+ return !0;
50
+ }
51
+ //#endregion
45
52
  //#region src/shared/async-registry.ts
46
- var n = class {
53
+ var r = class {
47
54
  items = /* @__PURE__ */ new Map();
48
55
  initializationErrors = /* @__PURE__ */ new Map();
49
56
  pendingCallbacks = /* @__PURE__ */ new Map();
50
57
  watchers = /* @__PURE__ */ new Set();
58
+ batchDepth = 0;
59
+ lastNotifiedItems = null;
60
+ lastNotifiedErrors = null;
51
61
  execute(e, t, n) {
52
62
  let r = this.items.get(e), i = this.initializationErrors.get(e);
53
63
  return i ? (n?.(i), Promise.reject(i)) : r ? Promise.resolve(t(r)) : new Promise((r, i) => {
@@ -57,28 +67,50 @@ var n = class {
57
67
  }), n ? a.error.push(n) : a.error.push(i);
58
68
  });
59
69
  }
70
+ mountEffect(e, t) {
71
+ let n, r, i = !1, a = this.watch((o) => {
72
+ let s = o.get(e);
73
+ if (s !== r && (n?.(), n = void 0, r = s, s)) try {
74
+ let e = t(s);
75
+ i ? (e?.(), a()) : n = e;
76
+ } catch (e) {
77
+ throw console.error(e), e;
78
+ }
79
+ });
80
+ return () => {
81
+ i = !0, r && (a(), n?.(), n = void 0);
82
+ };
83
+ }
60
84
  register(e, t) {
61
- if (this.items.has(e)) throw Error(`Item with ID "${e}" is already registered.`);
62
- this.resetErrors(e), this.items.set(e, t);
63
- let n = this.pendingCallbacks.get(e);
64
- n && (n.success.forEach((e) => e(t)), this.pendingCallbacks.delete(e)), this.registerAsDefault(e, t), this.notifyWatchers();
85
+ this.batch(() => {
86
+ if (this.items.has(e)) throw Error(`Item with ID "${e}" is already registered.`);
87
+ this.resetErrors(e), this.items.set(e, t);
88
+ let n = this.pendingCallbacks.get(e);
89
+ n && (n.success.forEach((e) => e(t)), this.pendingCallbacks.delete(e)), this.items.size === 1 && e !== null && this.register(null, t);
90
+ });
65
91
  }
66
92
  error(e, t) {
67
- this.items.delete(e), this.initializationErrors.set(e, t);
68
- let n = this.pendingCallbacks.get(e);
69
- n && (n.error.forEach((e) => e(t)), this.pendingCallbacks.delete(e)), this.initializationErrors.size === 1 && !this.items.size && this.error(null, t), this.notifyWatchers();
93
+ this.batch(() => {
94
+ this.items.delete(e), this.initializationErrors.set(e, t);
95
+ let n = this.pendingCallbacks.get(e);
96
+ n && (n.error.forEach((e) => e(t)), this.pendingCallbacks.delete(e)), this.initializationErrors.size === 1 && !this.items.size && this.error(null, t);
97
+ });
70
98
  }
71
99
  resetErrors(e) {
72
100
  let { initializationErrors: t } = this;
73
101
  t.has(null) && t.get(null) === t.get(e) && t.delete(null), t.delete(e);
74
102
  }
75
- unregister(e) {
76
- if (!this.items.has(e)) throw Error(`Item with ID "${e}" is not registered.`);
77
- e && this.items.get(null) === this.items.get(e) && this.unregister(null), this.items.delete(e), this.pendingCallbacks.delete(e), this.notifyWatchers();
103
+ unregister(e, t = !0) {
104
+ this.batch(() => {
105
+ e && this.items.get(null) === this.items.get(e) && this.unregister(null, !1), this.items.delete(e), t && this.pendingCallbacks.delete(e), this.resetErrors(e);
106
+ });
78
107
  }
79
108
  getItems() {
80
109
  return Array.from(this.items.values());
81
110
  }
111
+ getItem(e) {
112
+ return this.items.get(e);
113
+ }
82
114
  hasItem(e) {
83
115
  return this.items.has(e);
84
116
  }
@@ -89,7 +121,18 @@ var n = class {
89
121
  }
90
122
  async destroyAll() {
91
123
  let e = Array.from(new Set(this.items.values())).map((e) => e.destroy());
92
- this.items.clear(), this.pendingCallbacks.clear(), await Promise.all(e), this.notifyWatchers();
124
+ this.items.clear(), this.pendingCallbacks.clear(), await Promise.all(e), this.flushWatchers();
125
+ }
126
+ async reset() {
127
+ await this.destroyAll(), this.watchers.clear();
128
+ }
129
+ batch(e) {
130
+ this.batchDepth++;
131
+ try {
132
+ return e();
133
+ } finally {
134
+ this.batchDepth--, this.batchDepth === 0 && this.flushWatchers();
135
+ }
93
136
  }
94
137
  watch(e) {
95
138
  return this.watchers.add(e), e(new Map(this.items), new Map(this.initializationErrors)), this.unwatch.bind(this, e);
@@ -97,8 +140,8 @@ var n = class {
97
140
  unwatch(e) {
98
141
  this.watchers.delete(e);
99
142
  }
100
- notifyWatchers() {
101
- this.watchers.forEach((e) => e(new Map(this.items), new Map(this.initializationErrors)));
143
+ flushWatchers() {
144
+ n(this.lastNotifiedItems, this.items) && n(this.lastNotifiedErrors, this.initializationErrors) || (this.lastNotifiedItems = new Map(this.items), this.lastNotifiedErrors = new Map(this.initializationErrors), this.watchers.forEach((e) => e(new Map(this.items), new Map(this.initializationErrors))));
102
145
  }
103
146
  getPendingCallbacks(e) {
104
147
  let t = this.pendingCallbacks.get(e);
@@ -107,13 +150,10 @@ var n = class {
107
150
  error: []
108
151
  }, this.pendingCallbacks.set(e, t)), t;
109
152
  }
110
- registerAsDefault(e, t) {
111
- this.items.size === 1 && e !== null && this.register(null, t);
112
- }
113
153
  };
114
154
  //#endregion
115
155
  //#region src/shared/debounce.ts
116
- function r(e, t) {
156
+ function i(e, t) {
117
157
  let n = null;
118
158
  return (...r) => {
119
159
  n && clearTimeout(n), n = setTimeout(() => {
@@ -123,24 +163,24 @@ function r(e, t) {
123
163
  }
124
164
  //#endregion
125
165
  //#region src/shared/filter-object-values.ts
126
- function i(e, t) {
166
+ function a(e, t) {
127
167
  let n = Object.entries(e).filter(([e, n]) => t(n, e));
128
168
  return Object.fromEntries(n);
129
169
  }
130
170
  //#endregion
131
171
  //#region src/shared/is-empty-object.ts
132
- function a(e) {
172
+ function o(e) {
133
173
  return Object.keys(e).length === 0 && e.constructor === Object;
134
174
  }
135
175
  //#endregion
136
176
  //#region src/shared/map-object-values.ts
137
- function o(e, t) {
177
+ function s(e, t) {
138
178
  let n = Object.entries(e).map(([e, n]) => [e, t(n, e)]);
139
179
  return Object.fromEntries(n);
140
180
  }
141
181
  //#endregion
142
182
  //#region src/shared/shallow-equal.ts
143
- function s(e, t) {
183
+ function c(e, t) {
144
184
  if (e === t) return !0;
145
185
  let n = Object.keys(e), r = Object.keys(t);
146
186
  if (n.length !== r.length) return !1;
@@ -149,12 +189,12 @@ function s(e, t) {
149
189
  }
150
190
  //#endregion
151
191
  //#region src/shared/uid.ts
152
- function c() {
192
+ function l() {
153
193
  return Math.random().toString(36).substring(2);
154
194
  }
155
195
  //#endregion
156
196
  //#region src/shared/wait-for.ts
157
- function l(e, { timeOutAfter: t = 500, retryAfter: n = 100 } = {}) {
197
+ function u(e, { timeOutAfter: t = 500, retryAfter: n = 100 } = {}) {
158
198
  return new Promise((r, i) => {
159
199
  let a = Date.now(), o = null, s = setTimeout(() => {
160
200
  i(o ?? /* @__PURE__ */ Error("Timeout"));
@@ -170,10 +210,27 @@ function l(e, { timeOutAfter: t = 500, retryAfter: n = 100 } = {}) {
170
210
  });
171
211
  }
172
212
  //#endregion
213
+ //#region src/hooks/editor/utils/cleanup-orphan-editor-elements.ts
214
+ function d(e) {
215
+ let t = [
216
+ e.ui?.element,
217
+ e.ui?.view?.toolbar?.element,
218
+ e.ui?.view?.menuBarView?.element
219
+ ].filter(Boolean);
220
+ for (let e of t) i(e);
221
+ let n = e.ui?.view?.body?._bodyCollectionContainer;
222
+ n?.isConnected && i(n);
223
+ let r = e.editing?.view;
224
+ if (r) for (let e of r.domRoots.values()) e instanceof HTMLElement && (e.removeAttribute("contenteditable"), e.removeAttribute("role"), e.removeAttribute("aria-label"), e.removeAttribute("aria-multiline"), e.removeAttribute("spellcheck"), e.classList.remove("ck", "ck-content", "ck-editor__editable", "ck-rounded-corners", "ck-editor__editable_inline", "ck-blurred", "ck-focused"), i(e));
225
+ function i(e) {
226
+ e.hasAttribute("data-cke-controlled") ? e.innerHTML = "" : e.remove();
227
+ }
228
+ }
229
+ //#endregion
173
230
  //#region src/hooks/editor/utils/create-editor-in-context.ts
174
- var u = Symbol.for("context-editor-watchdog");
175
- async function d({ element: e, context: t, creator: n, config: r }) {
176
- let i = c();
231
+ var f = Symbol.for("context-editor-watchdog");
232
+ async function p({ element: e, context: t, creator: n, config: r }) {
233
+ let i = l();
177
234
  await t.add({
178
235
  creator: (e, t) => n.create(e, t),
179
236
  id: i,
@@ -186,24 +243,29 @@ async function d({ element: e, context: t, creator: n, config: r }) {
186
243
  editorContextId: i,
187
244
  context: t
188
245
  };
189
- a[u] = o;
246
+ a[f] = o;
190
247
  let s = t.destroy.bind(t);
191
248
  return t.destroy = async () => (o.state = "unavailable", s()), {
192
249
  ...o,
193
250
  editor: a
194
251
  };
195
252
  }
196
- function f(e) {
197
- return u in e ? e[u] : null;
253
+ function m(e) {
254
+ return f in e ? e[f] : null;
198
255
  }
199
256
  //#endregion
200
257
  //#region src/hooks/editor/utils/get-editor-roots-values.ts
201
- function p(e) {
258
+ function h(e) {
202
259
  return e.model.document.getRootNames().reduce((t, n) => (t[n] = e.getData({ rootName: n }), t), Object.create({}));
203
260
  }
204
261
  //#endregion
262
+ //#region src/hooks/editor/utils/is-multiroot-editor-instance.ts
263
+ function g(e) {
264
+ return "addEditable" in e.ui;
265
+ }
266
+ //#endregion
205
267
  //#region src/hooks/editor/utils/is-single-root-editor.ts
206
- function m(e) {
268
+ function _(e) {
207
269
  return [
208
270
  "inline",
209
271
  "classic",
@@ -213,7 +275,7 @@ function m(e) {
213
275
  }
214
276
  //#endregion
215
277
  //#region src/hooks/editor/utils/load-editor-constructor.ts
216
- async function h(e) {
278
+ async function v(e) {
217
279
  let t = await import("ckeditor5"), n = {
218
280
  inline: t.InlineEditor,
219
281
  balloon: t.BalloonEditor,
@@ -226,7 +288,7 @@ async function h(e) {
226
288
  }
227
289
  //#endregion
228
290
  //#region src/hooks/editor/custom-editor-plugins.ts
229
- var g = class e {
291
+ var y = class e {
230
292
  static the = new e();
231
293
  plugins = /* @__PURE__ */ new Map();
232
294
  constructor() {}
@@ -250,9 +312,9 @@ var g = class e {
250
312
  };
251
313
  //#endregion
252
314
  //#region src/hooks/editor/utils/load-editor-plugins.ts
253
- async function _(e) {
315
+ async function b(e) {
254
316
  let t = await import("ckeditor5"), n = null, r = e.map(async (e) => {
255
- let r = await g.the.get(e);
317
+ let r = await y.the.get(e);
256
318
  if (r) return r;
257
319
  let { [e]: i } = t;
258
320
  if (i) return i;
@@ -274,19 +336,19 @@ async function _(e) {
274
336
  }
275
337
  //#endregion
276
338
  //#region src/hooks/editor/utils/load-editor-translations.ts
277
- async function v(e, t) {
278
- let n = [e.ui, e.content], r = [y("ckeditor5", n)];
279
- return t && r.push(y("ckeditor5-premium-features", n)), await Promise.all(r).then((e) => e.flat());
339
+ async function x(e, t) {
340
+ let n = [e.ui, e.content], r = [S("ckeditor5", n)];
341
+ return t && r.push(S("ckeditor5-premium-features", n)), await Promise.all(r).then((e) => e.flat());
280
342
  }
281
- async function y(e, t) {
343
+ async function S(e, t) {
282
344
  /* v8 ignore next */
283
345
  return await Promise.all(t.filter((e) => e !== "en").map(async (t) => {
284
- let n = await b(e, t);
346
+ let n = await C(e, t);
285
347
  /* v8 ignore next -- @preserve */
286
348
  return n?.default ?? n;
287
349
  }).filter(Boolean));
288
350
  }
289
- async function b(e, t) {
351
+ async function C(e, t) {
290
352
  try {
291
353
  /* v8 ignore next if -- @preserve */
292
354
  if (e === "ckeditor5") switch (t) {
@@ -446,15 +508,15 @@ catch (n) {
446
508
  }
447
509
  //#endregion
448
510
  //#region src/hooks/editor/utils/normalize-custom-translations.ts
449
- function x(e) {
450
- return o(e, (e) => ({ dictionary: e }));
511
+ function w(e) {
512
+ return s(e, (e) => ({ dictionary: e }));
451
513
  }
452
514
  //#endregion
453
515
  //#region src/hooks/editor/utils/query-editor-editables.ts
454
- function S(e) {
455
- return o(C(e), ({ element: e }) => e);
516
+ function T(e) {
517
+ return s(E(e), ({ element: e }) => e);
456
518
  }
457
- function C(e) {
519
+ function E(e) {
458
520
  let t = window.Livewire.all().filter(({ name: t, canonical: n }) => t === "ckeditor5-editable" && n.editorId === e).reduce((e, { canonical: t, el: n }) => ({
459
521
  ...e,
460
522
  [t.rootName]: {
@@ -476,38 +538,38 @@ function C(e) {
476
538
  }
477
539
  } : t;
478
540
  }
479
- function w(e) {
480
- return i(o(C(e), ({ content: e }) => e), (e) => typeof e == "string");
541
+ function D(e) {
542
+ return a(s(E(e), ({ content: e }) => e), (e) => typeof e == "string");
481
543
  }
482
544
  //#endregion
483
545
  //#region src/hooks/editor/utils/resolve-editor-config-elements-references.ts
484
- function T(e) {
546
+ function O(e) {
485
547
  if (!e || typeof e != "object") return e;
486
- if (Array.isArray(e)) return e.map((e) => T(e));
548
+ if (Array.isArray(e)) return e.map((e) => O(e));
487
549
  let t = e;
488
550
  if (t.$element && typeof t.$element == "string") {
489
551
  let e = document.querySelector(t.$element);
490
552
  return e || console.warn(`Element not found for selector: ${t.$element}`), e || null;
491
553
  }
492
554
  let n = Object.create(null);
493
- for (let [t, r] of Object.entries(e)) n[t] = T(r);
555
+ for (let [t, r] of Object.entries(e)) n[t] = O(r);
494
556
  return n;
495
557
  }
496
558
  //#endregion
497
559
  //#region src/hooks/editor/utils/resolve-editor-config-translations.ts
498
- function E(e, t, n) {
560
+ function k(e, t, n) {
499
561
  if (!n || typeof n != "object") return n;
500
- if (Array.isArray(n)) return n.map((n) => E(e, t, n));
562
+ if (Array.isArray(n)) return n.map((n) => k(e, t, n));
501
563
  let r = n;
502
564
  if (r.$translation && typeof r.$translation == "string") {
503
- let n = r.$translation, i = D(e, n, t);
565
+ let n = r.$translation, i = A(e, n, t);
504
566
  return i === void 0 && console.warn(`Translation not found for key: ${n}`), i === void 0 ? null : i;
505
567
  }
506
568
  let i = Object.create(null);
507
- for (let [r, a] of Object.entries(n)) i[r] = E(e, t, a);
569
+ for (let [r, a] of Object.entries(n)) i[r] = k(e, t, a);
508
570
  return i;
509
571
  }
510
- function D(e, t, n) {
572
+ function A(e, t, n) {
511
573
  for (let r of e) {
512
574
  let e = r[n];
513
575
  if (e?.dictionary && t in e.dictionary) return e.dictionary[t];
@@ -515,7 +577,7 @@ function D(e, t, n) {
515
577
  }
516
578
  //#endregion
517
579
  //#region src/hooks/editor/utils/set-editor-editable-height.ts
518
- function O(e, t) {
580
+ function j(e, t) {
519
581
  let { editing: n } = e;
520
582
  n.view.change((e) => {
521
583
  e.setStyle("height", `${t}px`, n.view.document.getRoot());
@@ -523,34 +585,34 @@ function O(e, t) {
523
585
  }
524
586
  //#endregion
525
587
  //#region src/hooks/editor/utils/wrap-with-watchdog.ts
526
- var k = Symbol.for("elixir-editor-watchdog");
527
- async function A(e) {
528
- let { EditorWatchdog: t } = await import("ckeditor5"), n = new t(e);
529
- return n.setCreator(async (...t) => {
530
- let r = await e.create(...t);
531
- return r[k] = n, r;
532
- }), {
533
- watchdog: n,
534
- Constructor: { create: async (...e) => (await n.create(...e), n.editor) }
535
- };
588
+ var M = Symbol.for("livewire-editor-watchdog");
589
+ async function N(e, t) {
590
+ let { EditorWatchdog: n } = await import("ckeditor5"), r = new n(null, t ?? {
591
+ crashNumberLimit: 10,
592
+ minimumNonErrorTimePeriod: 5e3
593
+ });
594
+ return r.setCreator(async () => {
595
+ let t = await e();
596
+ return t[M] = r, t;
597
+ }), r;
536
598
  }
537
- function j(e) {
538
- return k in e ? e[k] : null;
599
+ function P(e) {
600
+ return M in e ? e[M] : null;
539
601
  }
540
602
  //#endregion
541
603
  //#region src/hooks/context/contexts-registry.ts
542
- var M = class e extends n {
604
+ var F = class e extends r {
543
605
  static the = new e();
544
- }, N = class extends e {
606
+ }, I = class extends e {
545
607
  contextPromise = null;
546
608
  async mounted() {
547
- let { contextId: e, language: t, context: n } = this.canonical, { customTranslations: r, watchdogConfig: i, config: { plugins: o, ...s } } = n, { loadedPlugins: c, hasPremium: l } = await _(o ?? []), u = [...await v(t, l), x(r || {})].filter((e) => !a(e));
609
+ let { contextId: e, language: t, context: n } = this.canonical, { customTranslations: r, watchdogConfig: i, config: { plugins: a, ...s } } = n, { loadedPlugins: c, hasPremium: l } = await b(a ?? []), u = [...await x(t, l), w(r || {})].filter((e) => !o(e));
548
610
  this.contextPromise = (async () => {
549
611
  let { ContextWatchdog: e, Context: n } = await import("ckeditor5"), r = new e(n, {
550
612
  crashNumberLimit: 10,
551
613
  ...i
552
- }), a = T(s);
553
- return a = E([...u].reverse(), t.ui, a), await r.create({
614
+ }), a = O(s);
615
+ return a = k([...u].reverse(), t.ui, a), await r.create({
554
616
  ...a,
555
617
  language: t,
556
618
  plugins: c,
@@ -561,7 +623,7 @@ var M = class e extends n {
561
623
  })();
562
624
  let d = await this.contextPromise;
563
625
  /* v8 ignore next if -- @preserve */
564
- this.isBeingDestroyed() || M.the.register(e, d);
626
+ this.isBeingDestroyed() || F.the.register(e, d);
565
627
  }
566
628
  async destroyed() {
567
629
  let { contextId: e } = this.canonical;
@@ -569,15 +631,15 @@ var M = class e extends n {
569
631
  try {
570
632
  await (await this.contextPromise)?.destroy();
571
633
  } finally {
572
- this.contextPromise = null, M.the.hasItem(e) && M.the.unregister(e);
634
+ this.contextPromise = null, F.the.hasItem(e) && F.the.unregister(e);
573
635
  }
574
636
  }
575
- }, P = class e extends n {
637
+ }, L = class e extends r {
576
638
  static the = new e();
577
639
  };
578
640
  //#endregion
579
641
  //#region src/hooks/utils/is-wire-model-connected.ts
580
- function F(e) {
642
+ function R(e) {
581
643
  let t = e;
582
644
  for (; t;) {
583
645
  for (let e of t.attributes) if (e.name.startsWith("wire:model")) return !0;
@@ -587,7 +649,7 @@ function F(e) {
587
649
  }
588
650
  //#endregion
589
651
  //#region src/hooks/utils/root-attributes-updater.ts
590
- function I(e, t) {
652
+ function z(e, t) {
591
653
  let n = /* @__PURE__ */ new Set();
592
654
  return (r) => {
593
655
  e.model.enqueueChange({ isUndoable: !1 }, (i) => {
@@ -601,22 +663,21 @@ function I(e, t) {
601
663
  }
602
664
  //#endregion
603
665
  //#region src/hooks/editable.ts
604
- var L = class extends e {
605
- editorPromise = null;
666
+ var B = class extends e {
606
667
  rootAttributesUpdater = null;
607
668
  pendingContent = null;
608
669
  mounted() {
609
- let { editorId: e, rootName: t, content: n } = this.canonical;
610
- this.editorPromise = P.the.execute(e, (e) => {
670
+ let { editorId: e, rootName: t, content: n } = this.canonical, r = L.the.mountEffect(e, (e) => {
611
671
  /* v8 ignore next if -- @preserve */
612
- if (this.isBeingDestroyed()) return null;
613
- let { ui: r, editing: i, model: a } = e;
614
- if (a.document.getRoot(t)) {
615
- if (n !== null) {
616
- let r = e.getData({ rootName: t });
617
- r && r !== n && e.setData({ [t]: n });
618
- }
619
- } else {
672
+ if (this.isBeingDestroyed()) return;
673
+ let r = e.model.document.getRoot(t);
674
+ if (r?.isAttached() && n !== null) {
675
+ let r = e.getData({ rootName: t });
676
+ r && r !== n && e.setData({ [t]: n });
677
+ }
678
+ /* v8 ignore next else -- @preserve */
679
+ if (!r && g(e)) {
680
+ let { ui: r, editing: i } = e;
620
681
  e.addRoot(t, {
621
682
  isUndoable: !1,
622
683
  ...n !== null && { data: n }
@@ -624,34 +685,45 @@ var L = class extends e {
624
685
  let a = this.element.querySelector("[data-cke-editable-content]"), o = r.view.createEditable(t, a);
625
686
  r.addEditable(o), i.view.forceRender();
626
687
  }
627
- return this.syncTypingContentPush(e), this.setupPendingReceivedContentHandlers(e), this.applyRootAttributes(e), e;
688
+ let i = this.syncTypingContentPush(e), a = this.setupPendingReceivedContentHandlers(e);
689
+ return this.applyRootAttributes(e), () => {
690
+ /* v8 ignore next else -- @preserve */
691
+ if (i(), a(), this.rootAttributesUpdater?.(null), e.state !== "destroyed") {
692
+ let n = e.model.document.getRoot(t);
693
+ /* v8 ignore next if -- @preserve */
694
+ if (n && g(e)) {
695
+ try {
696
+ /* v8 ignore else -- @preserve */
697
+ e.ui.view.editables[t] && e.detachEditable(n);
698
+ } catch (e) {
699
+ /* v8 ignore next -- @preserve */
700
+ console.error("Unable unmount editable from root:", e);
701
+ }
702
+ n.isAttached() && e.detachRoot(t, !1);
703
+ }
704
+ }
705
+ };
628
706
  });
707
+ this.onBeforeDestroy(r);
629
708
  }
630
709
  async afterCommitSynced() {
631
- let e = await this.editorPromise;
632
- this.applyCanonicalContentToEditor(e), this.applyRootAttributes(e);
710
+ let { editorId: e } = this.canonical, t = await L.the.waitFor(e);
711
+ this.applyCanonicalContentToEditor(t), this.applyRootAttributes(t);
633
712
  }
634
- async destroyed() {
635
- let { rootName: e } = this.canonical;
713
+ destroyed() {
636
714
  this.element.style.display = "none";
637
- let t = await this.editorPromise;
638
- if (this.editorPromise = null, this.rootAttributesUpdater?.(null), t && t.state !== "destroyed") {
639
- let n = t.model.document.getRoot(e);
640
- /* v8 ignore next if -- @preserve */
641
- n && "detachEditable" in t && (t.detachEditable(n), t.detachRoot(e, !1));
642
- }
643
715
  }
644
716
  syncTypingContentPush(e) {
645
- let { rootName: t, saveDebounceMs: n } = this.canonical, i = this.element.querySelector("input"), a = !1, o = () => {
646
- if (a) return;
717
+ let { rootName: t, saveDebounceMs: n } = this.canonical, r = this.element.querySelector("input"), a = !1, o = () => {
718
+ if (a || !e.model.document.getRoot(t)?.isAttached()) return;
647
719
  let n = e.getData({ rootName: t });
648
- i && (i.value = n), this.$wire.set("content", n);
649
- }, s = r(n, o), c = () => {
720
+ r && (r.value = n), this.$wire.set("content", n);
721
+ }, s = i(n, o), c = () => {
650
722
  e.ui.focusTracker.isFocused ? s() : o();
651
723
  };
652
- e.model.document.on("change:data", c), o(), this.onBeforeDestroy(() => {
724
+ return e.model.document.on("change:data", c), o(), () => {
653
725
  a = !0, e.model.document.off("change:data", c);
654
- });
726
+ };
655
727
  }
656
728
  setupPendingReceivedContentHandlers(e) {
657
729
  let { ui: t, model: n } = e, { focusTracker: r } = t, { rootName: i } = this.canonical, a = () => {
@@ -659,12 +731,12 @@ var L = class extends e {
659
731
  }, o = () => {
660
732
  !r.isFocused && this.pendingContent !== null && (e.setData({ [i]: this.pendingContent }), this.pendingContent = null);
661
733
  };
662
- n.document.on("change:data", a), r.on("change:isFocused", o), this.onBeforeDestroy(() => {
734
+ return n.document.on("change:data", a), r.on("change:isFocused", o), () => {
663
735
  n.document.off("change:data", a), r.off("change:isFocused", o);
664
- });
736
+ };
665
737
  }
666
738
  applyCanonicalContentToEditor(e) {
667
- if (!F(this.element)) return;
739
+ if (!R(this.element)) return;
668
740
  let { content: t, rootName: n } = this.canonical, { ui: r } = e;
669
741
  if (e.getData({ rootName: n }) !== (t ?? "")) {
670
742
  if (r.focusTracker.isFocused) {
@@ -676,12 +748,12 @@ var L = class extends e {
676
748
  }
677
749
  applyRootAttributes(e) {
678
750
  let { rootName: t, rootAttributes: n } = this.canonical;
679
- this.rootAttributesUpdater ??= I(e, t), this.rootAttributesUpdater(n);
751
+ this.rootAttributesUpdater ??= z(e, t), this.rootAttributesUpdater(n);
680
752
  }
681
753
  };
682
754
  //#endregion
683
755
  //#region src/hooks/editor/plugins/livewire-sync.ts
684
- async function R({ saveDebounceMs: e, component: t }) {
756
+ async function V({ saveDebounceMs: e, component: t }) {
685
757
  let { Plugin: n } = await import("ckeditor5");
686
758
  return class extends n {
687
759
  static get pluginName() {
@@ -693,15 +765,15 @@ async function R({ saveDebounceMs: e, component: t }) {
693
765
  setupAfterCommitHandler() {
694
766
  let { editor: e } = this, { model: n, ui: { focusTracker: r } } = e, i = null;
695
767
  e.on("afterCommitSynced", () => {
696
- if (!F(t.element)) return;
768
+ if (!R(t.element)) return;
697
769
  let { content: n } = t.canonical, a = this.getEditorRootsValues();
698
770
  if (r.isFocused) {
699
771
  /* v8 ignore next else -- @preserve */
700
- s(n, a) || (i = n);
772
+ c(n, a) || (i = n);
701
773
  return;
702
774
  }
703
775
  /* v8 ignore next else -- @preserve */
704
- s(n, a) || e.setData(n);
776
+ c(n, a) || e.setData(n);
705
777
  }), n.document.on("change:data", () => {
706
778
  i = null;
707
779
  }), r.on("change:isFocused", () => {
@@ -715,41 +787,43 @@ async function R({ saveDebounceMs: e, component: t }) {
715
787
  });
716
788
  }
717
789
  setupSetEditorContentHandler() {
718
- Livewire.on("set-editor-content", ({ editorId: e, content: n }) => {
719
- e === t.canonical.editorId && (s(this.getEditorRootsValues(), n) || this.editor.setData(n));
790
+ let { editor: e } = this, n = Livewire.on("set-editor-content", ({ editorId: n, content: r }) => {
791
+ n === t.canonical.editorId && (c(this.getEditorRootsValues(), r) || e.setData(r));
720
792
  });
793
+ /* v8 ignore next if -- @preserve */
794
+ typeof n == "function" && e.once("destroy", n);
721
795
  }
722
796
  setupTypingContentPush() {
723
- let { editor: n } = this, { model: i, ui: a } = n, { $wire: o } = t, c = !1, l = () => {
797
+ let { editor: n } = this, { model: r, ui: a } = n, { $wire: o } = t, s = !1, l = () => {
724
798
  /* v8 ignore next if -- @preserve */
725
- if (c) return;
799
+ if (s) return;
726
800
  let e = this.getEditorRootsValues();
727
- s(e, t.canonical.content ?? {}) || (o.set("content", e), o.dispatch("editor-content-changed", {
801
+ c(e, t.canonical.content ?? {}) || (o.set("content", e), o.dispatch("editor-content-changed", {
728
802
  editorId: t.canonical.editorId,
729
803
  content: e
730
804
  }));
731
- }, u = r(e, l), d = () => {
805
+ }, u = i(e, l);
806
+ r.document.on("change:data", i(10, () => {
732
807
  a.focusTracker.isFocused ? u() : l();
733
- };
734
- i.document.on("change:data", d), n.once("ready", l), n.once("destroy", () => {
735
- c = !0, i.document.off("change:data", d);
808
+ })), n.once("ready", l), n.once("destroy", () => {
809
+ s = !0;
736
810
  });
737
811
  }
738
812
  setupFocusableEventPush() {
739
813
  let { ui: e } = this.editor, { $wire: n } = t;
740
814
  e.focusTracker.on("change:isFocused", () => {
741
815
  let r = this.getEditorRootsValues();
742
- n.set("focused", e.focusTracker.isFocused), s(r, t.canonical.content ?? {}) || n.set("content", r);
816
+ n.set("focused", e.focusTracker.isFocused), c(r, t.canonical.content ?? {}) || n.set("content", r);
743
817
  });
744
818
  }
745
819
  getEditorRootsValues() {
746
- return p(this.editor);
820
+ return h(this.editor);
747
821
  }
748
822
  };
749
823
  }
750
824
  //#endregion
751
825
  //#region src/hooks/editor/plugins/sync-editor-with-input.ts
752
- async function z(e) {
826
+ async function H(e) {
753
827
  let { Plugin: t } = await import("ckeditor5");
754
828
  return class extends t {
755
829
  input = null;
@@ -759,7 +833,7 @@ async function z(e) {
759
833
  }
760
834
  afterInit() {
761
835
  let { editor: t } = this, n = t.sourceElement.id.replace(/_editor$/, "");
762
- this.input = document.getElementById(`${n}_input`), this.input && (t.model.document.on("change:data", r(e, () => this.sync())), t.once("ready", this.sync), this.form = this.input.closest("form"), this.form?.addEventListener("submit", this.sync));
836
+ this.input = document.getElementById(`${n}_input`), this.input && (t.model.document.on("change:data", i(e, () => this.sync())), t.once("ready", this.sync), this.form = this.input.closest("form"), this.form?.addEventListener("submit", this.sync));
763
837
  }
764
838
  sync = () => {
765
839
  /* v8 ignore next else -- @preserve */
@@ -775,100 +849,102 @@ async function z(e) {
775
849
  }
776
850
  //#endregion
777
851
  //#region src/hooks/editor/editor.ts
778
- var B = class extends e {
779
- editorPromise = null;
852
+ var U = class extends e {
780
853
  rootAttributesUpdater = null;
781
854
  async mounted() {
782
855
  let { editorId: e } = this.canonical;
783
- P.the.resetErrors(e);
856
+ L.the.resetErrors(e);
784
857
  try {
785
- this.editorPromise = this.createEditor();
786
- let t = await this.editorPromise;
787
- /* v8 ignore next if -- @preserve */
788
- this.isBeingDestroyed() || (P.the.register(e, t), t.once("destroy", () => {
789
- /* v8 ignore next if -- @preserve */
790
- P.the.hasItem(e) && P.the.unregister(e);
791
- }));
858
+ let t = await this.createEditor(), n = m(t), r = P(t);
859
+ /* v8 ignore next 3 */
860
+ if (this.isBeingDestroyed()) return;
861
+ let i = L.the.mountEffect(e, (t) => {
862
+ t.once("destroy", () => {
863
+ L.the.unregister(e, !1);
864
+ }, { priority: "highest" });
865
+ });
866
+ this.onBeforeDestroy(async () => {
867
+ L.the.unregister(e), i(), n ? n.state !== "unavailable" && await n.context.remove(n.editorContextId) : r ? await r.destroy() : await t.destroy();
868
+ }), L.the.register(e, t);
792
869
  } catch (t) {
793
- console.error(`Error initializing CKEditor5 instance with ID "${e}":`, t), this.editorPromise = null, P.the.error(e, t);
870
+ console.error(`Error initializing CKEditor5 instance with ID "${e}":`, t), L.the.error(e, t);
794
871
  }
795
872
  }
796
873
  async destroyed() {
797
874
  this.element.style.display = "none";
798
- try {
799
- let e = await this.editorPromise;
800
- if (!e) return;
801
- let t = f(e), n = j(e);
802
- t ? t.state !== "unavailable" && await t.context.remove(t.editorContextId) : n ? await n.destroy() : await e.destroy();
803
- } finally {
804
- this.editorPromise = null;
805
- }
806
875
  }
807
876
  async afterCommitSynced() {
808
- let e = await this.editorPromise;
877
+ let e = await L.the.waitFor(this.canonical.editorId);
809
878
  /* v8 ignore if -- @preserve */
810
879
  e && (e.fire("afterCommitSynced"), this.applyRootAttributes(e));
811
880
  }
812
881
  applyRootAttributes(e) {
813
882
  let { rootAttributes: t } = this.canonical;
814
- this.rootAttributesUpdater ??= I(e, "main"), this.rootAttributesUpdater(t);
883
+ this.rootAttributesUpdater ??= z(e, "main"), this.rootAttributesUpdater(t);
815
884
  }
816
885
  async createEditor() {
817
- let { preset: e, editorId: t, contextId: n, editableHeight: r, saveDebounceMs: i, language: o, watchdog: s, content: c } = this.canonical, { customTranslations: l, editorType: u, licenseKey: f, config: { plugins: p, ...g } } = e, y = await h(u), b = await (n ? M.the.waitFor(n) : null);
818
- if (s && !b) {
819
- let e = await A(y);
820
- ({Constructor: y} = e), e.watchdog.on("restart", () => {
821
- let n = e.watchdog.editor;
822
- this.editorPromise = Promise.resolve(n), P.the.register(t, n);
823
- });
824
- }
825
- let { loadedPlugins: C, hasPremium: D } = await _(p);
826
- C.push(await R({
827
- saveDebounceMs: i,
828
- component: this
829
- })), m(u) && C.push(await z(i));
830
- let k = [...await v(o, D), x(l || {})].filter((e) => !a(e)), j = {
831
- ...c,
832
- ...w(t)
833
- };
834
- m(u) && (j = j.main || "");
835
- let N = await (async () => {
836
- let e = S(t);
837
- if (!(e instanceof HTMLElement) && !("main" in e)) {
838
- let n = u === "decoupled" ? ["main"] : Object.keys(j);
839
- V(e, n) || (e = await H(t, n), j = {
840
- ...c,
841
- ...w(t)
842
- });
843
- }
844
- m(u) && "main" in e && (e = e.main);
845
- let n = T(g);
846
- n = E([...k].reverse(), o.ui, n);
847
- let r = {
848
- ...n,
849
- initialData: j,
850
- licenseKey: f,
851
- plugins: C,
852
- language: o,
853
- ...k.length && { translations: k }
886
+ let { preset: e, editorId: t, contextId: n, editableHeight: r, saveDebounceMs: i, language: a, watchdog: s, content: c } = this.canonical, { customTranslations: l, editorType: u, licenseKey: f, watchdogConfig: m, config: { plugins: h, ...g } } = e, y = await v(u), S = await (n ? F.the.waitFor(n) : null), C = async () => {
887
+ let { loadedPlugins: e, hasPremium: n } = await b(h);
888
+ e.push(await V({
889
+ saveDebounceMs: i,
890
+ component: this
891
+ })), _(u) && e.push(await H(i));
892
+ let s = [...await x(a, n), w(l || {})].filter((e) => !o(e)), d = {
893
+ ...c,
894
+ ...D(t)
854
895
  };
855
- return !b || !(e instanceof HTMLElement) ? y.create(e, r) : (await d({
856
- context: b,
857
- element: e,
858
- creator: y,
859
- config: r
860
- })).editor;
861
- })();
862
- return m(u) && r && O(N, r), this.applyRootAttributes(N), N;
896
+ _(u) && (d = d.main || "");
897
+ let m = await (async () => {
898
+ let n = T(t);
899
+ if (!(n instanceof HTMLElement) && !("main" in n)) {
900
+ let e = u === "decoupled" ? ["main"] : Object.keys(d);
901
+ W(n, e) || (n = await G(t, e), d = {
902
+ ...c,
903
+ ...D(t)
904
+ });
905
+ }
906
+ _(u) && "main" in n && (n = n.main);
907
+ let r = O(g);
908
+ r = k([...s].reverse(), a.ui, r);
909
+ let i = {
910
+ ...r,
911
+ initialData: d,
912
+ licenseKey: f,
913
+ plugins: e,
914
+ language: a,
915
+ ...s.length && { translations: s }
916
+ };
917
+ return !S || !(n instanceof HTMLElement) ? y.create(n, i) : (await p({
918
+ context: S,
919
+ element: n,
920
+ creator: y,
921
+ config: i
922
+ })).editor;
923
+ })();
924
+ return _(u) && r && j(m, r), this.applyRootAttributes(m), m;
925
+ };
926
+ if (s && !S) {
927
+ let e = await N(C, m);
928
+ return e.on("error", (e, { causesRestart: n }) => {
929
+ if (n) {
930
+ let e = L.the.getItem(t);
931
+ /* v8 ignore next 3 */
932
+ e && (d(e), L.the.unregister(t));
933
+ }
934
+ }), e.on("restart", () => {
935
+ L.the.register(t, e.editor);
936
+ }), await e.create({}), e.editor;
937
+ }
938
+ return C();
863
939
  }
864
940
  };
865
- function V(e, t) {
941
+ function W(e, t) {
866
942
  return t.every((t) => e[t]);
867
943
  }
868
- async function H(e, t) {
869
- return l(() => {
870
- let n = S(e);
871
- if (!V(n, t)) throw Error(`It looks like not all required root elements are present yet.
944
+ async function G(e, t) {
945
+ return u(() => {
946
+ let n = T(e);
947
+ if (!W(n, t)) throw Error(`It looks like not all required root elements are present yet.
872
948
  * If you want to wait for them, ensure they are registered before editor initialization.
873
949
  * If you want lazy initialize roots, consider removing root values from the \`initialData\` config and assign initial data in editable components.
874
950
  Missing roots: ${t.filter((e) => !n[e]).join(", ")}.`);
@@ -880,26 +956,27 @@ Missing roots: ${t.filter((e) => !n[e]).join(", ")}.`);
880
956
  }
881
957
  //#endregion
882
958
  //#region src/hooks/ui-part.ts
883
- var U = class extends e {
884
- mountedPromise = null;
885
- async mounted() {
886
- let { editorId: e, name: t } = this.canonical;
887
- this.mountedPromise = P.the.execute(e, (e) => {
959
+ var K = class extends e {
960
+ mounted() {
961
+ let { editorId: e, name: t } = this.canonical, n = L.the.mountEffect(e, (e) => {
888
962
  /* v8 ignore next if -- @preserve */
889
963
  if (this.isBeingDestroyed()) return;
890
- let { ui: n } = e, r = W(t), i = n.view[r];
964
+ let { ui: n } = e, r = q(t), i = n.view[r];
891
965
  if (!i) {
892
966
  console.error(`Unknown UI part name: "${t}". Supported names are "toolbar" and "menubar".`);
893
967
  return;
894
968
  }
895
- this.element.appendChild(i.element);
969
+ return this.element.appendChild(i.element), () => {
970
+ this.element.innerHTML = "";
971
+ };
896
972
  });
973
+ this.onBeforeDestroy(n);
897
974
  }
898
- async destroyed() {
899
- this.element.style.display = "none", await this.mountedPromise, this.mountedPromise = null, this.element.innerHTML = "";
975
+ destroyed() {
976
+ this.element.style.display = "none";
900
977
  }
901
978
  };
902
- function W(e) {
979
+ function q(e) {
903
980
  switch (e) {
904
981
  case "toolbar": return "toolbar";
905
982
  case "menubar": return "menuBarView";
@@ -908,19 +985,19 @@ function W(e) {
908
985
  }
909
986
  //#endregion
910
987
  //#region src/hooks/index.ts
911
- var G = {
912
- ckeditor5: B,
913
- "ckeditor5-context": N,
914
- "ckeditor5-ui-part": U,
915
- "ckeditor5-editable": L
988
+ var J = {
989
+ ckeditor5: U,
990
+ "ckeditor5-context": I,
991
+ "ckeditor5-ui-part": K,
992
+ "ckeditor5-editable": B
916
993
  };
917
- function K() {
918
- for (let [e, n] of Object.entries(G)) t(e, n);
994
+ function Y() {
995
+ for (let [e, n] of Object.entries(J)) t(e, n);
919
996
  }
920
997
  //#endregion
921
998
  //#region src/index.ts
922
- K();
999
+ Y();
923
1000
  //#endregion
924
- export { e as ClassHook, M as ContextsRegistry, g as CustomEditorPluginsRegistry, L as EditableComponentHook, B as EditorComponentHook, P as EditorsRegistry, U as UIPartComponentHook, t as registerLivewireComponentHook };
1001
+ export { e as ClassHook, F as ContextsRegistry, y as CustomEditorPluginsRegistry, B as EditableComponentHook, U as EditorComponentHook, L as EditorsRegistry, K as UIPartComponentHook, t as registerLivewireComponentHook };
925
1002
 
926
1003
  //# sourceMappingURL=index.mjs.map