ckeditor5-livewire 1.7.0 → 1.8.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ckeditor5-livewire",
3
- "version": "1.7.0",
3
+ "version": "1.8.0",
4
4
  "description": "CKEditor 5 integration for Laravel Livewire",
5
5
  "author": "Mateusz Bagiński <cziken58@gmail.com>",
6
6
  "license": "MIT",
@@ -29,15 +29,14 @@
29
29
  "src"
30
30
  ],
31
31
  "devDependencies": {
32
- "@vitest/coverage-v8": "^3.2.4",
32
+ "@vitest/coverage-v8": "^4.1.0",
33
33
  "ckeditor5": "^47.6.0",
34
34
  "ckeditor5-premium-features": "^47.6.0",
35
35
  "happy-dom": "^20.0.1",
36
36
  "typescript": "^5.5.4",
37
- "vite": "^7.1.11",
37
+ "vite": "^8.0.0",
38
38
  "vite-plugin-dts": "^4.5.4",
39
- "vite-tsconfig-paths": "^5.1.4",
40
- "vitest": "^3.2.3"
39
+ "vitest": "^4.1.0"
41
40
  },
42
41
  "scripts": {
43
42
  "clean": "rm -rf dist",
@@ -73,6 +73,7 @@ export class ContextComponentHook extends ClassHook<Snapshot> {
73
73
 
74
74
  const context = await this.contextPromise;
75
75
 
76
+ /* v8 ignore next if -- @preserve */
76
77
  if (!this.isBeingDestroyed()) {
77
78
  ContextsRegistry.the.register(contextId, context);
78
79
  }
@@ -27,7 +27,7 @@ export class EditableComponentHook extends ClassHook<Snapshot> {
27
27
 
28
28
  // If the editor is not registered yet, we will wait for it to be registered.
29
29
  this.editorPromise = EditorsRegistry.the.execute(editorId, (editor: MultiRootEditor) => {
30
- /* v8 ignore next 3 */
30
+ /* v8 ignore next if -- @preserve */
31
31
  if (this.isBeingDestroyed()) {
32
32
  return null;
33
33
  }
@@ -180,6 +180,7 @@ export class EditableComponentHook extends ClassHook<Snapshot> {
180
180
  if (editor && editor.state !== 'destroyed') {
181
181
  const root = editor.model.document.getRoot(rootName);
182
182
 
183
+ /* v8 ignore next if -- @preserve */
183
184
  if (root && 'detachEditable' in editor) {
184
185
  editor.detachEditable(root);
185
186
  editor.detachRoot(rootName, false);
@@ -432,7 +432,7 @@ describe('editor component', () => {
432
432
 
433
433
  const editor = await waitForTestEditor();
434
434
 
435
- $wire.set.mockClear();
435
+ vi.mocked($wire.set).mockClear();
436
436
  editor.setData('<p>Debounce test</p>');
437
437
 
438
438
  await vi.advanceTimersByTimeAsync(399);
@@ -621,13 +621,13 @@ describe('editor component', () => {
621
621
  const { ui: { focusTracker } } = await waitForTestEditor();
622
622
 
623
623
  // Focus the editor.
624
- $wire.set.mockClear();
624
+ vi.mocked($wire.set).mockClear();
625
625
  focusTracker.isFocused = true;
626
626
 
627
627
  expect($wire.set).toHaveBeenCalledWith('focused', true);
628
628
 
629
629
  // Blur the editor.
630
- $wire.set.mockClear();
630
+ vi.mocked($wire.set).mockClear();
631
631
  focusTracker.isFocused = false;
632
632
 
633
633
  expect($wire.set).toHaveBeenCalledWith('focused', false);
@@ -647,7 +647,7 @@ describe('editor component', () => {
647
647
 
648
648
  const editor = await waitForTestEditor();
649
649
 
650
- $wire.set.mockClear();
650
+ vi.mocked($wire.set).mockClear();
651
651
  editor.setData('<p>New content</p>');
652
652
 
653
653
  await vi.advanceTimersByTimeAsync(1);
@@ -671,7 +671,7 @@ describe('editor component', () => {
671
671
  const editor = await waitForTestEditor();
672
672
  const { ui: { focusTracker } } = editor;
673
673
 
674
- $wire.set.mockClear();
674
+ vi.mocked($wire.set).mockClear();
675
675
  editor.setData('<p>Updated content</p>');
676
676
  focusTracker.isFocused = true;
677
677
 
@@ -698,7 +698,7 @@ describe('editor component', () => {
698
698
 
699
699
  const editor = await waitForTestEditor();
700
700
 
701
- $wire.set.mockClear();
701
+ vi.mocked($wire.set).mockClear();
702
702
  editor.setData('<p>New content</p>');
703
703
 
704
704
  await vi.advanceTimersByTimeAsync(1);
@@ -720,7 +720,7 @@ describe('editor component', () => {
720
720
  const { ui: { focusTracker } } = await waitForTestEditor();
721
721
 
722
722
  // Focus the editor.
723
- $wire.set.mockClear();
723
+ vi.mocked($wire.set).mockClear();
724
724
  focusTracker.isFocused = true;
725
725
 
726
726
  expect($wire.set).toHaveBeenCalledWith('focused', true);
@@ -736,7 +736,7 @@ describe('editor component', () => {
736
736
  });
737
737
 
738
738
  // clear initial calls that may come from mounting logic
739
- $wire.dispatch.mockClear();
739
+ vi.mocked($wire.dispatch).mockClear();
740
740
 
741
741
  await waitForTestEditor();
742
742
 
@@ -759,7 +759,7 @@ describe('editor component', () => {
759
759
 
760
760
  const editor = await waitForTestEditor();
761
761
 
762
- $wire.dispatch.mockClear();
762
+ vi.mocked($wire.dispatch).mockClear();
763
763
  editor.setData('<p>Content change event test</p>');
764
764
 
765
765
  await vi.advanceTimersByTimeAsync(1);
@@ -52,10 +52,12 @@ export class EditorComponentHook extends ClassHook<Snapshot> {
52
52
 
53
53
  // Do not even try to broadcast about the registration of the editor
54
54
  // if hook was immediately destroyed.
55
+ /* v8 ignore next if -- @preserve */
55
56
  if (!this.isBeingDestroyed()) {
56
57
  EditorsRegistry.the.register(editorId, editor);
57
58
 
58
59
  editor.once('destroy', () => {
60
+ /* v8 ignore next if -- @preserve */
59
61
  if (EditorsRegistry.the.hasItem(editorId)) {
60
62
  EditorsRegistry.the.unregister(editorId);
61
63
  }
@@ -56,6 +56,7 @@ export async function createLivewireSyncPlugin(
56
56
 
57
57
  // If editor is focused, save the content to apply later when it blurs.
58
58
  if (focusTracker.isFocused) {
59
+ /* v8 ignore next else -- @preserve */
59
60
  if (!shallowEqual(content, values)) {
60
61
  pendingContent = content;
61
62
  }
@@ -63,6 +64,7 @@ export async function createLivewireSyncPlugin(
63
64
  return;
64
65
  }
65
66
 
67
+ /* v8 ignore next else -- @preserve */
66
68
  if (!shallowEqual(content, values)) {
67
69
  editor.setData(content);
68
70
  }
@@ -55,6 +55,7 @@ export async function createSyncEditorWithInputPlugin(saveDebounceMs: number): P
55
55
  * Synchronizes the editor's content with the input field.
56
56
  */
57
57
  private sync = (): void => {
58
+ /* v8 ignore next else -- @preserve */
58
59
  if (this.input) {
59
60
  const newValue = this.editor.getData();
60
61
 
@@ -35,17 +35,17 @@ export async function loadEditorPlugins(plugins: EditorPlugin[]): Promise<Loaded
35
35
  }
36
36
 
37
37
  // Plugin not found in base package, try premium package.
38
+ /* v8 ignore start -- @preserve */
38
39
  if (!premiumPackage) {
39
40
  try {
40
41
  premiumPackage = await import('ckeditor5-premium-features');
41
- /* v8 ignore next 6 */
42
42
  }
43
43
  catch (error) {
44
44
  console.error(`Failed to load premium package: ${error}`);
45
45
  }
46
46
  }
47
+ /* v8 ignore end */
47
48
 
48
- /* v8 ignore next */
49
49
  const { [plugin]: premiumPkgImport } = premiumPackage || {};
50
50
 
51
51
  if (premiumPkgImport) {
@@ -14,13 +14,18 @@ export async function loadAllEditorTranslations(
14
14
  hasPremium: boolean,
15
15
  ): Promise<Translations[]> {
16
16
  const translations = [language.ui, language.content];
17
- const loadedTranslations = await Promise.all(
18
- [
19
- loadEditorPkgTranslations('ckeditor5', translations),
20
- /* v8 ignore next */
21
- hasPremium && loadEditorPkgTranslations('ckeditor5-premium-features', translations),
22
- ].filter(pkg => !!pkg),
23
- )
17
+ const translationPromises = [
18
+ loadEditorPkgTranslations('ckeditor5', translations),
19
+ ];
20
+
21
+ /* v8 ignore next if -- @preserve */
22
+ if (hasPremium) {
23
+ translationPromises.push(
24
+ loadEditorPkgTranslations('ckeditor5-premium-features', translations),
25
+ );
26
+ }
27
+
28
+ const loadedTranslations = await Promise.all(translationPromises)
24
29
  .then(translations => translations.flat());
25
30
 
26
31
  return loadedTranslations;
@@ -46,7 +51,7 @@ async function loadEditorPkgTranslations(
46
51
  .map(async (lang) => {
47
52
  const pack = await loadEditorTranslation(pkg, lang);
48
53
 
49
- /* v8 ignore next */
54
+ /* v8 ignore next -- @preserve */
50
55
  return pack?.default ?? pack;
51
56
  })
52
57
  .filter(Boolean),
@@ -66,9 +71,8 @@ type EditorPkgName = 'ckeditor5' | 'ckeditor5-premium-features';
66
71
  */
67
72
  async function loadEditorTranslation(pkg: EditorPkgName, lang: string): Promise<any> {
68
73
  try {
69
- /* v8 ignore next 2 */
74
+ /* v8 ignore next if -- @preserve */
70
75
  if (pkg === 'ckeditor5') {
71
- /* v8 ignore next 79 */
72
76
  switch (lang) {
73
77
  case 'af': return await import('ckeditor5/translations/af.js');
74
78
  case 'ar': return await import('ckeditor5/translations/ar.js');
@@ -146,7 +150,6 @@ async function loadEditorTranslation(pkg: EditorPkgName, lang: string): Promise<
146
150
  return null;
147
151
  }
148
152
  }
149
- /* v8 ignore next 79 */
150
153
  else {
151
154
  // Premium features translations
152
155
  switch (lang) {
@@ -226,10 +229,11 @@ async function loadEditorTranslation(pkg: EditorPkgName, lang: string): Promise<
226
229
  return await import('ckeditor5-premium-features/translations/en.js'); // fallback to English
227
230
  }
228
231
  }
229
- /* v8 ignore next 7 */
230
232
  }
233
+ /* v8 ignore start -- @preserve */
231
234
  catch (error) {
232
235
  console.error(`Failed to load translation for ${pkg}/${lang}:`, error);
233
236
  return null;
234
237
  }
238
+ /* v8 ignore stop -- @preserve */
235
239
  }
package/src/hooks/hook.ts CHANGED
@@ -134,6 +134,7 @@ export function registerLivewireComponentHook(name: string, Hook: { new(componen
134
134
  succeed(() => {
135
135
  const instance = hookInstances.get(component.id);
136
136
 
137
+ /* v8 ignore next if -- @preserve */
137
138
  if (instance?.state === 'mounted') {
138
139
  instance?.afterCommitSynced?.();
139
140
  }
@@ -18,7 +18,7 @@ export class UIPartComponentHook extends ClassHook<Snapshot> {
18
18
 
19
19
  // If the editor is not registered yet, we will wait for it to be registered.
20
20
  this.mountedPromise = EditorsRegistry.the.execute(editorId, (editor) => {
21
- /* v8 ignore next 3 */
21
+ /* v8 ignore next if -- @preserve */
22
22
  if (this.isBeingDestroyed()) {
23
23
  return;
24
24
  }