@lobehub/editor 1.32.0 → 1.33.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.
Files changed (38) hide show
  1. package/es/editor-kernel/kernel.d.ts +4 -4
  2. package/es/editor-kernel/kernel.js +6 -2
  3. package/es/editor-kernel/react/PortalContainer.d.ts +11 -0
  4. package/es/editor-kernel/react/PortalContainer.js +32 -0
  5. package/es/editor-kernel/react/index.d.ts +1 -0
  6. package/es/editor-kernel/react/index.js +1 -0
  7. package/es/editor-kernel/react/useDecorators.js +3 -2
  8. package/es/editor-kernel/utils.d.ts +7 -1
  9. package/es/editor-kernel/utils.js +34 -0
  10. package/es/locale/index.d.ts +4 -0
  11. package/es/locale/index.js +4 -0
  12. package/es/plugins/file/node/FileNode.js +12 -2
  13. package/es/plugins/hr/node/HorizontalRuleNode.js +12 -2
  14. package/es/plugins/link/node/LinkNode.js +2 -0
  15. package/es/plugins/link-highlight/node/link-highlight.js +1 -0
  16. package/es/plugins/litexml/command/diffCommand.d.ts +10 -0
  17. package/es/plugins/litexml/command/diffCommand.js +47 -0
  18. package/es/plugins/litexml/command/index.d.ts +19 -0
  19. package/es/plugins/litexml/command/index.js +286 -45
  20. package/es/plugins/litexml/index.d.ts +1 -1
  21. package/es/plugins/litexml/index.js +1 -1
  22. package/es/plugins/litexml/node/DiffNode.d.ts +26 -0
  23. package/es/plugins/litexml/node/DiffNode.js +164 -0
  24. package/es/plugins/litexml/plugin/index.d.ts +4 -0
  25. package/es/plugins/litexml/plugin/index.js +20 -3
  26. package/es/plugins/litexml/react/DiffNodeToolbar/index.d.ts +10 -0
  27. package/es/plugins/litexml/react/DiffNodeToolbar/index.js +62 -0
  28. package/es/plugins/litexml/react/DiffNodeToolbar/style.d.ts +5 -0
  29. package/es/plugins/litexml/react/DiffNodeToolbar/style.js +13 -0
  30. package/es/plugins/litexml/react/index.js +14 -1
  31. package/es/plugins/litexml/react/style.d.ts +1 -0
  32. package/es/plugins/litexml/react/style.js +8 -0
  33. package/es/plugins/litexml/utils/index.d.ts +1 -0
  34. package/es/plugins/litexml/utils/index.js +34 -0
  35. package/es/plugins/math/node/index.js +24 -4
  36. package/es/plugins/mention/node/MentionNode.js +12 -2
  37. package/es/types/kernel.d.ts +8 -3
  38. package/package.json +1 -1
@@ -1,8 +1,8 @@
1
1
  import { HistoryState } from '@lexical/history';
2
2
  import EventEmitter from 'eventemitter3';
3
- import { CommandListener, CommandListenerPriority, CommandPayloadType, DecoratorNode, LexicalCommand, LexicalEditor, LexicalNodeConfig } from 'lexical';
3
+ import { CommandListener, CommandListenerPriority, CommandPayloadType, LexicalCommand, LexicalEditor, LexicalNodeConfig } from 'lexical';
4
4
  import { HotkeyId } from "../types/hotkey";
5
- import { IEditor, IEditorKernel, IEditorPluginConstructor, IPlugin, IServiceID } from "../types/kernel";
5
+ import { IDecorator, IEditor, IEditorKernel, IEditorPluginConstructor, IPlugin, IServiceID } from "../types/kernel";
6
6
  import { ILocaleKeys } from "../types/locale";
7
7
  import { HotkeyOptions, HotkeysEvent } from "../utils/hotkey/registerHotkey";
8
8
  import DataSource from './data-source';
