ckeditor5-livewire 1.2.5 → 1.2.7
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/dist/hooks/editor/editor.d.ts.map +1 -1
- package/dist/hooks/editor/utils/query-editor-editables.d.ts +2 -3
- package/dist/hooks/editor/utils/query-editor-editables.d.ts.map +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +138 -127
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/hooks/editable.test.ts +1 -1
- package/src/hooks/editor/editor.test.ts +29 -7
- package/src/hooks/editor/editor.ts +13 -17
- package/src/hooks/editor/utils/query-editor-editables.ts +35 -9
- package/src/hooks/ui-part.test.ts +1 -1
|
@@ -159,7 +159,7 @@ describe('editor component', () => {
|
|
|
159
159
|
it('should create a decoupled editor with `main` editable and default preset', async () => {
|
|
160
160
|
livewireStub.$internal.appendComponentToDOM<EditorSnapshot>({
|
|
161
161
|
name: 'ckeditor5',
|
|
162
|
-
el: createEditorHtmlElement(),
|
|
162
|
+
el: createEditorHtmlElement({ editorType: 'decoupled' }),
|
|
163
163
|
canonical: {
|
|
164
164
|
...createEditorSnapshot(),
|
|
165
165
|
preset: createEditorPreset('decoupled'),
|
|
@@ -183,7 +183,7 @@ describe('editor component', () => {
|
|
|
183
183
|
|
|
184
184
|
livewireStub.$internal.appendComponentToDOM<EditorSnapshot>({
|
|
185
185
|
name: 'ckeditor5',
|
|
186
|
-
el: createEditorHtmlElement(),
|
|
186
|
+
el: createEditorHtmlElement({ editorType: 'decoupled' }),
|
|
187
187
|
canonical: {
|
|
188
188
|
...createEditorSnapshot(),
|
|
189
189
|
preset: createEditorPreset('decoupled'),
|
|
@@ -202,10 +202,32 @@ describe('editor component', () => {
|
|
|
202
202
|
expect(editor.getData()).toBe(initialEditableContent);
|
|
203
203
|
});
|
|
204
204
|
|
|
205
|
+
it('should pick initial content from root editor element if editable has null content', async () => {
|
|
206
|
+
livewireStub.$internal.appendComponentToDOM<EditorSnapshot>({
|
|
207
|
+
name: 'ckeditor5',
|
|
208
|
+
el: createEditorHtmlElement({ editorType: 'decoupled' }),
|
|
209
|
+
canonical: {
|
|
210
|
+
...createEditorSnapshot(),
|
|
211
|
+
preset: createEditorPreset('decoupled'),
|
|
212
|
+
},
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
livewireStub.$internal.appendComponentToDOM({
|
|
216
|
+
name: 'ckeditor5-editable',
|
|
217
|
+
el: createEditableHtmlElement(),
|
|
218
|
+
canonical: createEditableSnapshot('main'),
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
const editor = await waitForTestEditor();
|
|
222
|
+
|
|
223
|
+
expect(editor).to.toBeInstanceOf(DecoupledEditor);
|
|
224
|
+
expect(editor.getData()).toBe('<p>Initial content</p>');
|
|
225
|
+
});
|
|
226
|
+
|
|
205
227
|
it('should throw error if `main` editable is not found in the DOM', async () => {
|
|
206
228
|
livewireStub.$internal.appendComponentToDOM<EditorSnapshot>({
|
|
207
229
|
name: 'ckeditor5',
|
|
208
|
-
el: createEditorHtmlElement(),
|
|
230
|
+
el: createEditorHtmlElement({ editorType: 'decoupled' }),
|
|
209
231
|
canonical: {
|
|
210
232
|
...createEditorSnapshot(),
|
|
211
233
|
preset: createEditorPreset('decoupled'),
|
|
@@ -240,7 +262,7 @@ describe('editor component', () => {
|
|
|
240
262
|
it('should create a multiroot editor without editables in the DOM and initial content', async () => {
|
|
241
263
|
livewireStub.$internal.appendComponentToDOM<EditorSnapshot>({
|
|
242
264
|
name: 'ckeditor5',
|
|
243
|
-
el: createEditorHtmlElement(),
|
|
265
|
+
el: createEditorHtmlElement({ editorType: 'multiroot' }),
|
|
244
266
|
canonical: {
|
|
245
267
|
...createEditorSnapshot(),
|
|
246
268
|
preset: createEditorPreset('multiroot'),
|
|
@@ -256,7 +278,7 @@ describe('editor component', () => {
|
|
|
256
278
|
it('should wait and for root elements to be present in DOM if they are not (with content=null value)', async () => {
|
|
257
279
|
livewireStub.$internal.appendComponentToDOM<EditorSnapshot>({
|
|
258
280
|
name: 'ckeditor5',
|
|
259
|
-
el: createEditorHtmlElement(),
|
|
281
|
+
el: createEditorHtmlElement({ editorType: 'multiroot' }),
|
|
260
282
|
canonical: {
|
|
261
283
|
...createEditorSnapshot(),
|
|
262
284
|
preset: createEditorPreset('multiroot'),
|
|
@@ -283,7 +305,7 @@ describe('editor component', () => {
|
|
|
283
305
|
it('should wait and for root elements to be present in DOM if they are not (with content=\'\' value)', async () => {
|
|
284
306
|
livewireStub.$internal.appendComponentToDOM<EditorSnapshot>({
|
|
285
307
|
name: 'ckeditor5',
|
|
286
|
-
el: createEditorHtmlElement(),
|
|
308
|
+
el: createEditorHtmlElement({ editorType: 'multiroot' }),
|
|
287
309
|
canonical: {
|
|
288
310
|
...createEditorSnapshot(),
|
|
289
311
|
preset: createEditorPreset('multiroot'),
|
|
@@ -310,7 +332,7 @@ describe('editor component', () => {
|
|
|
310
332
|
it('should wait and for root elements to be present in DOM if they are not (with set content value)', async () => {
|
|
311
333
|
livewireStub.$internal.appendComponentToDOM<EditorSnapshot>({
|
|
312
334
|
name: 'ckeditor5',
|
|
313
|
-
el: createEditorHtmlElement(),
|
|
335
|
+
el: createEditorHtmlElement({ editorType: 'multiroot' }),
|
|
314
336
|
canonical: {
|
|
315
337
|
...createEditorSnapshot(),
|
|
316
338
|
preset: createEditorPreset('multiroot'),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Editor } from 'ckeditor5';
|
|
2
2
|
|
|
3
|
-
import type { EditorId, EditorLanguage, EditorPreset
|
|
3
|
+
import type { EditorId, EditorLanguage, EditorPreset } from './typings';
|
|
4
4
|
import type { EditorCreator } from './utils';
|
|
5
5
|
|
|
6
6
|
import { ContextsRegistry } from '../../hooks/context';
|
|
@@ -197,19 +197,19 @@ export class EditorComponentHook extends ClassHook<Snapshot> {
|
|
|
197
197
|
|
|
198
198
|
// Depending of the editor type, and parent lookup for nearest context or initialize it without it.
|
|
199
199
|
const editor = await (async () => {
|
|
200
|
-
let
|
|
200
|
+
let sourceElements: HTMLElement | Record<string, HTMLElement> = queryEditablesElements(editorId);
|
|
201
201
|
|
|
202
202
|
// Handle special case when user specified `initialData` of several root elements, but editable components
|
|
203
203
|
// are not yet present in the DOM. In other words - editor is initialized before attaching root elements.
|
|
204
|
-
if (!(
|
|
204
|
+
if (!(sourceElements instanceof HTMLElement) && !('main' in sourceElements)) {
|
|
205
205
|
const requiredRoots = (
|
|
206
206
|
editorType === 'decoupled'
|
|
207
207
|
? ['main']
|
|
208
208
|
: Object.keys(initialData as Record<string, string>)
|
|
209
209
|
);
|
|
210
210
|
|
|
211
|
-
if (!checkIfAllRootsArePresent(
|
|
212
|
-
|
|
211
|
+
if (!checkIfAllRootsArePresent(sourceElements, requiredRoots)) {
|
|
212
|
+
sourceElements = await waitForAllRootsToBePresent(editorId, requiredRoots);
|
|
213
213
|
initialData = {
|
|
214
214
|
...content,
|
|
215
215
|
...queryEditablesSnapshotContent(editorId),
|
|
@@ -218,8 +218,8 @@ export class EditorComponentHook extends ClassHook<Snapshot> {
|
|
|
218
218
|
}
|
|
219
219
|
|
|
220
220
|
// If single root editor, unwrap the element from the object.
|
|
221
|
-
if (isSingleRootEditor(editorType) && 'main' in
|
|
222
|
-
|
|
221
|
+
if (isSingleRootEditor(editorType) && 'main' in sourceElements) {
|
|
222
|
+
sourceElements = sourceElements['main'];
|
|
223
223
|
}
|
|
224
224
|
|
|
225
225
|
// Construct parsed config.
|
|
@@ -234,13 +234,13 @@ export class EditorComponentHook extends ClassHook<Snapshot> {
|
|
|
234
234
|
},
|
|
235
235
|
};
|
|
236
236
|
|
|
237
|
-
if (!context || !(
|
|
238
|
-
return Constructor.create(
|
|
237
|
+
if (!context || !(sourceElements instanceof HTMLElement)) {
|
|
238
|
+
return Constructor.create(sourceElements as any, parsedConfig);
|
|
239
239
|
}
|
|
240
240
|
|
|
241
241
|
const result = await createEditorInContext({
|
|
242
242
|
context,
|
|
243
|
-
element:
|
|
243
|
+
element: sourceElements,
|
|
244
244
|
creator: Constructor,
|
|
245
245
|
config: parsedConfig,
|
|
246
246
|
});
|
|
@@ -271,18 +271,16 @@ function checkIfAllRootsArePresent(elements: Record<string, HTMLElement>, requir
|
|
|
271
271
|
* Waits for all required root elements to be present in the DOM.
|
|
272
272
|
*
|
|
273
273
|
* @param editorId The editor's ID.
|
|
274
|
-
* @param editorType The type of the editor.
|
|
275
274
|
* @param requiredRoots The list of required root IDs.
|
|
276
275
|
* @returns A promise that resolves to the record of root elements.
|
|
277
276
|
*/
|
|
278
277
|
async function waitForAllRootsToBePresent(
|
|
279
278
|
editorId: EditorId,
|
|
280
|
-
editorType: EditorType,
|
|
281
279
|
requiredRoots: string[],
|
|
282
280
|
): Promise<Record<string, HTMLElement>> {
|
|
283
|
-
|
|
281
|
+
return waitFor(
|
|
284
282
|
() => {
|
|
285
|
-
const elements = queryEditablesElements(editorId
|
|
283
|
+
const elements = queryEditablesElements(editorId) as unknown as Record<string, HTMLElement>;
|
|
286
284
|
|
|
287
285
|
if (!checkIfAllRootsArePresent(elements, requiredRoots)) {
|
|
288
286
|
throw new Error(
|
|
@@ -294,12 +292,10 @@ async function waitForAllRootsToBePresent(
|
|
|
294
292
|
);
|
|
295
293
|
}
|
|
296
294
|
|
|
297
|
-
return
|
|
295
|
+
return elements;
|
|
298
296
|
},
|
|
299
297
|
{ timeOutAfter: 2000, retryAfter: 100 },
|
|
300
298
|
);
|
|
301
|
-
|
|
302
|
-
return queryEditablesElements(editorId, editorType) as unknown as Record<string, HTMLElement>;
|
|
303
299
|
}
|
|
304
300
|
|
|
305
301
|
/**
|
|
@@ -1,20 +1,14 @@
|
|
|
1
|
-
import type { EditorId
|
|
1
|
+
import type { EditorId } from '../typings';
|
|
2
2
|
|
|
3
3
|
import { filterObjectValues, mapObjectValues } from '../../../shared';
|
|
4
|
-
import { isSingleRootEditor } from './is-single-root-editor';
|
|
5
4
|
|
|
6
5
|
/**
|
|
7
6
|
* Gets the initial root elements for the editor based on its type.
|
|
8
7
|
*
|
|
9
8
|
* @param editorId The editor's ID.
|
|
10
|
-
* @param type The type of the editor.
|
|
11
9
|
* @returns The root element(s) for the editor.
|
|
12
10
|
*/
|
|
13
|
-
export function queryEditablesElements(editorId: EditorId
|
|
14
|
-
if (isSingleRootEditor(type) && type !== 'decoupled') {
|
|
15
|
-
return document.getElementById(`${editorId}_editor`)!;
|
|
16
|
-
}
|
|
17
|
-
|
|
11
|
+
export function queryEditablesElements(editorId: EditorId) {
|
|
18
12
|
const editables = queryAllEditorEditables(editorId);
|
|
19
13
|
|
|
20
14
|
return mapObjectValues(editables, ({ element }) => element);
|
|
@@ -27,7 +21,7 @@ export function queryEditablesElements(editorId: EditorId, type: EditorType) {
|
|
|
27
21
|
* @returns An object mapping editable names to their corresponding elements and initial values.
|
|
28
22
|
*/
|
|
29
23
|
export function queryAllEditorEditables(editorId: EditorId): Record<string, EditableItem> {
|
|
30
|
-
|
|
24
|
+
const acc = (
|
|
31
25
|
window.Livewire
|
|
32
26
|
.all()
|
|
33
27
|
.filter(({ name, canonical }) => name === 'ckeditor5-editable' && canonical['editorId'] === editorId)
|
|
@@ -39,6 +33,38 @@ export function queryAllEditorEditables(editorId: EditorId): Record<string, Edit
|
|
|
39
33
|
},
|
|
40
34
|
}), Object.create({}))
|
|
41
35
|
);
|
|
36
|
+
|
|
37
|
+
const rootHook = (
|
|
38
|
+
window.Livewire
|
|
39
|
+
.all()
|
|
40
|
+
.find(({ name, canonical }) => name === 'ckeditor5' && canonical['editorId'] === editorId)
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
const initialRootEditableValue = rootHook?.canonical.content as Record<string, string> | null;
|
|
44
|
+
const contentElement = document.querySelector<HTMLElement>(`#${editorId}_editor `);
|
|
45
|
+
const currentMain = acc['main'];
|
|
46
|
+
|
|
47
|
+
if (currentMain && initialRootEditableValue?.['main']) {
|
|
48
|
+
return {
|
|
49
|
+
...acc,
|
|
50
|
+
main: {
|
|
51
|
+
...currentMain,
|
|
52
|
+
content: currentMain.content || initialRootEditableValue['main'],
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (contentElement) {
|
|
58
|
+
return {
|
|
59
|
+
...acc,
|
|
60
|
+
main: {
|
|
61
|
+
element: contentElement,
|
|
62
|
+
content: initialRootEditableValue?.['main'] || null,
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return acc;
|
|
42
68
|
}
|
|
43
69
|
|
|
44
70
|
/**
|
|
@@ -150,7 +150,7 @@ describe('ui-part component', () => {
|
|
|
150
150
|
function appendMultirootEditor(initialContent: Record<string, string> = {}) {
|
|
151
151
|
livewireStub.$internal.appendComponentToDOM<EditorSnapshot>({
|
|
152
152
|
name: 'ckeditor5',
|
|
153
|
-
el: createEditorHtmlElement(),
|
|
153
|
+
el: createEditorHtmlElement({ editorType: 'multiroot' }),
|
|
154
154
|
canonical: {
|
|
155
155
|
...createEditorSnapshot(),
|
|
156
156
|
preset: createEditorPreset('multiroot'),
|