ckeditor5-symfony 1.0.0 → 1.0.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.
- package/LICENSE +21 -0
- package/dist/elements/editable.d.ts.map +1 -1
- package/dist/elements/ui-part.d.ts.map +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +24 -13
- package/dist/index.mjs.map +1 -1
- package/package.json +14 -12
- package/src/elements/context/context.test.ts +8 -4
- package/src/elements/editable.test.ts +23 -2
- package/src/elements/editable.ts +13 -2
- package/src/elements/editor/editor.test.ts +29 -8
- package/src/elements/ui-part.test.ts +18 -4
- package/src/elements/ui-part.ts +4 -0
|
@@ -6,10 +6,11 @@ import {
|
|
|
6
6
|
createEditorPreset,
|
|
7
7
|
renderTestEditable,
|
|
8
8
|
renderTestEditor,
|
|
9
|
+
waitForDestroyAllEditors,
|
|
9
10
|
waitForTestEditor,
|
|
10
11
|
} from '~/test-utils';
|
|
11
12
|
|
|
12
|
-
import {
|
|
13
|
+
import { timeout } from '../shared';
|
|
13
14
|
import { registerCustomElements } from './register-custom-elements';
|
|
14
15
|
|
|
15
16
|
describe('editable component', () => {
|
|
@@ -22,8 +23,9 @@ describe('editable component', () => {
|
|
|
22
23
|
vi.useRealTimers();
|
|
23
24
|
vi.resetAllMocks();
|
|
24
25
|
|
|
26
|
+
await waitForDestroyAllEditors();
|
|
27
|
+
|
|
25
28
|
document.body.innerHTML = '';
|
|
26
|
-
EditorsRegistry.the.reset();
|
|
27
29
|
});
|
|
28
30
|
|
|
29
31
|
describe('mounting editable', () => {
|
|
@@ -155,6 +157,25 @@ describe('editable component', () => {
|
|
|
155
157
|
expect(editable.getAttribute('data-cke-editor-id')).toBe('test-editor');
|
|
156
158
|
});
|
|
157
159
|
});
|
|
160
|
+
|
|
161
|
+
it('should not initialize editable if element is disconnected before editor is ready', async () => {
|
|
162
|
+
const el = renderTestEditable({
|
|
163
|
+
rootName: 'foo',
|
|
164
|
+
content: '<p>Foo</p>',
|
|
165
|
+
});
|
|
166
|
+
el.remove();
|
|
167
|
+
|
|
168
|
+
renderTestEditor({
|
|
169
|
+
preset: createEditorPreset('multiroot'),
|
|
170
|
+
content: {},
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
const editor = await waitForTestEditor<MultiRootEditor>();
|
|
174
|
+
|
|
175
|
+
await timeout(10);
|
|
176
|
+
|
|
177
|
+
expect(editor.model.document.getRoot('foo')).toBe(null);
|
|
178
|
+
});
|
|
158
179
|
});
|
|
159
180
|
|
|
160
181
|
describe('input value synchronization', () => {
|
package/src/elements/editable.ts
CHANGED
|
@@ -12,7 +12,7 @@ export class EditableComponentElement extends HTMLElement {
|
|
|
12
12
|
/**
|
|
13
13
|
* The promise that resolves when the editable is mounted.
|
|
14
14
|
*/
|
|
15
|
-
private editorPromise: Promise<MultiRootEditor> | null = null;
|
|
15
|
+
private editorPromise: Promise<MultiRootEditor | null> | null = null;
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* Mounts the editable component.
|
|
@@ -37,6 +37,10 @@ export class EditableComponentElement extends HTMLElement {
|
|
|
37
37
|
// If the editor is not registered yet, we will wait for it to be registered.
|
|
38
38
|
this.style.display = 'block';
|
|
39
39
|
this.editorPromise = EditorsRegistry.the.execute(editorId, async (editor: MultiRootEditor) => {
|
|
40
|
+
if (!this.isConnected) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
|
|
40
44
|
const input = this.querySelector('input') as HTMLInputElement | null;
|
|
41
45
|
const { ui, editing, model } = editor;
|
|
42
46
|
|
|
@@ -106,7 +110,14 @@ export class EditableComponentElement extends HTMLElement {
|
|
|
106
110
|
const root = editor.model.document.getRoot(rootName);
|
|
107
111
|
|
|
108
112
|
if (root && 'detachEditable' in editor) {
|
|
109
|
-
|
|
113
|
+
try {
|
|
114
|
+
editor.detachEditable(root);
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
// Ignore errors when detaching editable.
|
|
118
|
+
console.error('Unable unmount editable from root:', err);
|
|
119
|
+
}
|
|
120
|
+
|
|
110
121
|
editor.detachRoot(rootName, false);
|
|
111
122
|
}
|
|
112
123
|
}
|
|
@@ -19,27 +19,28 @@ import {
|
|
|
19
19
|
isEditorShown,
|
|
20
20
|
renderTestEditable,
|
|
21
21
|
renderTestEditor,
|
|
22
|
+
waitForDestroyAllEditors,
|
|
22
23
|
waitForTestEditor,
|
|
23
24
|
} from '~/test-utils';
|
|
24
25
|
|
|
25
26
|
import { timeout } from '../../shared/timeout';
|
|
26
27
|
import { registerCustomElements } from '../register-custom-elements';
|
|
27
28
|
import { CustomEditorPluginsRegistry } from './custom-editor-plugins';
|
|
28
|
-
import { EditorsRegistry } from './editors-registry';
|
|
29
29
|
import { unwrapEditorWatchdog } from './utils';
|
|
30
30
|
|
|
31
31
|
describe('editor component', () => {
|
|
32
|
-
beforeEach(() => {
|
|
32
|
+
beforeEach(async () => {
|
|
33
33
|
document.body.innerHTML = '';
|
|
34
34
|
registerCustomElements();
|
|
35
35
|
});
|
|
36
36
|
|
|
37
37
|
afterEach(async () => {
|
|
38
38
|
vi.useRealTimers();
|
|
39
|
+
vi.resetAllMocks();
|
|
40
|
+
|
|
39
41
|
document.body.innerHTML = '';
|
|
40
42
|
|
|
41
|
-
|
|
42
|
-
EditorsRegistry.the.reset();
|
|
43
|
+
await waitForDestroyAllEditors();
|
|
43
44
|
});
|
|
44
45
|
|
|
45
46
|
it('should save the editor instance in the registry with provided editorId', async () => {
|
|
@@ -219,14 +220,17 @@ describe('editor component', () => {
|
|
|
219
220
|
},
|
|
220
221
|
});
|
|
221
222
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
223
|
+
renderTestEditable(
|
|
224
|
+
createEditableSnapshot('header', '<p>Editable content overrides snapshot content</p>'),
|
|
225
|
+
);
|
|
225
226
|
|
|
226
227
|
const editor = await waitForTestEditor();
|
|
227
228
|
|
|
228
229
|
expect(editor).toBeInstanceOf(MultiRootEditor);
|
|
229
|
-
|
|
230
|
+
|
|
231
|
+
await vi.waitFor(() => {
|
|
232
|
+
expect(editor.getData({ rootName: 'header' })).toBe('<p>Editable content overrides snapshot content</p>');
|
|
233
|
+
});
|
|
230
234
|
});
|
|
231
235
|
|
|
232
236
|
it('should not crash after setting content using `setData`', async () => {
|
|
@@ -242,6 +246,23 @@ describe('editor component', () => {
|
|
|
242
246
|
editor.setData('<p>New content</p>');
|
|
243
247
|
}).not.toThrow();
|
|
244
248
|
});
|
|
249
|
+
|
|
250
|
+
it('should update root data if root already exists but editable has different content', async () => {
|
|
251
|
+
renderTestEditor({
|
|
252
|
+
preset: createEditorPreset('multiroot'),
|
|
253
|
+
content: {},
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
const editor = await waitForTestEditor<MultiRootEditor>();
|
|
257
|
+
|
|
258
|
+
editor.addRoot('existingRoot', { data: '<p>Old content</p>' });
|
|
259
|
+
|
|
260
|
+
renderTestEditable(createEditableSnapshot('existingRoot', '<p>New content</p>'));
|
|
261
|
+
|
|
262
|
+
await vi.waitFor(() => {
|
|
263
|
+
expect(editor.getData({ rootName: 'existingRoot' })).toBe('<p>New content</p>');
|
|
264
|
+
});
|
|
265
|
+
});
|
|
245
266
|
});
|
|
246
267
|
});
|
|
247
268
|
|
|
@@ -5,10 +5,11 @@ import {
|
|
|
5
5
|
createUIPartSnapshot,
|
|
6
6
|
renderTestEditor,
|
|
7
7
|
renderTestUIPart,
|
|
8
|
+
waitForDestroyAllEditors,
|
|
8
9
|
waitForTestEditor,
|
|
9
10
|
} from '~/test-utils';
|
|
10
11
|
|
|
11
|
-
import {
|
|
12
|
+
import { timeout } from '../shared';
|
|
12
13
|
import { EditorsRegistry } from './editor/editors-registry';
|
|
13
14
|
import { registerCustomElements } from './register-custom-elements';
|
|
14
15
|
|
|
@@ -19,10 +20,11 @@ describe('ui-part component', () => {
|
|
|
19
20
|
});
|
|
20
21
|
|
|
21
22
|
afterEach(async () => {
|
|
23
|
+
vi.useRealTimers();
|
|
24
|
+
vi.resetAllMocks();
|
|
25
|
+
|
|
26
|
+
await waitForDestroyAllEditors();
|
|
22
27
|
document.body.innerHTML = '';
|
|
23
|
-
CustomEditorPluginsRegistry.the.unregisterAll();
|
|
24
|
-
EditorsRegistry.the.reset();
|
|
25
|
-
vi.restoreAllMocks();
|
|
26
28
|
});
|
|
27
29
|
|
|
28
30
|
describe('mounting ui part', () => {
|
|
@@ -86,6 +88,18 @@ describe('ui-part component', () => {
|
|
|
86
88
|
|
|
87
89
|
expect(toolbarElement).toBeTruthy();
|
|
88
90
|
});
|
|
91
|
+
|
|
92
|
+
it('should not mount UI part if element is disconnected before editor is ready', async () => {
|
|
93
|
+
const el = renderTestUIPart(createUIPartSnapshot('toolbar'));
|
|
94
|
+
el.remove();
|
|
95
|
+
|
|
96
|
+
appendMultirootEditor();
|
|
97
|
+
|
|
98
|
+
await waitForTestEditor();
|
|
99
|
+
await timeout(10);
|
|
100
|
+
|
|
101
|
+
expect(el.innerHTML).toBe('');
|
|
102
|
+
});
|
|
89
103
|
});
|
|
90
104
|
|
|
91
105
|
describe('destroying ui part', () => {
|
package/src/elements/ui-part.ts
CHANGED
|
@@ -29,6 +29,10 @@ export class UIPartComponentElement extends HTMLElement {
|
|
|
29
29
|
// If the editor is not registered yet, we will wait for it to be registered.
|
|
30
30
|
this.style.display = 'block';
|
|
31
31
|
this.mountedPromise = EditorsRegistry.the.execute(editorId, (editor) => {
|
|
32
|
+
if (!this.isConnected) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
32
36
|
const { ui } = editor;
|
|
33
37
|
|
|
34
38
|
const uiViewName = mapUIPartView(name);
|