@@ -45,8 +45,8 @@ export declare class Kernel extends EventEmitter implements IEditorKernel {
45
45
  blur(): void;
46
46
  getDocument(type: string): DataSource | undefined;
47
47
  getSelectionDocument(type: string): unknown | null;
48
- registerDecorator(name: string, decorator: (_node: DecoratorNode<any>, _editor: LexicalEditor) => any): this;
49
- getDecorator(name: string): ((_node: DecoratorNode<any>, _editor: LexicalEditor) => any) | undefined;
48
+ registerDecorator(name: string, decorator: IDecorator): this;
49
+ getDecorator(name: string): IDecorator | undefined;
50
50
  /**
51
51
  * Unregister a decorator
52
52
  * @param name Decorator name
@@ -29,7 +29,7 @@ import { createDebugLogger } from "../utils/debug";
29
29
  import { getHotkeyById, registerHotkey as _registerHotkey } from "../utils/hotkey/registerHotkey";
30
30
  import { registerEvent } from "./event";
31
31
  import { KernelPlugin } from "./plugin";
32
- import { createEmptyEditorState, noop } from "./utils";
32
+ import { EDITOR_THEME_KEY, createEmptyEditorState, generateEditorId, noop, registerEditorKernel, unregisterEditorKernel } from "./utils";
33
33
  templateSettings.interpolate = /{{([\S\s]+?)}}/g;
34
34
  export var Kernel = /*#__PURE__*/function (_EventEmitter) {
35
35
  _inherits(Kernel, _EventEmitter);
@@ -43,7 +43,7 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
43
43
  _defineProperty(_assertThisInitialized(_this), "pluginsConfig", new Map());
44
44
  _defineProperty(_assertThisInitialized(_this), "pluginsInstances", []);
45
45
  _defineProperty(_assertThisInitialized(_this), "nodes", []);
46
- _defineProperty(_assertThisInitialized(_this), "themes", {});
46
+ _defineProperty(_assertThisInitialized(_this), "themes", _defineProperty({}, EDITOR_THEME_KEY, generateEditorId()));
47
47
  // Used to store theme configuration
48
48
  _defineProperty(_assertThisInitialized(_this), "decorators", {});
49
49
  _defineProperty(_assertThisInitialized(_this), "serviceMap", new Map());
@@ -127,6 +127,7 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
127
127
  key: "destroy",
128
128
  value: function destroy() {
129
129
  var _this$editor2;
130
+ unregisterEditorKernel(this.themes[EDITOR_THEME_KEY]);
130
131
  this.logger.info("\uD83D\uDDD1\uFE0F Destroying editor with ".concat(this.pluginsInstances.length, " plugins"));
131
132
  (_this$editor2 = this.editor) === null || _this$editor2 === void 0 || _this$editor2.setEditorState(createEmptyEditorState());
132
133
  this.dataTypeMap.clear();
@@ -140,6 +141,8 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
140
141
  this.serviceMap.clear();
141
142
  // Clear decorators to prevent memory leaks
142
143
  this.decorators = {};
144
+ // Clear themes
145
+ this.themes = {};
143
146
  this.logger.info('✅ Editor destroyed');
144
147
  }
145
148
  }, {
@@ -178,6 +181,7 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
178
181
  }
179
182
  }
180
183
  this.logger.info("\uD83D\uDCDD Creating editor with ".concat(this.nodes.length, " nodes"));
