ckeditor5-livewire 1.6.1 → 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/bundler/vite-ckeditor5-externalize.ts +15 -4
- package/dist/bundler/vite-ckeditor5-externalize.cjs +2 -2
- package/dist/bundler/vite-ckeditor5-externalize.cjs.map +1 -1
- package/dist/bundler/vite-ckeditor5-externalize.d.ts.map +1 -1
- package/dist/bundler/vite-ckeditor5-externalize.mjs +37 -37
- package/dist/bundler/vite-ckeditor5-externalize.mjs.map +1 -1
- package/dist/hooks/context/context.d.ts.map +1 -1
- package/dist/hooks/editable.d.ts.map +1 -1
- package/dist/hooks/editor/editor.d.ts.map +1 -1
- package/dist/hooks/editor/plugins/livewire-sync.d.ts.map +1 -1
- package/dist/hooks/editor/plugins/sync-editor-with-input.d.ts.map +1 -1
- package/dist/hooks/editor/utils/load-editor-translations.d.ts.map +1 -1
- package/dist/hooks/hook.d.ts.map +1 -1
- package/dist/index.cjs +3 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +883 -1328
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -7
- package/src/hooks/context/context.ts +1 -0
- package/src/hooks/editable.ts +2 -1
- package/src/hooks/editor/editor.test.ts +9 -9
- package/src/hooks/editor/editor.ts +2 -0
- package/src/hooks/editor/plugins/livewire-sync.ts +2 -0
- package/src/hooks/editor/plugins/sync-editor-with-input.ts +1 -0
- package/src/hooks/editor/utils/load-editor-plugins.ts +2 -2
- package/src/hooks/editor/utils/load-editor-translations.ts +16 -12
- package/src/hooks/hook.ts +1 -0
- package/src/hooks/ui-part.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ckeditor5-livewire",
|
|
3
|
-
"version": "1.
|
|
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": "^
|
|
33
|
-
"ckeditor5": "^
|
|
34
|
-
"ckeditor5-premium-features": "^
|
|
32
|
+
"@vitest/coverage-v8": "^4.1.0",
|
|
33
|
+
"ckeditor5": "^47.6.0",
|
|
34
|
+
"ckeditor5-premium-features": "^47.6.0",
|
|
35
35
|
"happy-dom": "^20.0.1",
|
|
36
36
|
"typescript": "^5.5.4",
|
|
37
|
-
"vite": "^
|
|
37
|
+
"vite": "^8.0.0",
|
|
38
38
|
"vite-plugin-dts": "^4.5.4",
|
|
39
|
-
"
|
|
40
|
-
"vitest": "^3.2.3"
|
|
39
|
+
"vitest": "^4.1.0"
|
|
41
40
|
},
|
|
42
41
|
"scripts": {
|
|
43
42
|
"clean": "rm -rf dist",
|
package/src/hooks/editable.ts
CHANGED
|
@@ -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
|
|
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
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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
|
|
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
|
}
|
package/src/hooks/ui-part.ts
CHANGED
|
@@ -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
|
|
21
|
+
/* v8 ignore next if -- @preserve */
|
|
22
22
|
if (this.isBeingDestroyed()) {
|
|
23
23
|
return;
|
|
24
24
|
}
|