@ckeditor/ckeditor5-watchdog 38.2.0-alpha.1 → 39.0.1
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/README.md +0 -1
- package/package.json +2 -3
- package/src/augmentation.d.ts +15 -0
- package/src/augmentation.js +5 -0
- package/src/contextwatchdog.d.ts +4 -4
- package/src/contextwatchdog.js +4 -4
- package/src/editorwatchdog.d.ts +35 -6
- package/src/editorwatchdog.js +220 -14
- package/src/index.d.ts +4 -3
- package/src/index.js +4 -3
- package/src/utils/areconnectedthroughproperties.js +1 -1
- package/src/watchdog.d.ts +3 -3
package/README.md
CHANGED
|
@@ -4,7 +4,6 @@ CKEditor 5 watchdog feature
|
|
|
4
4
|
[](https://www.npmjs.com/package/@ckeditor/ckeditor5-watchdog)
|
|
5
5
|
[](https://coveralls.io/github/ckeditor/ckeditor5?branch=master)
|
|
6
6
|
[](https://app.travis-ci.com/github/ckeditor/ckeditor5)
|
|
7
|
-

|
|
8
7
|
|
|
9
8
|
This package implements the watchdog feature for CKEditor 5. It keeps a CKEditor 5 rich-text editor instance running.
|
|
10
9
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ckeditor/ckeditor5-watchdog",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "39.0.1",
|
|
4
4
|
"description": "A watchdog feature for CKEditor 5 editors. It keeps a CKEditor 5 editor instance running.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ckeditor",
|
|
@@ -10,9 +10,8 @@
|
|
|
10
10
|
"ckeditor5-dll"
|
|
11
11
|
],
|
|
12
12
|
"main": "src/index.js",
|
|
13
|
-
"type": "module",
|
|
14
13
|
"dependencies": {
|
|
15
|
-
"lodash-es": "
|
|
14
|
+
"lodash-es": "4.17.21"
|
|
16
15
|
},
|
|
17
16
|
"engines": {
|
|
18
17
|
"node": ">=16.0.0",
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
import type { EditorData } from './editorwatchdog';
|
|
6
|
+
declare module '@ckeditor/ckeditor5-core' {
|
|
7
|
+
interface EditorConfig {
|
|
8
|
+
/**
|
|
9
|
+
* The temporary property that is used for passing data to the plugin which restores the editor state.
|
|
10
|
+
*
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
_watchdogInitialData?: EditorData;
|
|
14
|
+
}
|
|
15
|
+
}
|
package/src/contextwatchdog.d.ts
CHANGED
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
/**
|
|
6
6
|
* @module watchdog/contextwatchdog
|
|
7
7
|
*/
|
|
8
|
-
import type { Context, Editor, EditorConfig, ContextConfig } from 'ckeditor5/src/core
|
|
9
|
-
import type { ArrayOrItem, CKEditorError } from 'ckeditor5/src/utils
|
|
10
|
-
import Watchdog, { type WatchdogConfig, type WatchdogState } from './watchdog
|
|
11
|
-
import EditorWatchdog, { type EditorCreatorFunction } from './editorwatchdog
|
|
8
|
+
import type { Context, Editor, EditorConfig, ContextConfig } from 'ckeditor5/src/core';
|
|
9
|
+
import type { ArrayOrItem, CKEditorError } from 'ckeditor5/src/utils';
|
|
10
|
+
import Watchdog, { type WatchdogConfig, type WatchdogState } from './watchdog';
|
|
11
|
+
import EditorWatchdog, { type EditorCreatorFunction } from './editorwatchdog';
|
|
12
12
|
/**
|
|
13
13
|
* A watchdog for the {@link module:core/context~Context} class.
|
|
14
14
|
*
|
package/src/contextwatchdog.js
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
3
|
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
4
|
*/
|
|
5
|
-
import Watchdog from './watchdog
|
|
6
|
-
import EditorWatchdog from './editorwatchdog
|
|
7
|
-
import areConnectedThroughProperties from './utils/areconnectedthroughproperties
|
|
8
|
-
import getSubNodes from './utils/getsubnodes
|
|
5
|
+
import Watchdog from './watchdog';
|
|
6
|
+
import EditorWatchdog from './editorwatchdog';
|
|
7
|
+
import areConnectedThroughProperties from './utils/areconnectedthroughproperties';
|
|
8
|
+
import getSubNodes from './utils/getsubnodes';
|
|
9
9
|
const mainQueueId = Symbol('MainQueueId');
|
|
10
10
|
/**
|
|
11
11
|
* A watchdog for the {@link module:core/context~Context} class.
|
package/src/editorwatchdog.d.ts
CHANGED
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
/**
|
|
6
6
|
* @module watchdog/editorwatchdog
|
|
7
7
|
*/
|
|
8
|
-
import type { CKEditorError } from 'ckeditor5/src/utils
|
|
9
|
-
import type { Editor, EditorConfig, Context } from 'ckeditor5/src/core
|
|
10
|
-
import Watchdog, { type WatchdogConfig } from './watchdog
|
|
8
|
+
import type { CKEditorError } from 'ckeditor5/src/utils';
|
|
9
|
+
import type { Editor, EditorConfig, Context } from 'ckeditor5/src/core';
|
|
10
|
+
import Watchdog, { type WatchdogConfig } from './watchdog';
|
|
11
11
|
/**
|
|
12
12
|
* A watchdog for CKEditor 5 editors.
|
|
13
13
|
*
|
|
@@ -36,6 +36,14 @@ export default class EditorWatchdog<TEditor extends Editor = Editor> extends Wat
|
|
|
36
36
|
* The editor source element or data.
|
|
37
37
|
*/
|
|
38
38
|
private _elementOrData?;
|
|
39
|
+
/**
|
|
40
|
+
* Specifies whether the editor was initialized using document data (`true`) or HTML elements (`false`).
|
|
41
|
+
*/
|
|
42
|
+
private _initUsingData;
|
|
43
|
+
/**
|
|
44
|
+
* The latest record of the editor editable elements. Used to restart the editor.
|
|
45
|
+
*/
|
|
46
|
+
private _editables;
|
|
39
47
|
/**
|
|
40
48
|
* The editor configuration.
|
|
41
49
|
*/
|
|
@@ -109,7 +117,7 @@ export default class EditorWatchdog<TEditor extends Editor = Editor> extends Wat
|
|
|
109
117
|
* @param config The editor configuration.
|
|
110
118
|
* @param context A context for the editor.
|
|
111
119
|
*/
|
|
112
|
-
create(elementOrData?: HTMLElement | string | Record<string, string>, config?: EditorConfig, context?: Context): Promise<unknown>;
|
|
120
|
+
create(elementOrData?: HTMLElement | string | Record<string, string> | Record<string, HTMLElement>, config?: EditorConfig, context?: Context): Promise<unknown>;
|
|
113
121
|
/**
|
|
114
122
|
* Destroys the watchdog and the current editor instance. It fires the callback
|
|
115
123
|
* registered in {@link #setDestructor `setDestructor()`} and uses it to destroy the editor instance.
|
|
@@ -127,9 +135,13 @@ export default class EditorWatchdog<TEditor extends Editor = Editor> extends Wat
|
|
|
127
135
|
*/
|
|
128
136
|
_setExcludedProperties(props: Set<unknown>): void;
|
|
129
137
|
/**
|
|
130
|
-
*
|
|
138
|
+
* Gets all data that is required to reinitialize editor instance.
|
|
131
139
|
*/
|
|
132
140
|
private _getData;
|
|
141
|
+
/**
|
|
142
|
+
* For each attached model root, returns its HTML editable element (if available).
|
|
143
|
+
*/
|
|
144
|
+
private _getEditables;
|
|
133
145
|
/**
|
|
134
146
|
* Traverses the error context and the current editor to find out whether these structures are connected
|
|
135
147
|
* to each other via properties.
|
|
@@ -142,6 +154,23 @@ export default class EditorWatchdog<TEditor extends Editor = Editor> extends Wat
|
|
|
142
154
|
*/
|
|
143
155
|
private _cloneEditorConfiguration;
|
|
144
156
|
}
|
|
157
|
+
export type EditorData = {
|
|
158
|
+
roots: Record<string, {
|
|
159
|
+
content: string;
|
|
160
|
+
attributes: string;
|
|
161
|
+
isLoaded: boolean;
|
|
162
|
+
}>;
|
|
163
|
+
markers: Record<string, {
|
|
164
|
+
rangeJSON: {
|
|
165
|
+
start: any;
|
|
166
|
+
end: any;
|
|
167
|
+
};
|
|
168
|
+
usingOperation: boolean;
|
|
169
|
+
affectsData: boolean;
|
|
170
|
+
}>;
|
|
171
|
+
commentThreads: string;
|
|
172
|
+
suggestions: string;
|
|
173
|
+
};
|
|
145
174
|
/**
|
|
146
175
|
* Fired after the watchdog restarts the error in case of a crash.
|
|
147
176
|
*
|
|
@@ -152,4 +181,4 @@ export type EditorWatchdogRestartEvent = {
|
|
|
152
181
|
args: [];
|
|
153
182
|
return: undefined;
|
|
154
183
|
};
|
|
155
|
-
export type EditorCreatorFunction<TEditor = Editor> = (elementOrData: HTMLElement | string | Record<string, string>, config: EditorConfig) => Promise<TEditor>;
|
|
184
|
+
export type EditorCreatorFunction<TEditor = Editor> = (elementOrData: HTMLElement | string | Record<string, string> | Record<string, HTMLElement>, config: EditorConfig) => Promise<TEditor>;
|
package/src/editorwatchdog.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
3
|
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
4
|
*/
|
|
5
|
-
import areConnectedThroughProperties from './utils/areconnectedthroughproperties
|
|
6
|
-
import Watchdog from './watchdog
|
|
5
|
+
import areConnectedThroughProperties from './utils/areconnectedthroughproperties';
|
|
6
|
+
import Watchdog from './watchdog';
|
|
7
7
|
import { throttle, cloneDeepWith, isElement } from 'lodash-es';
|
|
8
8
|
/**
|
|
9
9
|
* A watchdog for CKEditor 5 editors.
|
|
@@ -22,6 +22,14 @@ export default class EditorWatchdog extends Watchdog {
|
|
|
22
22
|
* The current editor instance.
|
|
23
23
|
*/
|
|
24
24
|
this._editor = null;
|
|
25
|
+
/**
|
|
26
|
+
* Specifies whether the editor was initialized using document data (`true`) or HTML elements (`false`).
|
|
27
|
+
*/
|
|
28
|
+
this._initUsingData = true;
|
|
29
|
+
/**
|
|
30
|
+
* The latest record of the editor editable elements. Used to restart the editor.
|
|
31
|
+
*/
|
|
32
|
+
this._editables = {};
|
|
25
33
|
// this._editorClass = Editor;
|
|
26
34
|
this._throttledSave = throttle(this._save.bind(this), typeof watchdogConfig.saveInterval === 'number' ? watchdogConfig.saveInterval : 5000);
|
|
27
35
|
// Set default creator and destructor functions:
|
|
@@ -90,14 +98,56 @@ export default class EditorWatchdog extends Watchdog {
|
|
|
90
98
|
console.error('An error happened during the editor destroying.', err);
|
|
91
99
|
})
|
|
92
100
|
.then(() => {
|
|
93
|
-
|
|
94
|
-
|
|
101
|
+
// Pre-process some data from the original editor config.
|
|
102
|
+
// Our goal here is to make sure that the restarted editor will be reinitialized with correct set of roots.
|
|
103
|
+
// We are not interested in any data set in config or in `.create()` first parameter. It will be replaced anyway.
|
|
104
|
+
// But we need to set them correctly to make sure that proper roots are created.
|
|
105
|
+
//
|
|
106
|
+
// Since a different set of roots will be created, `lazyRoots` and `rootsAttributes` properties must be managed too.
|
|
107
|
+
// Keys are root names, values are ''. Used when the editor was initialized by setting the first parameter to document data.
|
|
108
|
+
const existingRoots = {};
|
|
109
|
+
// Keeps lazy roots. They may be different when compared to initial config if some of the roots were loaded.
|
|
110
|
+
const lazyRoots = [];
|
|
111
|
+
// Roots attributes from the old config. Will be referred when setting new attributes.
|
|
112
|
+
const oldRootsAttributes = this._config.rootsAttributes || {};
|
|
113
|
+
// New attributes to be set. Is filled only for roots that still exist in the document.
|
|
114
|
+
const rootsAttributes = {};
|
|
115
|
+
// Traverse through the roots saved when the editor crashed and set up the discussed values.
|
|
116
|
+
for (const [rootName, rootData] of Object.entries(this._data.roots)) {
|
|
117
|
+
if (rootData.isLoaded) {
|
|
118
|
+
existingRoots[rootName] = '';
|
|
119
|
+
rootsAttributes[rootName] = oldRootsAttributes[rootName] || {};
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
lazyRoots.push(rootName);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
const updatedConfig = {
|
|
126
|
+
...this._config,
|
|
127
|
+
extraPlugins: this._config.extraPlugins || [],
|
|
128
|
+
lazyRoots,
|
|
129
|
+
rootsAttributes,
|
|
130
|
+
_watchdogInitialData: this._data
|
|
131
|
+
};
|
|
132
|
+
// Delete `initialData` as it is not needed. Data will be set by the watchdog based on `_watchdogInitialData`.
|
|
133
|
+
// First parameter of the editor `.create()` will be used to set up initial roots.
|
|
134
|
+
delete updatedConfig.initialData;
|
|
135
|
+
updatedConfig.extraPlugins.push(EditorWatchdogInitPlugin);
|
|
136
|
+
if (this._initUsingData) {
|
|
137
|
+
return this.create(existingRoots, updatedConfig, updatedConfig.context);
|
|
95
138
|
}
|
|
96
139
|
else {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
140
|
+
// Set correct editables to make sure that proper roots are created and linked with DOM elements.
|
|
141
|
+
// No need to set initial data, as it would be discarded anyway.
|
|
142
|
+
//
|
|
143
|
+
// If one element was initially set in `elementOrData`, then use that original element to restart the editor.
|
|
144
|
+
// This is for compatibility purposes with single-root editor types.
|
|
145
|
+
if (isElement(this._elementOrData)) {
|
|
146
|
+
return this.create(this._elementOrData, updatedConfig, updatedConfig.context);
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
return this.create(this._editables, updatedConfig, updatedConfig.context);
|
|
150
|
+
}
|
|
101
151
|
}
|
|
102
152
|
})
|
|
103
153
|
.then(() => {
|
|
@@ -116,6 +166,10 @@ export default class EditorWatchdog extends Watchdog {
|
|
|
116
166
|
.then(() => {
|
|
117
167
|
super._startErrorHandling();
|
|
118
168
|
this._elementOrData = elementOrData;
|
|
169
|
+
// Use document data in the first parameter of the editor `.create()` call only if it was used like this originally.
|
|
170
|
+
// Use document data if a string or object with strings was passed.
|
|
171
|
+
this._initUsingData = typeof elementOrData == 'string' ||
|
|
172
|
+
(Object.keys(elementOrData).length > 0 && typeof Object.values(elementOrData)[0] == 'string');
|
|
119
173
|
// Clone configuration because it might be shared within multiple watchdog instances. Otherwise,
|
|
120
174
|
// when an error occurs in one of these editors, the watchdog will restart all of them.
|
|
121
175
|
this._config = this._cloneEditorConfiguration(config) || {};
|
|
@@ -127,6 +181,9 @@ export default class EditorWatchdog extends Watchdog {
|
|
|
127
181
|
editor.model.document.on('change:data', this._throttledSave);
|
|
128
182
|
this._lastDocumentVersion = editor.model.document.version;
|
|
129
183
|
this._data = this._getData();
|
|
184
|
+
if (!this._initUsingData) {
|
|
185
|
+
this._editables = this._getEditables();
|
|
186
|
+
}
|
|
130
187
|
this.state = 'ready';
|
|
131
188
|
this._fire('stateChange');
|
|
132
189
|
});
|
|
@@ -149,8 +206,7 @@ export default class EditorWatchdog extends Watchdog {
|
|
|
149
206
|
return Promise.resolve()
|
|
150
207
|
.then(() => {
|
|
151
208
|
this._stopErrorHandling();
|
|
152
|
-
|
|
153
|
-
this._throttledSave.flush();
|
|
209
|
+
this._throttledSave.cancel();
|
|
154
210
|
const editor = this._editor;
|
|
155
211
|
this._editor = null;
|
|
156
212
|
// Remove the `change:data` listener before destroying the editor.
|
|
@@ -168,6 +224,9 @@ export default class EditorWatchdog extends Watchdog {
|
|
|
168
224
|
const version = this._editor.model.document.version;
|
|
169
225
|
try {
|
|
170
226
|
this._data = this._getData();
|
|
227
|
+
if (!this._initUsingData) {
|
|
228
|
+
this._editables = this._getEditables();
|
|
229
|
+
}
|
|
171
230
|
this._lastDocumentVersion = version;
|
|
172
231
|
}
|
|
173
232
|
catch (err) {
|
|
@@ -182,15 +241,59 @@ export default class EditorWatchdog extends Watchdog {
|
|
|
182
241
|
this._excludedProps = props;
|
|
183
242
|
}
|
|
184
243
|
/**
|
|
185
|
-
*
|
|
244
|
+
* Gets all data that is required to reinitialize editor instance.
|
|
186
245
|
*/
|
|
187
246
|
_getData() {
|
|
188
|
-
const
|
|
189
|
-
|
|
190
|
-
|
|
247
|
+
const editor = this._editor;
|
|
248
|
+
const roots = editor.model.document.roots.filter(root => root.isAttached() && root.rootName != '$graveyard');
|
|
249
|
+
const { plugins } = editor;
|
|
250
|
+
// `as any` to avoid linking from external private repo.
|
|
251
|
+
const commentsRepository = plugins.has('CommentsRepository') && plugins.get('CommentsRepository');
|
|
252
|
+
const trackChanges = plugins.has('TrackChanges') && plugins.get('TrackChanges');
|
|
253
|
+
const data = {
|
|
254
|
+
roots: {},
|
|
255
|
+
markers: {},
|
|
256
|
+
commentThreads: JSON.stringify([]),
|
|
257
|
+
suggestions: JSON.stringify([])
|
|
258
|
+
};
|
|
259
|
+
roots.forEach(root => {
|
|
260
|
+
data.roots[root.rootName] = {
|
|
261
|
+
content: JSON.stringify(Array.from(root.getChildren())),
|
|
262
|
+
attributes: JSON.stringify(Array.from(root.getAttributes())),
|
|
263
|
+
isLoaded: root._isLoaded
|
|
264
|
+
};
|
|
265
|
+
});
|
|
266
|
+
for (const marker of editor.model.markers) {
|
|
267
|
+
if (!marker._affectsData) {
|
|
268
|
+
continue;
|
|
269
|
+
}
|
|
270
|
+
data.markers[marker.name] = {
|
|
271
|
+
rangeJSON: marker.getRange().toJSON(),
|
|
272
|
+
usingOperation: marker._managedUsingOperations,
|
|
273
|
+
affectsData: marker._affectsData
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
if (commentsRepository) {
|
|
277
|
+
data.commentThreads = JSON.stringify(commentsRepository.getCommentThreads({ toJSON: true, skipNotAttached: true }));
|
|
278
|
+
}
|
|
279
|
+
if (trackChanges) {
|
|
280
|
+
data.suggestions = JSON.stringify(trackChanges.getSuggestions({ toJSON: true, skipNotAttached: true }));
|
|
191
281
|
}
|
|
192
282
|
return data;
|
|
193
283
|
}
|
|
284
|
+
/**
|
|
285
|
+
* For each attached model root, returns its HTML editable element (if available).
|
|
286
|
+
*/
|
|
287
|
+
_getEditables() {
|
|
288
|
+
const editables = {};
|
|
289
|
+
for (const rootName of this.editor.model.document.getRootNames()) {
|
|
290
|
+
const editable = this.editor.ui.getEditableElement(rootName);
|
|
291
|
+
if (editable) {
|
|
292
|
+
editables[rootName] = editable;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
return editables;
|
|
296
|
+
}
|
|
194
297
|
/**
|
|
195
298
|
* Traverses the error context and the current editor to find out whether these structures are connected
|
|
196
299
|
* to each other via properties.
|
|
@@ -215,3 +318,106 @@ export default class EditorWatchdog extends Watchdog {
|
|
|
215
318
|
});
|
|
216
319
|
}
|
|
217
320
|
}
|
|
321
|
+
/**
|
|
322
|
+
* Internal plugin that is used to stop the default editor initialization and restoring the editor state
|
|
323
|
+
* based on the `editor.config._watchdogInitialData` data.
|
|
324
|
+
*/
|
|
325
|
+
class EditorWatchdogInitPlugin {
|
|
326
|
+
constructor(editor) {
|
|
327
|
+
this.editor = editor;
|
|
328
|
+
this._data = editor.config.get('_watchdogInitialData');
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* @inheritDoc
|
|
332
|
+
*/
|
|
333
|
+
init() {
|
|
334
|
+
// Stops the default editor initialization and use the saved data to restore the editor state.
|
|
335
|
+
// Some of data could not be initialize as a config properties. It is important to keep the data
|
|
336
|
+
// in the same form as it was before the restarting.
|
|
337
|
+
this.editor.data.on('init', evt => {
|
|
338
|
+
evt.stop();
|
|
339
|
+
this.editor.model.enqueueChange({ isUndoable: false }, writer => {
|
|
340
|
+
this._restoreCollaborationData();
|
|
341
|
+
this._restoreEditorData(writer);
|
|
342
|
+
});
|
|
343
|
+
this.editor.data.fire('ready');
|
|
344
|
+
// Keep priority `'high' - 1` to be sure that RTC initialization will be first.
|
|
345
|
+
}, { priority: 1000 - 1 });
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Creates a model node (element or text) based on provided JSON.
|
|
349
|
+
*/
|
|
350
|
+
_createNode(writer, jsonNode) {
|
|
351
|
+
if ('name' in jsonNode) {
|
|
352
|
+
// If child has name property, it is an Element.
|
|
353
|
+
const element = writer.createElement(jsonNode.name, jsonNode.attributes);
|
|
354
|
+
if (jsonNode.children) {
|
|
355
|
+
for (const child of jsonNode.children) {
|
|
356
|
+
element._appendChild(this._createNode(writer, child));
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
return element;
|
|
360
|
+
}
|
|
361
|
+
else {
|
|
362
|
+
// Otherwise, it is a Text node.
|
|
363
|
+
return writer.createText(jsonNode.data, jsonNode.attributes);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Restores the editor by setting the document data, roots attributes and markers.
|
|
368
|
+
*/
|
|
369
|
+
_restoreEditorData(writer) {
|
|
370
|
+
const editor = this.editor;
|
|
371
|
+
Object.entries(this._data.roots).forEach(([rootName, { content, attributes }]) => {
|
|
372
|
+
const parsedNodes = JSON.parse(content);
|
|
373
|
+
const parsedAttributes = JSON.parse(attributes);
|
|
374
|
+
const rootElement = editor.model.document.getRoot(rootName);
|
|
375
|
+
for (const [key, value] of parsedAttributes) {
|
|
376
|
+
writer.setAttribute(key, value, rootElement);
|
|
377
|
+
}
|
|
378
|
+
for (const child of parsedNodes) {
|
|
379
|
+
const node = this._createNode(writer, child);
|
|
380
|
+
writer.insert(node, rootElement, 'end');
|
|
381
|
+
}
|
|
382
|
+
});
|
|
383
|
+
Object.entries(this._data.markers).forEach(([markerName, markerOptions]) => {
|
|
384
|
+
const { document } = editor.model;
|
|
385
|
+
const { rangeJSON: { start, end }, ...options } = markerOptions;
|
|
386
|
+
const root = document.getRoot(start.root);
|
|
387
|
+
const startPosition = writer.createPositionFromPath(root, start.path, start.stickiness);
|
|
388
|
+
const endPosition = writer.createPositionFromPath(root, end.path, end.stickiness);
|
|
389
|
+
const range = writer.createRange(startPosition, endPosition);
|
|
390
|
+
writer.addMarker(markerName, {
|
|
391
|
+
range,
|
|
392
|
+
...options
|
|
393
|
+
});
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Restores the editor collaboration data - comment threads and suggestions.
|
|
398
|
+
*/
|
|
399
|
+
_restoreCollaborationData() {
|
|
400
|
+
// `as any` to avoid linking from external private repo.
|
|
401
|
+
const parsedCommentThreads = JSON.parse(this._data.commentThreads);
|
|
402
|
+
const parsedSuggestions = JSON.parse(this._data.suggestions);
|
|
403
|
+
parsedCommentThreads.forEach(commentThreadData => {
|
|
404
|
+
const channelId = this.editor.config.get('collaboration.channelId');
|
|
405
|
+
const commentsRepository = this.editor.plugins.get('CommentsRepository');
|
|
406
|
+
if (commentsRepository.hasCommentThread(commentThreadData.threadId)) {
|
|
407
|
+
const commentThread = commentsRepository.getCommentThread(commentThreadData.threadId);
|
|
408
|
+
commentThread.remove();
|
|
409
|
+
}
|
|
410
|
+
commentsRepository.addCommentThread({ channelId, ...commentThreadData });
|
|
411
|
+
});
|
|
412
|
+
parsedSuggestions.forEach(suggestionData => {
|
|
413
|
+
const trackChangesEditing = this.editor.plugins.get('TrackChangesEditing');
|
|
414
|
+
if (trackChangesEditing.hasSuggestion(suggestionData.id)) {
|
|
415
|
+
const suggestion = trackChangesEditing.getSuggestion(suggestionData.id);
|
|
416
|
+
suggestion.attributes = suggestionData.attributes;
|
|
417
|
+
}
|
|
418
|
+
else {
|
|
419
|
+
trackChangesEditing.addSuggestionData(suggestionData);
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
}
|
package/src/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
/**
|
|
6
6
|
* @module watchdog
|
|
7
7
|
*/
|
|
8
|
-
export { default as ContextWatchdog } from './contextwatchdog
|
|
9
|
-
export { default as EditorWatchdog } from './editorwatchdog
|
|
10
|
-
export { default as Watchdog } from './watchdog
|
|
8
|
+
export { default as ContextWatchdog } from './contextwatchdog';
|
|
9
|
+
export { default as EditorWatchdog } from './editorwatchdog';
|
|
10
|
+
export { default as Watchdog } from './watchdog';
|
|
11
|
+
import './augmentation';
|
package/src/index.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
/**
|
|
6
6
|
* @module watchdog
|
|
7
7
|
*/
|
|
8
|
-
export { default as ContextWatchdog } from './contextwatchdog
|
|
9
|
-
export { default as EditorWatchdog } from './editorwatchdog
|
|
10
|
-
export { default as Watchdog } from './watchdog
|
|
8
|
+
export { default as ContextWatchdog } from './contextwatchdog';
|
|
9
|
+
export { default as EditorWatchdog } from './editorwatchdog';
|
|
10
|
+
export { default as Watchdog } from './watchdog';
|
|
11
|
+
import './augmentation';
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* @module watchdog/utils/areconnectedthroughproperties
|
|
7
7
|
*/
|
|
8
8
|
/* globals console */
|
|
9
|
-
import getSubNodes from './getsubnodes
|
|
9
|
+
import getSubNodes from './getsubnodes';
|
|
10
10
|
/**
|
|
11
11
|
* Traverses both structures to find out whether there is a reference that is shared between both structures.
|
|
12
12
|
*/
|
package/src/watchdog.d.ts
CHANGED
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
/**
|
|
6
6
|
* @module watchdog/watchdog
|
|
7
7
|
*/
|
|
8
|
-
import type { CKEditorError } from 'ckeditor5/src/utils
|
|
9
|
-
import type { EditorWatchdogRestartEvent } from './editorwatchdog
|
|
10
|
-
import type { ContextWatchdogItemErrorEvent, ContextWatchdogItemRestartEvent } from './contextwatchdog
|
|
8
|
+
import type { CKEditorError } from 'ckeditor5/src/utils';
|
|
9
|
+
import type { EditorWatchdogRestartEvent } from './editorwatchdog';
|
|
10
|
+
import type { ContextWatchdogItemErrorEvent, ContextWatchdogItemRestartEvent } from './contextwatchdog';
|
|
11
11
|
/**
|
|
12
12
|
* An abstract watchdog class that handles most of the error handling process and the state of the underlying component.
|
|
13
13
|
*
|