184
+ registerEditorKernel(this.themes[EDITOR_THEME_KEY], this);
181
185
  var editor = this.editor = createEditor({
182
186
  // @ts-expect-error Inject into lexical editor instance
183
187
  __kernel: this,
@@ -0,0 +1,11 @@
1
+ import { LexicalEditor, LexicalNode } from 'lexical';
2
+ import React from 'react';
3
+ export interface PortalContainerProps {
4
+ children: React.ReactNode;
5
+ className?: string;
6
+ editor: LexicalEditor;
7
+ node: LexicalNode;
8
+ style?: React.CSSProperties;
9
+ }
10
+ export declare const LexicalPortalContainer: React.ForwardRefExoticComponent<PortalContainerProps & React.RefAttributes<HTMLDivElement | null>>;
11
+ export default LexicalPortalContainer;
@@ -0,0 +1,32 @@
1
+ import React, { forwardRef, useEffect, useImperativeHandle, useRef } from 'react';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ export var LexicalPortalContainer = /*#__PURE__*/forwardRef(function (_ref, ref) {
4
+ var editor = _ref.editor,
5
+ node = _ref.node,
6
+ children = _ref.children;
7
+ var divRef = useRef(null);
8
+ useImperativeHandle(ref, function () {
9
+ return divRef.current;
10
+ }, []);
11
+ useEffect(function () {
12
+ return function () {
13
+ if (divRef.current) {
14
+ // @ts-expect-error not error
15
+ delete divRef.current["__lexicalKey_".concat(editor._key)];
16
+ }
17
+ };
18
+ }, [editor, node]);
19
+ return /*#__PURE__*/_jsx("div", {
20
+ ref: function ref(dom) {
21
+ divRef.current = dom;
22
+ if (dom) {
23
+ var prop = "__lexicalKey_".concat(editor._key);
24
+ // @ts-expect-error not error
25
+ dom[prop] = node.getKey();
26
+ }
27
+ },
28
+ children: children
29
+ });
30
+ });
31
+ LexicalPortalContainer.displayName = 'LexicalPortalContainer';
32
+ export default LexicalPortalContainer;
@@ -1,4 +1,5 @@
1
1
  export { LexicalErrorBoundary } from './LexicalErrorBoundary';
2
+ export { LexicalPortalContainer } from './PortalContainer';
2
3
  export { useLexicalComposerContext } from './react-context';
3
4
  export { ReactEditor } from './react-editor';
4
5
  export { useLexicalEditor } from './useLexicalEditor';
@@ -1,4 +1,5 @@
1
1
  export { LexicalErrorBoundary } from "./LexicalErrorBoundary";
2
+ export { LexicalPortalContainer } from "./PortalContainer";
2
3
  export { useLexicalComposerContext } from "./react-context";
3
4
  export { ReactEditor } from "./react-editor";
4
5
  export { useLexicalEditor } from "./useLexicalEditor";
@@ -59,6 +59,7 @@ export function useDecorators(editor, ErrorBoundary) {
59
59
  for (var _i = 0, _decoratorKeys = decoratorKeys; _i < _decoratorKeys.length; _i++) {
60
60
  var _editor$getLexicalEdi3;
61
61
  var nodeKey = _decoratorKeys[_i];
62
+ var decorator = decorators[nodeKey];
62
63
  var reactDecorator = /*#__PURE__*/_jsx(ErrorBoundary, {
63
64
  onError: function onError(e) {
64
65
  var _editor$getLexicalEdi2;
@@ -66,12 +67,12 @@ export function useDecorators(editor, ErrorBoundary) {
66
67
  },
67
68
  children: /*#__PURE__*/_jsx(Suspense, {
68
69
  fallback: null,
69
- children: decorators[nodeKey]
70
+ children: 'render' in decorator ? decorator.render : decorator
70
71
  })
71
72
  });
72
73
  var element = (_editor$getLexicalEdi3 = editor.getLexicalEditor()) === null || _editor$getLexicalEdi3 === void 0 ? void 0 : _editor$getLexicalEdi3.getElementByKey(nodeKey);
73
74
  if (element !== null && element !== undefined) {
74
- decoratedPortals.push( /*#__PURE__*/createPortal(reactDecorator, element, nodeKey));
75
+ decoratedPortals.push( /*#__PURE__*/createPortal(reactDecorator, 'queryDOM' in decorator ? decorator.queryDOM(element) : element, nodeKey));
75
76
  }
76
77
  }
77
78
  return decoratedPortals;
@@ -1,4 +1,4 @@
1
- import { ElementNode, LexicalEditor, LexicalNode, NodeKey } from 'lexical';
1
+ import { EditorConfig, ElementNode, LexicalEditor, LexicalNode, NodeKey } from 'lexical';
2
2
  import type { IEditorKernel, IServiceID } from "../types";
3
3
  export declare const DOM_ELEMENT_TYPE = 1;
4
4
  export declare const DOM_TEXT_TYPE = 3;
@@ -23,6 +23,11 @@ export declare function isDocumentFragment(x: unknown): x is DocumentFragment;
23
23
  export declare function getParentElement(node: Node): HTMLElement | null;
24
24
  export declare function $getNearestNodeFromDOMNode(startingDOM: Node, editor: LexicalEditor, editorState?: ReturnType<LexicalEditor['getEditorState']>): LexicalNode | null;
25
25
  export declare function getKernelFromEditor(editor: LexicalEditor): IEditorKernel;
26
+ export declare const EDITOR_THEME_KEY = "__editorId";
27
+ export declare function generateEditorId(): string;
28
+ export declare function registerEditorKernel(id: string, kernel: IEditorKernel): void;
29
+ export declare function unregisterEditorKernel(id: string): void;
30
+ export declare function getKernelFromEditorConfig(config: EditorConfig): IEditorKernel | null;
26
31
  /**
27
32
  *
28
33
  * @param nodeA
@@ -33,3 +38,4 @@ export declare function compareNodeOrder(nodeA: LexicalNode, nodeB: LexicalNode)
33
38
  export declare function $closest(node: LexicalNode | ElementNode | null, test: (node: LexicalNode) => boolean): LexicalNode | null;
34
39
  export declare function $closestNodeType(node: LexicalNode | ElementNode | null, type: string | string[]): LexicalNode | null;
35
40
  export declare function moment(): Promise<unknown>;
41
+ export declare function reconcileDecorator(activeEditor: LexicalEditor, key: NodeKey, decorator: unknown): void;
@@ -69,6 +69,23 @@ export function getKernelFromEditor(editor) {
69
69
  // @ts-expect-error __kernel is injected into the lexical editor instance
70
70
  return ((_editor$_createEditor = editor._createEditorArgs) === null || _editor$_createEditor === void 0 ? void 0 : _editor$_createEditor.__kernel) || editor._kernel;
71
71
  }
72
+ var EditorId = 0;
73
+ export var EDITOR_THEME_KEY = '__editorId';
74
+ export function generateEditorId() {
75
+ EditorId += 1;
76
+ return "editor-".concat(EditorId);
77
+ }
78
+ var EditorMap = new Map();
79
+ export function registerEditorKernel(id, kernel) {
80
+ EditorMap.set(id, kernel);
81
+ }
82
+ export function unregisterEditorKernel(id) {
83
+ EditorMap.delete(id);
84
+ }
85
+ export function getKernelFromEditorConfig(config) {
86
+ var id = config.theme[EDITOR_THEME_KEY];
87
+ return EditorMap.get(id) || null;
88
+ }
72
89
 
73
90
  /**
74
91
  *
@@ -130,4 +147,21 @@ export function moment() {
130
147
  return resolve(true);
131
148
  });
132
149
  });
150
+ }
151
+ function cloneDecorators(editor) {
152
+ var currentDecorators = editor._decorators;
153
+ var pendingDecorators = Object.assign({}, currentDecorators);
154
+ editor._pendingDecorators = pendingDecorators;
155
+ return pendingDecorators;
156
+ }
157
+ export function reconcileDecorator(activeEditor, key, decorator) {
158
+ var pendingDecorators = activeEditor._pendingDecorators;
159
+ var currentDecorators = activeEditor._decorators;
160
+ if (pendingDecorators === null) {
161
+ if (currentDecorators[key] === decorator) {
162
+ return;
163
+ }
164
+ pendingDecorators = cloneDecorators(activeEditor);
165
+ }
166
+ pendingDecorators[key] = decorator;
133
167
  }
@@ -25,6 +25,10 @@ declare const _default: {
25
25
  math: {
26
26
  placeholder: string;
27
27
  };
28
+ modifier: {
29
+ accept: string;
30
+ reject: string;
31
+ };
28
32
  table: {
29
33
  delete: string;
30
34
  deleteColumn: string;
@@ -25,6 +25,10 @@ export default {
25
25
  math: {
26
26
  placeholder: 'Enter TeX formula'
27
27
  },
28
+ modifier: {
29
+ accept: 'Accept',
30
+ reject: 'Reject'
31
+ },
28
32
  table: {
29
33
  delete: 'Delete table',
30
34
  deleteColumn: 'Delete column',
@@ -123,8 +123,18 @@ export var FileNode = /*#__PURE__*/function (_DecoratorNode) {
123
123
  }, {
124
124
  key: "decorate",
125
125
  value: function decorate(editor) {
126
- var _getKernelFromEditor, _getKernelFromEditor$;
127
- return ((_getKernelFromEditor = getKernelFromEditor(editor)) === null || _getKernelFromEditor === void 0 || (_getKernelFromEditor$ = _getKernelFromEditor.getDecorator('file')) === null || _getKernelFromEditor$ === void 0 ? void 0 : _getKernelFromEditor$(this, editor)) || null;
126
+ var _getKernelFromEditor;
127
+ var decorator = (_getKernelFromEditor = getKernelFromEditor(editor)) === null || _getKernelFromEditor === void 0 ? void 0 : _getKernelFromEditor.getDecorator('file');
128
+ if (!decorator) {
129
+ return null;
130
+ }
131
+ if (typeof decorator === 'function') {
132
+ return decorator(this, editor);
133
+ }
134
+ return {
135
+ queryDOM: decorator.queryDOM,
136
+ render: decorator.render(this, editor)
137
+ };
128
138
  }
129
139
  }], [{
130
140
  key: "getType",
@@ -54,8 +54,18 @@ export var HorizontalRuleNode = /*#__PURE__*/function (_DecoratorNode) {
54
54
  }, {
55
55
  key: "decorate",
56
56
  value: function decorate(editor) {
57
- var _getKernelFromEditor, _getKernelFromEditor$;
58
- return ((_getKernelFromEditor = getKernelFromEditor(editor)) === null || _getKernelFromEditor === void 0 || (_getKernelFromEditor$ = _getKernelFromEditor.getDecorator('horizontalrule')) === null || _getKernelFromEditor$ === void 0 ? void 0 : _getKernelFromEditor$(this, editor)) || null;
57
+ var _getKernelFromEditor;
58
+ var decorator = (_getKernelFromEditor = getKernelFromEditor(editor)) === null || _getKernelFromEditor === void 0 ? void 0 : _getKernelFromEditor.getDecorator('horizontalrule');
59
+ if (!decorator) {
60
+ return null;
61
+ }
62
+ if (typeof decorator === 'function') {
63
+ return decorator(this, editor);
64
+ }
65
+ return {
66
+ queryDOM: decorator.queryDOM,
67
+ render: decorator.render(this, editor)
68
+ };
59
69
  }
60
70
  }], [{
61
71
  key: "getType",
@@ -62,6 +62,7 @@ export var LinkNode = /*#__PURE__*/function (_ElementNode) {
62
62
  key: "createDOM",
63
63
  value: function createDOM(config, editor) {
64
64
  var _this2 = this;
65
+ console.info('config', config);
65
66
  var element = document.createElement('a');
66
67
  this.updateLinkDOM(null, element, config);
67
68
  addClassNamesToElement(element, config.theme.link);
@@ -356,6 +357,7 @@ export var AutoLinkNode = /*#__PURE__*/function (_LinkNode) {
356
357
  }, {
357
358
  key: "createDOM",
358
359
  value: function createDOM(config, editor) {
360
+ console.info('config', config);
359
361
  if (this.__isUnlinked) {
360
362
  return document.createElement('span');
361
363
  } else {
@@ -24,6 +24,7 @@ export var LinkHighlightNode = /*#__PURE__*/function (_ElementNode) {
24
24
  _createClass(LinkHighlightNode, [{
25
25
  key: "createDOM",
26
26
  value: function createDOM(config) {
27
+ console.info('config', config);
27
28
  var element = document.createElement('a');
28
29
 
29
30
  // Set link attributes
@@ -0,0 +1,10 @@
1
+ import { LexicalEditor } from 'lexical';
2
+ export declare enum DiffAction {
3
+ Reject = 0,
4
+ Accept = 1
5
+ }
6
+ export declare const LITEXML_DIFFNODE_COMMAND: import("lexical").LexicalCommand<{
7
+ action: DiffAction;
8
+ nodeKey: string;
9
+ }>;
10
+ export declare function registerLiteXMLDiffCommand(editor: LexicalEditor): () => void;
@@ -0,0 +1,47 @@
1
+ import { mergeRegister } from '@lexical/utils';
2
+ import { $getNodeByKey, COMMAND_PRIORITY_EDITOR, createCommand } from 'lexical';
3
+ export var DiffAction = /*#__PURE__*/function (DiffAction) {
4
+ DiffAction[DiffAction["Reject"] = 0] = "Reject";
5
+ DiffAction[DiffAction["Accept"] = 1] = "Accept";
6
+ return DiffAction;
7
+ }({});
8
+ export var LITEXML_DIFFNODE_COMMAND = createCommand('LITEXML_DIFFNODE_COMMAND');
9
+ export function registerLiteXMLDiffCommand(editor) {
10
+ return mergeRegister(editor.registerCommand(LITEXML_DIFFNODE_COMMAND, function (payload) {
11
+ var action = payload.action,
12
+ nodeKey = payload.nodeKey;
13
+ var node = editor.read(function () {
14
+ return $getNodeByKey(nodeKey);
15
+ });
16
+ if (!node) {
17
+ return false;
18
+ }
19
+ editor.update(function () {
20
+ if (node.diffType === 'modify') {
21
+ var children = node.getChildren();
22
+ if (action === DiffAction.Accept) {
23
+ node.replace(children[1], false).selectEnd();
24
+ } else if (action === DiffAction.Reject) {
25
+ node.replace(children[0], false).selectEnd();
26
+ }
27
+ }
28
+ if (node.diffType === 'remove') {
29
+ if (action === DiffAction.Accept) {
30
+ node.remove();
31
+ } else if (action === DiffAction.Reject) {
32
+ var _children = node.getChildren();
33
+ node.replace(_children[0], false).selectEnd();
34
+ }
35
+ }
36
+ if (node.diffType === 'add') {
37
+ if (action === DiffAction.Accept) {
38
+ var _children2 = node.getChildren();
39
+ node.replace(_children2[0], false).selectEnd();
40
+ } else if (action === DiffAction.Reject) {
41
+ node.remove();
42
+ }
43
+ }
44
+ });
45
+ return false;
46
+ }, COMMAND_PRIORITY_EDITOR));
47
+ }
@@ -1,16 +1,35 @@
1
1
  import { LexicalEditor } from 'lexical';
2
2
  import type LitexmlDataSource from '../data-source/litexml-data-source';
3
+ export declare const LITEXML_MODIFY_COMMAND: import("lexical").LexicalCommand<({
4
+ action: 'insert';
5
+ beforeId: string;
6
+ litexml: string;
7
+ } | {
8
+ action: 'insert';
9
+ afterId: string;
10
+ litexml: string;
11
+ } | {
12
+ action: 'remove';
13
+ id: string;
14
+ } | {
15
+ action: 'modify';
16
+ litexml: string | string[];
17
+ })[]>;
3
18
  export declare const LITEXML_APPLY_COMMAND: import("lexical").LexicalCommand<{
19
+ delay?: boolean | undefined;
4
20
  litexml: string | string[];
5
21
  }>;
6
22
  export declare const LITEXML_REMOVE_COMMAND: import("lexical").LexicalCommand<{
23
+ delay?: boolean | undefined;
7
24
  id: string;
8
25
  }>;
9
26
  export declare const LITEXML_INSERT_COMMAND: import("lexical").LexicalCommand<{
10
27
  beforeId: string;
28
+ delay?: boolean | undefined;
11
29
  litexml: string;
12
30
  } | {
13
31
  afterId: string;
32
+ delay?: boolean | undefined;
14
33
  litexml: string;
15
34
  }>;
16
35
  export declare function registerLiteXMLCommand(editor: LexicalEditor, dataSource: LitexmlDataSource): () => void;