@lobehub/editor 1.22.0 → 1.22.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/es/editor-kernel/kernel.d.ts +3 -0
- package/es/editor-kernel/kernel.js +7 -0
- package/es/plugins/common/plugin/index.js +2 -2
- package/es/plugins/markdown/command/index.d.ts +3 -1
- package/es/plugins/markdown/command/index.js +32 -14
- package/es/plugins/markdown/plugin/index.js +3 -1
- package/es/plugins/markdown/react/index.js +3 -3
- package/es/types/kernel.d.ts +9 -3
- package/package.json +23 -23
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { HistoryState } from '@lexical/history';
|
|
1
2
|
import EventEmitter from 'eventemitter3';
|
|
2
3
|
import { CommandListener, CommandListenerPriority, CommandPayloadType, DecoratorNode, LexicalCommand, LexicalEditor, LexicalNodeConfig } from 'lexical';
|
|
3
4
|
import { HotkeyId } from "../types/hotkey";
|
|
@@ -17,8 +18,10 @@ export declare class Kernel extends EventEmitter implements IEditorKernel {
|
|
|
17
18
|
private localeMap;
|
|
18
19
|
private hotReloadMode;
|
|
19
20
|
private logger;
|
|
21
|
+
private historyState;
|
|
20
22
|
private editor?;
|
|
21
23
|
constructor();
|
|
24
|
+
getHistoryState(): HistoryState;
|
|
22
25
|
private detectDevelopmentMode;
|
|
23
26
|
/**
|
|
24
27
|
* Globally enable or disable hot reload mode for all kernel instances
|
|
@@ -19,6 +19,7 @@ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.g
|
|
|
19
19
|
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
20
20
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
21
21
|
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
22
|
+
import { createEmptyHistoryState } from '@lexical/history';
|
|
22
23
|
import EventEmitter from 'eventemitter3';
|
|
23
24
|
import { $getSelection, $isRangeSelection, COMMAND_PRIORITY_CRITICAL, KEY_DOWN_COMMAND, createEditor } from 'lexical';
|
|
24
25
|
import { get, merge, template, templateSettings } from 'lodash-es';
|
|
@@ -48,6 +49,7 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
|
48
49
|
_defineProperty(_assertThisInitialized(_this), "localeMap", defaultLocale);
|
|
49
50
|
_defineProperty(_assertThisInitialized(_this), "hotReloadMode", false);
|
|
50
51
|
_defineProperty(_assertThisInitialized(_this), "logger", createDebugLogger('kernel'));
|
|
52
|
+
_defineProperty(_assertThisInitialized(_this), "historyState", createEmptyHistoryState());
|
|
51
53
|
_defineProperty(_assertThisInitialized(_this), "editor", void 0);
|
|
52
54
|
_defineProperty(_assertThisInitialized(_this), "_commands", new Map());
|
|
53
55
|
_defineProperty(_assertThisInitialized(_this), "_commandsClean", new Map());
|
|
@@ -58,6 +60,11 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
|
58
60
|
return _this;
|
|
59
61
|
}
|
|
60
62
|
_createClass(Kernel, [{
|
|
63
|
+
key: "getHistoryState",
|
|
64
|
+
value: function getHistoryState() {
|
|
65
|
+
return this.historyState;
|
|
66
|
+
}
|
|
67
|
+
}, {
|
|
61
68
|
key: "detectDevelopmentMode",
|
|
62
69
|
value: function detectDevelopmentMode() {
|
|
63
70
|
var _process$env;
|
|
@@ -22,7 +22,7 @@ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key i
|
|
|
22
22
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
23
23
|
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
24
24
|
import { registerDragonSupport } from '@lexical/dragon';
|
|
25
|
-
import {
|
|
25
|
+
import { registerHistory } from '@lexical/history';
|
|
26
26
|
import { $createHeadingNode, $createQuoteNode, $isHeadingNode, $isQuoteNode, HeadingNode, QuoteNode, registerRichText } from '@lexical/rich-text';
|
|
27
27
|
import { $createLineBreakNode, $createParagraphNode, $getSelection, $isRangeSelection, $isTextNode, COMMAND_PRIORITY_HIGH, INSERT_LINE_BREAK_COMMAND, INSERT_PARAGRAPH_COMMAND } from 'lexical';
|
|
28
28
|
import { KernelPlugin } from "../../../editor-kernel/plugin";
|
|
@@ -322,7 +322,7 @@ export var CommonPlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
|
322
322
|
key: "onInit",
|
|
323
323
|
value: function onInit(editor) {
|
|
324
324
|
var _this$config2;
|
|
325
|
-
this.registerClears(registerRichText(editor), registerDragonSupport(editor), registerHistory(editor,
|
|
325
|
+
this.registerClears(registerRichText(editor), registerDragonSupport(editor), registerHistory(editor, this.kernel.getHistoryState(), 300), registerHeaderBackspace(editor), registerRichKeydown(editor, this.kernel, {
|
|
326
326
|
enableHotkey: (_this$config2 = this.config) === null || _this$config2 === void 0 ? void 0 : _this$config2.enableHotkey
|
|
327
327
|
}), registerCommands(editor), registerBreakLineClick(editor), registerCursorNode(editor), registerLastElement(editor),
|
|
328
328
|
// Convert soft line breaks (Shift+Enter) to hard line breaks (paragraph breaks)
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { HistoryState, HistoryStateEntry } from '@lexical/history';
|
|
1
2
|
import { LexicalEditor } from 'lexical';
|
|
2
3
|
import { MarkdownShortCutService } from '../service/shortcut';
|
|
3
4
|
export declare const INSERT_MARKDOWN_COMMAND: import("lexical").LexicalCommand<{
|
|
5
|
+
historyState: HistoryStateEntry | null;
|
|
4
6
|
markdown: string;
|
|
5
7
|
}>;
|
|
6
|
-
export declare function registerMarkdownCommand(editor: LexicalEditor, service: MarkdownShortCutService): () => void;
|
|
8
|
+
export declare function registerMarkdownCommand(editor: LexicalEditor, service: MarkdownShortCutService, history: HistoryState): () => void;
|
|
@@ -1,25 +1,43 @@
|
|
|
1
|
-
import { $getSelection, COMMAND_PRIORITY_HIGH, createCommand } from 'lexical';
|
|
1
|
+
import { $getSelection, CAN_UNDO_COMMAND, COMMAND_PRIORITY_HIGH, HISTORIC_TAG, createCommand } from 'lexical';
|
|
2
2
|
import { createDebugLogger } from "../../../utils/debug";
|
|
3
3
|
import { parseMarkdownToLexical } from "../data-source/markdown/parse";
|
|
4
4
|
import { $generateNodesFromSerializedNodes, $insertGeneratedNodes } from "../utils";
|
|
5
5
|
var logger = createDebugLogger('plugin', 'markdown');
|
|
6
6
|
export var INSERT_MARKDOWN_COMMAND = createCommand('INSERT_MARKDOWN_COMMAND');
|
|
7
|
-
|
|
7
|
+
function undoToEntry(editor, historyState, entry) {
|
|
8
|
+
var undoStack = historyState.undoStack;
|
|
9
|
+
var current = historyState.current;
|
|
10
|
+
if (current) {
|
|
11
|
+
undoStack.push(current);
|
|
12
|
+
editor.dispatchCommand(CAN_UNDO_COMMAND, false);
|
|
13
|
+
}
|
|
14
|
+
historyState.current = entry || null;
|
|
15
|
+
if (entry) {
|
|
16
|
+
editor.setEditorState(entry.editorState, {
|
|
17
|
+
tag: HISTORIC_TAG
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
return editor.getEditorState();
|
|
21
|
+
}
|
|
22
|
+
export function registerMarkdownCommand(editor, service, history) {
|
|
8
23
|
return editor.registerCommand(INSERT_MARKDOWN_COMMAND, function (payload) {
|
|
9
24
|
var markdown = payload.markdown;
|
|
10
25
|
logger.debug('INSERT_MARKDOWN_COMMAND payload:', payload);
|
|
11
|
-
editor.
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
26
|
+
undoToEntry(editor, history, payload.historyState);
|
|
27
|
+
queueMicrotask(function () {
|
|
28
|
+
editor.update(function () {
|
|
29
|
+
try {
|
|
30
|
+
// Use the markdown data source to parse the content
|
|
31
|
+
var root = parseMarkdownToLexical(markdown, service.markdownReaders);
|
|
32
|
+
var selection = $getSelection();
|
|
33
|
+
var nodes = $generateNodesFromSerializedNodes(root.children);
|
|
34
|
+
logger.debug('INSERT_MARKDOWN_COMMAND nodes:', nodes);
|
|
35
|
+
$insertGeneratedNodes(editor, nodes, selection);
|
|
36
|
+
return true;
|
|
37
|
+
} catch (error) {
|
|
38
|
+
logger.error('Failed to handle markdown paste:', error);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
23
41
|
});
|
|
24
42
|
return false;
|
|
25
43
|
}, COMMAND_PRIORITY_HIGH // Priority
|
|
@@ -144,9 +144,11 @@ export var MarkdownPlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
|
144
144
|
if (hasMarkdownContent) {
|
|
145
145
|
// Markdown detected - show confirmation dialog
|
|
146
146
|
_this2.logger.debug('markdown patterns detected:', _this2.getMarkdownPatterns(text));
|
|
147
|
+
var historyState = _this2.kernel.getHistoryState().current;
|
|
147
148
|
setTimeout(function () {
|
|
148
149
|
_this2.kernel.emit('markdownParse', {
|
|
149
150
|
cacheState: editor.getEditorState(),
|
|
151
|
+
historyState: historyState,
|
|
150
152
|
markdown: text
|
|
151
153
|
});
|
|
152
154
|
}, 10);
|
|
@@ -156,7 +158,7 @@ export var MarkdownPlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
|
156
158
|
}
|
|
157
159
|
return false;
|
|
158
160
|
}, COMMAND_PRIORITY_CRITICAL));
|
|
159
|
-
this.register(registerMarkdownCommand(editor, this.service));
|
|
161
|
+
this.register(registerMarkdownCommand(editor, this.service, this.kernel.getHistoryState()));
|
|
160
162
|
}
|
|
161
163
|
|
|
162
164
|
/**
|
|
@@ -8,7 +8,6 @@ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" !=
|
|
|
8
8
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
9
9
|
import { Button } from '@lobehub/ui';
|
|
10
10
|
import { Space, notification } from 'antd';
|
|
11
|
-
import { UNDO_COMMAND } from 'lexical';
|
|
12
11
|
import { useLayoutEffect } from 'react';
|
|
13
12
|
import { useLexicalComposerContext } from "../../../editor-kernel/react";
|
|
14
13
|
import { useTranslation } from "../../../editor-kernel/react/useTranslation";
|
|
@@ -28,7 +27,8 @@ var ReactMarkdownPlugin = function ReactMarkdownPlugin() {
|
|
|
28
27
|
useLayoutEffect(function () {
|
|
29
28
|
editor.registerPlugin(MarkdownPlugin);
|
|
30
29
|
var handleEvent = function handleEvent(_ref) {
|
|
31
|
-
var markdown = _ref.markdown
|
|
30
|
+
var markdown = _ref.markdown,
|
|
31
|
+
historyState = _ref.historyState;
|
|
32
32
|
var key = "open".concat(Date.now());
|
|
33
33
|
var actions = /*#__PURE__*/_jsxs(Space, {
|
|
34
34
|
children: [/*#__PURE__*/_jsx(Button, {
|
|
@@ -39,8 +39,8 @@ var ReactMarkdownPlugin = function ReactMarkdownPlugin() {
|
|
|
39
39
|
children: t('markdown.cancel')
|
|
40
40
|
}), /*#__PURE__*/_jsx(Button, {
|
|
41
41
|
onClick: function onClick() {
|
|
42
|
-
editor.dispatchCommand(UNDO_COMMAND, undefined);
|
|
43
42
|
editor.dispatchCommand(INSERT_MARKDOWN_COMMAND, {
|
|
43
|
+
historyState: historyState,
|
|
44
44
|
markdown: markdown
|
|
45
45
|
});
|
|
46
46
|
api.destroy();
|
package/es/types/kernel.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import type { HistoryState, HistoryStateEntry } from '@lexical/history';
|
|
1
2
|
import type { CommandListener, CommandListenerPriority, CommandPayloadType, DecoratorNode, EditorState, LexicalCommand, LexicalEditor, LexicalNodeConfig } from 'lexical';
|
|
2
3
|
import type DataSource from "../editor-kernel/data-source";
|
|
3
|
-
import { HotkeyId } from "./hotkey";
|
|
4
|
-
import { HotkeyOptions, HotkeysEvent } from "../utils/hotkey/registerHotkey";
|
|
5
|
-
import { ILocaleKeys } from './locale';
|
|
4
|
+
import type { HotkeyId } from "./hotkey";
|
|
5
|
+
import type { HotkeyOptions, HotkeysEvent } from "../utils/hotkey/registerHotkey";
|
|
6
|
+
import type { ILocaleKeys } from './locale';
|
|
6
7
|
export type Commands = Map<LexicalCommand<unknown>, Array<Set<CommandListener<unknown>>>>;
|
|
7
8
|
export type CommandsClean = Map<LexicalCommand<unknown>, () => void>;
|
|
8
9
|
/**
|
|
@@ -28,6 +29,7 @@ export interface IKernelEventMap {
|
|
|
28
29
|
*/
|
|
29
30
|
markdownParse: (params: {
|
|
30
31
|
cacheState: EditorState;
|
|
32
|
+
historyState: HistoryStateEntry | null;
|
|
31
33
|
markdown: string;
|
|
32
34
|
}) => void;
|
|
33
35
|
}
|
|
@@ -188,6 +190,10 @@ export interface IEditorKernel extends IEditor {
|
|
|
188
190
|
* @param name
|
|
189
191
|
*/
|
|
190
192
|
getDecorator(name: string): ((_node: DecoratorNode<any>, _editor: LexicalEditor) => any) | undefined;
|
|
193
|
+
/**
|
|
194
|
+
* Get editor history state
|
|
195
|
+
*/
|
|
196
|
+
getHistoryState(): HistoryState;
|
|
191
197
|
/**
|
|
192
198
|
* Get all registered decorator names
|
|
193
199
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobehub/editor",
|
|
3
|
-
"version": "1.22.
|
|
3
|
+
"version": "1.22.1",
|
|
4
4
|
"description": "A powerful and extensible rich text editor built on Meta's Lexical framework, providing a modern editing experience with React integration.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"lobehub",
|
|
@@ -27,38 +27,38 @@
|
|
|
27
27
|
"react.js"
|
|
28
28
|
],
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@floating-ui/dom": "^1.7.
|
|
31
|
-
"@floating-ui/react": "^0.27.
|
|
32
|
-
"@lexical/code": "^0.
|
|
33
|
-
"@lexical/code-shiki": "^0.
|
|
34
|
-
"@lexical/dragon": "^0.
|
|
35
|
-
"@lexical/history": "^0.
|
|
36
|
-
"@lexical/link": "^0.
|
|
37
|
-
"@lexical/list": "^0.
|
|
38
|
-
"@lexical/rich-text": "^0.
|
|
39
|
-
"@lexical/selection": "^0.
|
|
40
|
-
"@lexical/table": "^0.
|
|
41
|
-
"@lexical/utils": "^0.
|
|
42
|
-
"@shikijs/core": "^3.
|
|
43
|
-
"@shikijs/engine-javascript": "^3.
|
|
44
|
-
"ahooks": "^3.9.
|
|
30
|
+
"@floating-ui/dom": "^1.7.4",
|
|
31
|
+
"@floating-ui/react": "^0.27.16",
|
|
32
|
+
"@lexical/code": "^0.38.2",
|
|
33
|
+
"@lexical/code-shiki": "^0.38.2",
|
|
34
|
+
"@lexical/dragon": "^0.38.2",
|
|
35
|
+
"@lexical/history": "^0.38.2",
|
|
36
|
+
"@lexical/link": "^0.38.2",
|
|
37
|
+
"@lexical/list": "^0.38.2",
|
|
38
|
+
"@lexical/rich-text": "^0.38.2",
|
|
39
|
+
"@lexical/selection": "^0.38.2",
|
|
40
|
+
"@lexical/table": "^0.38.2",
|
|
41
|
+
"@lexical/utils": "^0.38.2",
|
|
42
|
+
"@shikijs/core": "^3.15.0",
|
|
43
|
+
"@shikijs/engine-javascript": "^3.15.0",
|
|
44
|
+
"ahooks": "^3.9.6",
|
|
45
45
|
"antd-style": "^3.7.1",
|
|
46
|
-
"debug": "^4.4.
|
|
46
|
+
"debug": "^4.4.3",
|
|
47
47
|
"eventemitter3": "^5.0.1",
|
|
48
|
-
"framer-motion": "^12.23.
|
|
48
|
+
"framer-motion": "^12.23.24",
|
|
49
49
|
"fuse.js": "^7.1.0",
|
|
50
|
-
"katex": "^0.16.
|
|
51
|
-
"lexical": "^0.
|
|
50
|
+
"katex": "^0.16.25",
|
|
51
|
+
"lexical": "^0.38.2",
|
|
52
52
|
"lodash-es": "^4.17.21",
|
|
53
|
-
"lucide-react": "^0.
|
|
53
|
+
"lucide-react": "^0.553.0",
|
|
54
54
|
"polished": "^4.3.1",
|
|
55
55
|
"re-resizable": "^6.11.2",
|
|
56
56
|
"react-error-boundary": "^6.0.0",
|
|
57
57
|
"react-layout-kit": "^2.0.0",
|
|
58
58
|
"react-merge-refs": "^3.0.2",
|
|
59
|
-
"remark-cjk-friendly": "^1.2.
|
|
59
|
+
"remark-cjk-friendly": "^1.2.3",
|
|
60
60
|
"remark-supersub": "^1.0.0",
|
|
61
|
-
"shiki": "^3.
|
|
61
|
+
"shiki": "^3.15.0",
|
|
62
62
|
"ts-key-enum": "^3.0.13",
|
|
63
63
|
"use-merge-value": "^1.2.0"
|
|
64
64
|
},
|