@lobehub/editor 1.5.1 → 1.5.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/es/editor-kernel/kernel.d.ts +9 -0
- package/es/editor-kernel/kernel.js +79 -12
- package/es/editor-kernel/plugin.d.ts +14 -0
- package/es/editor-kernel/plugin.js +36 -0
- package/es/plugins/file/plugin/index.js +1 -1
- package/es/plugins/hr/plugin/index.js +1 -1
- package/es/plugins/math/plugin/index.js +2 -2
- package/es/plugins/mention/plugin/index.js +1 -1
- package/es/types/kernel.d.ts +9 -0
- package/package.json +1 -1
|
@@ -37,6 +37,15 @@ export declare class Kernel extends EventEmitter implements IEditorKernel {
|
|
|
37
37
|
getSelectionDocument(type: string): unknown | null;
|
|
38
38
|
registerDecorator(name: string, decorator: (_node: DecoratorNode<any>, _editor: LexicalEditor) => any): this;
|
|
39
39
|
getDecorator(name: string): ((_node: DecoratorNode<any>, _editor: LexicalEditor) => any) | undefined;
|
|
40
|
+
/**
|
|
41
|
+
* Unregister a decorator
|
|
42
|
+
* @param name Decorator name
|
|
43
|
+
*/
|
|
44
|
+
unregisterDecorator(name: string): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Get all registered decorator names
|
|
47
|
+
*/
|
|
48
|
+
getRegisteredDecorators(): string[];
|
|
40
49
|
/**
|
|
41
50
|
* Support registering target data source
|
|
42
51
|
* @param dataSource Data source
|
|
@@ -25,6 +25,7 @@ import { get, merge, template, templateSettings } from 'lodash-es';
|
|
|
25
25
|
import defaultLocale from "../locale";
|
|
26
26
|
import { $isRootTextContentEmpty } from "../plugins/common/utils";
|
|
27
27
|
import { registerEvent } from "./event";
|
|
28
|
+
import { KernelPlugin } from "./plugin";
|
|
28
29
|
import { createEmptyEditorState } from "./utils";
|
|
29
30
|
templateSettings.interpolate = /{{([\S\s]+?)}}/g;
|
|
30
31
|
export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
@@ -118,6 +119,9 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
|
118
119
|
this.pluginsInstances = [];
|
|
119
120
|
// Clear services to support hot reload
|
|
120
121
|
this.serviceMap.clear();
|
|
122
|
+
// Clear decorators to prevent memory leaks
|
|
123
|
+
this.decorators = {};
|
|
124
|
+
console.debug('[Editor] Cleared all decorators during destroy');
|
|
121
125
|
}
|
|
122
126
|
}, {
|
|
123
127
|
key: "getRootElement",
|
|
@@ -224,7 +228,28 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
|
224
228
|
}, {
|
|
225
229
|
key: "registerDecorator",
|
|
226
230
|
value: function registerDecorator(name, decorator) {
|
|
231
|
+
if (this.decorators[name]) {
|
|
232
|
+
if (this.hotReloadMode) {
|
|
233
|
+
// In hot reload mode, allow decorator override with warning
|
|
234
|
+
console.warn("[Hot Reload] Overriding decorator \"".concat(name, "\""));
|
|
235
|
+
this.decorators[name] = decorator;
|
|
236
|
+
return this;
|
|
237
|
+
} else {
|
|
238
|
+
// Check if it's the same decorator function
|
|
239
|
+
var existingDecorator = this.decorators[name];
|
|
240
|
+
if (existingDecorator === decorator) {
|
|
241
|
+
// Same decorator function, no need to re-register
|
|
242
|
+
console.warn("[Editor] Decorator \"".concat(name, "\" is already registered with the same function"));
|
|
243
|
+
return this;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// Different decorator function in production mode
|
|
247
|
+
console.error("[Editor] Attempting to register duplicate decorator \"".concat(name, "\". Enable hot reload mode if this is intended."));
|
|
248
|
+
throw new Error("Decorator with name \"".concat(name, "\" is already registered."));
|
|
249
|
+
}
|
|
250
|
+
}
|
|
227
251
|
this.decorators[name] = decorator;
|
|
252
|
+
console.debug("[Editor] Registered decorator: ".concat(name));
|
|
228
253
|
return this;
|
|
229
254
|
}
|
|
230
255
|
}, {
|
|
@@ -233,6 +258,31 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
|
233
258
|
return this.decorators[name];
|
|
234
259
|
}
|
|
235
260
|
|
|
261
|
+
/**
|
|
262
|
+
* Unregister a decorator
|
|
263
|
+
* @param name Decorator name
|
|
264
|
+
*/
|
|
265
|
+
}, {
|
|
266
|
+
key: "unregisterDecorator",
|
|
267
|
+
value: function unregisterDecorator(name) {
|
|
268
|
+
if (this.decorators[name]) {
|
|
269
|
+
delete this.decorators[name];
|
|
270
|
+
console.debug("[Editor] Unregistered decorator: ".concat(name));
|
|
271
|
+
return true;
|
|
272
|
+
}
|
|
273
|
+
console.warn("[Editor] Decorator \"".concat(name, "\" not found for unregistration"));
|
|
274
|
+
return false;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Get all registered decorator names
|
|
279
|
+
*/
|
|
280
|
+
}, {
|
|
281
|
+
key: "getRegisteredDecorators",
|
|
282
|
+
value: function getRegisteredDecorators() {
|
|
283
|
+
return Object.keys(this.decorators);
|
|
284
|
+
}
|
|
285
|
+
|
|
236
286
|
/**
|
|
237
287
|
* Support registering target data source
|
|
238
288
|
* @param dataSource Data source
|
|
@@ -270,6 +320,23 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
|
270
320
|
});
|
|
271
321
|
if (instanceIndex !== -1) {
|
|
272
322
|
var oldInstance = this.pluginsInstances[instanceIndex];
|
|
323
|
+
// Clean up decorators registered by the old plugin instance
|
|
324
|
+
if (oldInstance instanceof KernelPlugin) {
|
|
325
|
+
var decoratorNames = oldInstance.getRegisteredDecorators();
|
|
326
|
+
var _iterator2 = _createForOfIteratorHelper(decoratorNames),
|
|
327
|
+
_step2;
|
|
328
|
+
try {
|
|
329
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
330
|
+
var decoratorName = _step2.value;
|
|
331
|
+
this.unregisterDecorator(decoratorName);
|
|
332
|
+
console.debug("[Hot Reload] Cleaned up decorator \"".concat(decoratorName, "\" from old plugin instance"));
|
|
333
|
+
}
|
|
334
|
+
} catch (err) {
|
|
335
|
+
_iterator2.e(err);
|
|
336
|
+
} finally {
|
|
337
|
+
_iterator2.f();
|
|
338
|
+
}
|
|
339
|
+
}
|
|
273
340
|
if (oldInstance.destroy) {
|
|
274
341
|
oldInstance.destroy();
|
|
275
342
|
}
|
|
@@ -297,11 +364,11 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
|
297
364
|
}, {
|
|
298
365
|
key: "registerPlugins",
|
|
299
366
|
value: function registerPlugins(plugins) {
|
|
300
|
-
var
|
|
301
|
-
|
|
367
|
+
var _iterator3 = _createForOfIteratorHelper(plugins),
|
|
368
|
+
_step3;
|
|
302
369
|
try {
|
|
303
|
-
for (
|
|
304
|
-
var plugin =
|
|
370
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
371
|
+
var plugin = _step3.value;
|
|
305
372
|
if (Array.isArray(plugin)) {
|
|
306
373
|
this.registerPlugin(plugin[0], plugin[1]);
|
|
307
374
|
} else {
|
|
@@ -309,9 +376,9 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
|
309
376
|
}
|
|
310
377
|
}
|
|
311
378
|
} catch (err) {
|
|
312
|
-
|
|
379
|
+
_iterator3.e(err);
|
|
313
380
|
} finally {
|
|
314
|
-
|
|
381
|
+
_iterator3.f();
|
|
315
382
|
}
|
|
316
383
|
return this;
|
|
317
384
|
}
|
|
@@ -471,19 +538,19 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
|
471
538
|
var listenerInPriorityOrder = _this4._commands.get(command);
|
|
472
539
|
if (listenerInPriorityOrder !== undefined) {
|
|
473
540
|
var listenersSet = listenerInPriorityOrder[i];
|
|
474
|
-
var
|
|
475
|
-
|
|
541
|
+
var _iterator4 = _createForOfIteratorHelper(listenersSet),
|
|
542
|
+
_step4;
|
|
476
543
|
try {
|
|
477
|
-
for (
|
|
478
|
-
var _listener =
|
|
544
|
+
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
545
|
+
var _listener = _step4.value;
|
|
479
546
|
if (_listener(payload, lexicalEditor)) {
|
|
480
547
|
return true;
|
|
481
548
|
}
|
|
482
549
|
}
|
|
483
550
|
} catch (err) {
|
|
484
|
-
|
|
551
|
+
_iterator4.e(err);
|
|
485
552
|
} finally {
|
|
486
|
-
|
|
553
|
+
_iterator4.f();
|
|
487
554
|
}
|
|
488
555
|
}
|
|
489
556
|
}
|
|
@@ -1,7 +1,21 @@
|
|
|
1
1
|
import EventEmitter from 'eventemitter3';
|
|
2
|
+
import type { IEditorKernel } from "../types/kernel";
|
|
2
3
|
export declare abstract class KernelPlugin extends EventEmitter {
|
|
3
4
|
protected clears: Array<() => void>;
|
|
5
|
+
protected registeredDecorators: Set<string>;
|
|
4
6
|
protected register(clear: () => void): void;
|
|
5
7
|
protected registerClears(...clears: Array<() => void>): void;
|
|
8
|
+
/**
|
|
9
|
+
* Register a decorator and track it for cleanup
|
|
10
|
+
*/
|
|
11
|
+
protected registerDecorator(kernel: IEditorKernel, name: string, decorator: (node: any, editor: any) => any): void;
|
|
12
|
+
/**
|
|
13
|
+
* Unregister a specific decorator
|
|
14
|
+
*/
|
|
15
|
+
protected unregisterDecorator(kernel: IEditorKernel, name: string): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Get all decorator names registered by this plugin
|
|
18
|
+
*/
|
|
19
|
+
getRegisteredDecorators(): string[];
|
|
6
20
|
destroy(): void;
|
|
7
21
|
}
|
|
@@ -24,6 +24,7 @@ export var KernelPlugin = /*#__PURE__*/function (_EventEmitter) {
|
|
|
24
24
|
}
|
|
25
25
|
_this = _super.call.apply(_super, [this].concat(args));
|
|
26
26
|
_defineProperty(_assertThisInitialized(_this), "clears", []);
|
|
27
|
+
_defineProperty(_assertThisInitialized(_this), "registeredDecorators", new Set());
|
|
27
28
|
return _this;
|
|
28
29
|
}
|
|
29
30
|
_createClass(KernelPlugin, [{
|
|
@@ -42,12 +43,47 @@ export var KernelPlugin = /*#__PURE__*/function (_EventEmitter) {
|
|
|
42
43
|
return _this2.register(clear);
|
|
43
44
|
});
|
|
44
45
|
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Register a decorator and track it for cleanup
|
|
49
|
+
*/
|
|
50
|
+
}, {
|
|
51
|
+
key: "registerDecorator",
|
|
52
|
+
value: function registerDecorator(kernel, name, decorator) {
|
|
53
|
+
kernel.registerDecorator(name, decorator);
|
|
54
|
+
this.registeredDecorators.add(name);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Unregister a specific decorator
|
|
59
|
+
*/
|
|
60
|
+
}, {
|
|
61
|
+
key: "unregisterDecorator",
|
|
62
|
+
value: function unregisterDecorator(kernel, name) {
|
|
63
|
+
var result = kernel.unregisterDecorator(name);
|
|
64
|
+
if (result) {
|
|
65
|
+
this.registeredDecorators.delete(name);
|
|
66
|
+
}
|
|
67
|
+
return result;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Get all decorator names registered by this plugin
|
|
72
|
+
*/
|
|
73
|
+
}, {
|
|
74
|
+
key: "getRegisteredDecorators",
|
|
75
|
+
value: function getRegisteredDecorators() {
|
|
76
|
+
return Array.from(this.registeredDecorators);
|
|
77
|
+
}
|
|
45
78
|
}, {
|
|
46
79
|
key: "destroy",
|
|
47
80
|
value: function destroy() {
|
|
48
81
|
this.clears.forEach(function (clear) {
|
|
49
82
|
return clear();
|
|
50
83
|
});
|
|
84
|
+
// Note: Decorators will be cleaned up when kernel.destroy() is called
|
|
85
|
+
// Individual decorator cleanup should be handled by the kernel itself
|
|
86
|
+
this.registeredDecorators.clear();
|
|
51
87
|
}
|
|
52
88
|
}]);
|
|
53
89
|
return KernelPlugin;
|
|
@@ -42,7 +42,7 @@ export var FilePlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
|
42
42
|
if (config !== null && config !== void 0 && config.theme) {
|
|
43
43
|
kernel.registerThemes(config === null || config === void 0 ? void 0 : config.theme);
|
|
44
44
|
}
|
|
45
|
-
|
|
45
|
+
_this.registerDecorator(kernel, FileNode.getType(), function (node, editor) {
|
|
46
46
|
return config !== null && config !== void 0 && config.decorator ? config.decorator(node, editor) : null;
|
|
47
47
|
});
|
|
48
48
|
(_kernel$requireServic = kernel.requireService(IMarkdownShortCutService)) === null || _kernel$requireServic === void 0 || _kernel$requireServic.registerMarkdownWriter(FileNode.getType(), function (ctx, node) {
|
|
@@ -34,7 +34,7 @@ export var HRPlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
|
34
34
|
kernel.registerThemes({
|
|
35
35
|
hr: (config === null || config === void 0 ? void 0 : config.theme) || ''
|
|
36
36
|
});
|
|
37
|
-
|
|
37
|
+
_this.registerDecorator(kernel, 'horizontalrule', function (node, editor) {
|
|
38
38
|
return config !== null && config !== void 0 && config.decorator ? config.decorator(node, editor) : null;
|
|
39
39
|
});
|
|
40
40
|
(_kernel$requireServic = kernel.requireService(IMarkdownShortCutService)) === null || _kernel$requireServic === void 0 || _kernel$requireServic.registerMarkdownShortCut({
|
|
@@ -41,10 +41,10 @@ export var MathPlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
|
41
41
|
if (config !== null && config !== void 0 && config.theme) {
|
|
42
42
|
kernel.registerThemes(config === null || config === void 0 ? void 0 : config.theme);
|
|
43
43
|
}
|
|
44
|
-
|
|
44
|
+
_this.registerDecorator(kernel, MathInlineNode.getType(), function (node, editor) {
|
|
45
45
|
return config !== null && config !== void 0 && config.decorator ? config.decorator(node, editor) : null;
|
|
46
46
|
});
|
|
47
|
-
|
|
47
|
+
_this.registerDecorator(kernel, MathBlockNode.getType(), function (node, editor) {
|
|
48
48
|
return config !== null && config !== void 0 && config.decorator ? config.decorator(node, editor) : null;
|
|
49
49
|
});
|
|
50
50
|
(_kernel$requireServic = kernel.requireService(IMarkdownShortCutService)) === null || _kernel$requireServic === void 0 || _kernel$requireServic.registerMarkdownShortCut({
|
|
@@ -36,7 +36,7 @@ export var MentionPlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
|
36
36
|
if (config !== null && config !== void 0 && config.theme) {
|
|
37
37
|
kernel.registerThemes(config === null || config === void 0 ? void 0 : config.theme);
|
|
38
38
|
}
|
|
39
|
-
|
|
39
|
+
_this.registerDecorator(kernel, MentionNode.getType(), function (node, editor) {
|
|
40
40
|
return config !== null && config !== void 0 && config.decorator ? config.decorator(node, editor) : null;
|
|
41
41
|
});
|
|
42
42
|
(_kernel$requireServic = kernel.requireService(IMarkdownShortCutService)) === null || _kernel$requireServic === void 0 || _kernel$requireServic.registerMarkdownWriter(MentionNode.getType(), function (ctx, node) {
|
package/es/types/kernel.d.ts
CHANGED
|
@@ -171,6 +171,10 @@ export interface IEditorKernel extends IEditor {
|
|
|
171
171
|
* @param name
|
|
172
172
|
*/
|
|
173
173
|
getDecorator(name: string): ((_node: DecoratorNode<any>, _editor: LexicalEditor) => any) | undefined;
|
|
174
|
+
/**
|
|
175
|
+
* Get all registered decorator names
|
|
176
|
+
*/
|
|
177
|
+
getRegisteredDecorators(): string[];
|
|
174
178
|
/**
|
|
175
179
|
* Check if hot reload mode is enabled
|
|
176
180
|
*/
|
|
@@ -213,6 +217,11 @@ export interface IEditorKernel extends IEditor {
|
|
|
213
217
|
* @param enabled Whether to enable hot reload mode
|
|
214
218
|
*/
|
|
215
219
|
setHotReloadMode(enabled: boolean): void;
|
|
220
|
+
/**
|
|
221
|
+
* Unregister editor node decorator
|
|
222
|
+
* @param name Decorator name
|
|
223
|
+
*/
|
|
224
|
+
unregisterDecorator(name: string): boolean;
|
|
216
225
|
}
|
|
217
226
|
/**
|
|
218
227
|
* Plugin interface
|
package/package.json
CHANGED