@lobehub/editor 1.31.2 → 1.33.0

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 (55) hide show
  1. package/es/const/hotkey.js +1 -1
  2. package/es/editor-kernel/kernel.d.ts +4 -4
  3. package/es/editor-kernel/kernel.js +6 -2
  4. package/es/editor-kernel/react/PortalContainer.d.ts +11 -0
  5. package/es/editor-kernel/react/PortalContainer.js +32 -0
  6. package/es/editor-kernel/react/index.d.ts +1 -0
  7. package/es/editor-kernel/react/index.js +1 -0
  8. package/es/editor-kernel/react/useDecorators.js +3 -2
  9. package/es/editor-kernel/utils.d.ts +7 -1
  10. package/es/editor-kernel/utils.js +34 -0
  11. package/es/index.d.ts +1 -0
  12. package/es/index.js +1 -0
  13. package/es/plugins/common/plugin/register.js +37 -2
  14. package/es/plugins/file/node/FileNode.js +12 -2
  15. package/es/plugins/hr/node/HorizontalRuleNode.js +12 -2
  16. package/es/plugins/image/node/block-image-node.js +1 -1
  17. package/es/plugins/image/plugin/index.js +33 -3
  18. package/es/plugins/image/react/components/Image.js +1 -1
  19. package/es/plugins/inode/index.d.ts +3 -0
  20. package/es/plugins/inode/index.js +3 -0
  21. package/es/plugins/inode/plugin/index.d.ts +16 -0
  22. package/es/plugins/inode/plugin/index.js +49 -0
  23. package/es/plugins/inode/react/index.d.ts +3 -0
  24. package/es/plugins/inode/react/index.js +22 -0
  25. package/es/plugins/inode/service/index.d.ts +25 -0
  26. package/es/plugins/inode/service/index.js +49 -0
  27. package/es/plugins/link/node/LinkNode.js +2 -0
  28. package/es/plugins/link-highlight/node/link-highlight.js +1 -0
  29. package/es/plugins/litexml/command/diffCommand.d.ts +10 -0
  30. package/es/plugins/litexml/command/diffCommand.js +47 -0
  31. package/es/plugins/litexml/command/index.d.ts +19 -0
  32. package/es/plugins/litexml/command/index.js +286 -45
  33. package/es/plugins/litexml/data-source/litexml-data-source.d.ts +3 -1
  34. package/es/plugins/litexml/data-source/litexml-data-source.js +10 -3
  35. package/es/plugins/litexml/index.d.ts +1 -1
  36. package/es/plugins/litexml/index.js +1 -1
  37. package/es/plugins/litexml/node/DiffNode.d.ts +26 -0
  38. package/es/plugins/litexml/node/DiffNode.js +164 -0
  39. package/es/plugins/litexml/plugin/index.d.ts +4 -0
  40. package/es/plugins/litexml/plugin/index.js +23 -4
  41. package/es/plugins/litexml/react/DiffNodeToolbar.d.ts +10 -0
  42. package/es/plugins/litexml/react/DiffNodeToolbar.js +47 -0
  43. package/es/plugins/litexml/react/index.js +16 -1
  44. package/es/plugins/litexml/react/style.d.ts +1 -0
  45. package/es/plugins/litexml/react/style.js +8 -0
  46. package/es/plugins/litexml/utils/index.d.ts +3 -0
  47. package/es/plugins/litexml/utils/index.js +47 -0
  48. package/es/plugins/markdown/data-source/markdown-data-source.d.ts +3 -1
  49. package/es/plugins/markdown/data-source/markdown-data-source.js +5 -1
  50. package/es/plugins/markdown/plugin/index.js +3 -2
  51. package/es/plugins/markdown/react/index.js +2 -0
  52. package/es/plugins/math/node/index.js +24 -4
  53. package/es/plugins/mention/node/MentionNode.js +12 -2
  54. package/es/types/kernel.d.ts +8 -3
  55. package/package.json +2 -2
@@ -0,0 +1,164 @@
1
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
3
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
6
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
7
+ function _get() { if (typeof Reflect !== "undefined" && Reflect.get) { _get = Reflect.get.bind(); } else { _get = function _get(target, property, receiver) { var base = _superPropBase(target, property); if (!base) return; var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { return desc.get.call(arguments.length < 3 ? target : receiver); } return desc.value; }; } return _get.apply(this, arguments); }
8
+ function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; }
9
+ function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
10
+ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
11
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
12
+ function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }
13
+ function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
14
+ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
15
+ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
16
+ 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; }
17
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
18
+ 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); }
19
+ /* eslint-disable @typescript-eslint/no-use-before-define */
20
+ import { $applyNodeReplacement } from 'lexical';
21
+ import { getKernelFromEditor, getKernelFromEditorConfig, reconcileDecorator } from "../../../editor-kernel/utils";
22
+ import { CardLikeElementNode } from "../../common/node/cursor";
23
+ /** DiffNode - contains two block children: original and modified */
24
+ export var DiffNode = /*#__PURE__*/function (_CardLikeElementNode) {
25
+ _inherits(DiffNode, _CardLikeElementNode);
26
+ var _super = _createSuper(DiffNode);
27
+ function DiffNode(type, key) {
28
+ var _this;
29
+ _classCallCheck(this, DiffNode);
30
+ _this = _super.call(this, key);
31
+ _defineProperty(_assertThisInitialized(_this), "__diffType", 'unchanged');
32
+ _this.__diffType = type;
33
+ return _this;
34
+ }
35
+ _createClass(DiffNode, [{
36
+ key: "diffType",
37
+ get: function get() {
38
+ return this.__diffType;
39
+ }
40
+ }, {
41
+ key: "setDiffType",
42
+ value: function setDiffType(type) {
43
+ this.getWritable().__diffType = type;
44
+ return this;
45
+ }
46
+ }, {
47
+ key: "updateFromJSON",
48
+ value: function updateFromJSON(serializedNode) {
49
+ return _get(_getPrototypeOf(DiffNode.prototype), "updateFromJSON", this).call(this, serializedNode).setDiffType(serializedNode.diffType);
50
+ }
51
+ }, {
52
+ key: "exportJSON",
53
+ value: function exportJSON() {
54
+ return _objectSpread(_objectSpread({}, _get(_getPrototypeOf(DiffNode.prototype), "exportJSON", this).call(this)), {}, {
55
+ diffType: this.__diffType,
56
+ type: 'diff'
57
+ });
58
+ }
59
+ }, {
60
+ key: "exportDOM",
61
+ value: function exportDOM(editor) {
62
+ return _get(_getPrototypeOf(DiffNode.prototype), "exportDOM", this).call(this, editor);
63
+ }
64
+ }, {
65
+ key: "createDOM",
66
+ value: function createDOM(config, editor) {
67
+ var _getKernelFromEditor;
68
+ var el = document.createElement('div');
69
+ el.contentEditable = 'false';
70
+ el.dataset.lexicalKey = this.getKey();
71
+ el.dataset.diffType = this.__diffType;
72
+ el.classList.add('ne-diff');
73
+ if (config.theme.diffNode) {
74
+ el.classList.add(config.theme.diffNode);
75
+ }
76
+ var toolbar = document.createElement('div');
77
+ toolbar.className = 'toolbar';
78
+ toolbar.dataset.lexicalDecorator = 'true';
79
+ el.append(toolbar);
80
+ var content = document.createElement('div');
81
+ content.className = 'content';
82
+ el.append(content);
83
+ var decorator = ((_getKernelFromEditor = getKernelFromEditor(editor)) === null || _getKernelFromEditor === void 0 ? void 0 : _getKernelFromEditor.getDecorator('diff')) || null;
84
+ if (decorator) {
85
+ if (typeof decorator === 'function') {
86
+ reconcileDecorator(editor, this.getKey(), decorator(this, editor));
87
+ } else {
88
+ reconcileDecorator(editor, this.getKey(), {
89
+ queryDOM: decorator.queryDOM,
90
+ render: decorator.render(this, editor)
91
+ });
92
+ }
93
+ }
94
+ return el;
95
+ }
96
+ }, {
97
+ key: "updateDOM",
98
+ value: function updateDOM(_prevNode, _dom, _config) {
99
+ if (_dom.dataset.diffType !== this.__diffType) {
100
+ _dom.dataset.diffType = this.__diffType;
101
+ }
102
+ var kernel = getKernelFromEditorConfig(_config);
103
+ var editor = kernel === null || kernel === void 0 ? void 0 : kernel.getLexicalEditor();
104
+ if (editor) {
105
+ var decorator = (kernel === null || kernel === void 0 ? void 0 : kernel.getDecorator('diff')) || null;
106
+ if (decorator) {
107
+ if (typeof decorator === 'function') {
108
+ reconcileDecorator(editor, this.getKey(), decorator(this, editor));
109
+ } else {
110
+ reconcileDecorator(editor, this.getKey(), {
111
+ queryDOM: decorator.queryDOM,
112
+ render: decorator.render(this, editor)
113
+ });
114
+ }
115
+ }
116
+ }
117
+ return false;
118
+ }
119
+ }, {
120
+ key: "getDOMSlot",
121
+ value: function getDOMSlot(element) {
122
+ return _get(_getPrototypeOf(DiffNode.prototype), "getDOMSlot", this).call(this, element).withElement(element.querySelector('.content'));
123
+ }
124
+ }, {
125
+ key: "isInline",
126
+ value: function isInline() {
127
+ return false;
128
+ }
129
+ }, {
130
+ key: "isCardLike",
131
+ value: function isCardLike() {
132
+ return true;
133
+ }
134
+ }], [{
135
+ key: "getType",
136
+ value: function getType() {
137
+ return 'diff';
138
+ }
139
+ }, {
140
+ key: "clone",
141
+ value: function clone(node) {
142
+ return new DiffNode(node.__diffType, node.__key);
143
+ }
144
+ }, {
145
+ key: "importJSON",
146
+ value: function importJSON(serializedNode) {
147
+ return $createDiffNode().updateFromJSON(serializedNode);
148
+ }
149
+ }, {
150
+ key: "importDOM",
151
+ value: function importDOM() {
152
+ // TODO: Should link node should handle the import over autolink?
153
+ return null;
154
+ }
155
+ }]);
156
+ return DiffNode;
157
+ }(CardLikeElementNode);
158
+ export function $createDiffNode() {
159
+ var diffType = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'unchanged';
160
+ return $applyNodeReplacement(new DiffNode(diffType));
161
+ }
162
+ export function $isDiffNode(node) {
163
+ return node instanceof DiffNode;
164
+ }
@@ -1,13 +1,17 @@
1
+ import { LexicalEditor } from 'lexical';
1
2
  import type { IEditorPluginConstructor } from "../../../types";
3
+ import { DiffNode } from '../node/DiffNode';
2
4
  /**
3
5
  * LitexmlPluginOptions - Configuration options for the Litexml plugin
4
6
  */
5
7
  export interface LitexmlPluginOptions {
8
+ decorator: (node: DiffNode, editor: LexicalEditor) => any;
6
9
  /**
7
10
  * Enable or disable the litexml data source
8
11
  * @default true
9
12
  */
10
13
  enabled?: boolean;
14
+ theme?: string;
11
15
  }
12
16
  /**
13
17
  * LitexmlPlugin - A plugin that provides XML-based data source support
@@ -15,7 +15,9 @@ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol"
15
15
  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); }
16
16
  import { KernelPlugin } from "../../../editor-kernel/plugin";
17
17
  import { registerLiteXMLCommand } from "../command";
18
+ import { registerLiteXMLDiffCommand } from "../command/diffCommand";
18
19
  import LitexmlDataSource from "../data-source/litexml-data-source";
20
+ import { DiffNode } from "../node/DiffNode";
19
21
  import { ILitexmlService, LitexmlService } from "../service/litexml-service";
20
22
 
21
23
  /**
@@ -33,14 +35,30 @@ export var LitexmlPlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
33
35
  var _this;
34
36
  _classCallCheck(this, LitexmlPlugin);
35
37
  _this = _super.call(this);
36
-
37
- // Create and register the Litexml service
38
38
  _defineProperty(_assertThisInitialized(_this), "datasource", void 0);
39
39
  _this.kernel = kernel;
40
40
  _this.config = config;
41
+ kernel.registerThemes({
42
+ diffNode: (config === null || config === void 0 ? void 0 : config.theme) || 'editor_diffNode'
43
+ });
44
+
45
+ // Create and register the Litexml service
41
46
  var litexmlService = new LitexmlService();
42
47
  kernel.registerService(ILitexmlService, litexmlService);
43
- _this.datasource = new LitexmlDataSource('litexml', litexmlService);
48
+ _this.datasource = new LitexmlDataSource('litexml', function (serviceId) {
49
+ return kernel.requireService(serviceId);
50
+ }, litexmlService);
51
+
52
+ // register diff node type
53
+ kernel.registerNodes([DiffNode]);
54
+ kernel.registerDecorator(DiffNode.getType(), {
55
+ queryDOM: function queryDOM(el) {
56
+ return el.querySelector('.toolbar');
57
+ },
58
+ render: function render(node, editor) {
59
+ return config !== null && config !== void 0 && config.decorator ? config.decorator(node, editor) : null;
60
+ }
61
+ });
44
62
 
45
63
  // Register the litexml data source
46
64
  if ((config === null || config === void 0 ? void 0 : config.enabled) !== false) {
@@ -52,7 +70,8 @@ export var LitexmlPlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
52
70
  key: "onInit",
53
71
  value: function onInit(editor) {
54
72
  // Plugin initialization logic can be added here if needed
55
- registerLiteXMLCommand(editor, this.datasource);
73
+ this.register(registerLiteXMLCommand(editor, this.datasource));
74
+ this.register(registerLiteXMLDiffCommand(editor));
56
75
  }
57
76
  }]);
58
77
  return LitexmlPlugin;
@@ -0,0 +1,10 @@
1
+ /// <reference types="react" />
2
+ import { LexicalEditor } from 'lexical';
3
+ import { DiffNode } from '../node/DiffNode';
4
+ interface ReactDiffNodeToolbarProps {
5
+ className?: string;
6
+ editor: LexicalEditor;
7
+ node: DiffNode;
8
+ }
9
+ declare const ReactDiffNodeToolbar: import("react").NamedExoticComponent<ReactDiffNodeToolbarProps>;
10
+ export default ReactDiffNodeToolbar;
@@ -0,0 +1,47 @@
1
+ import { Check, X } from 'lucide-react';
2
+ import { memo } from 'react';
3
+ import { LexicalPortalContainer } from "../../../editor-kernel/react";
4
+ import { DiffAction, LITEXML_DIFFNODE_COMMAND } from "../command/diffCommand";
5
+ import { jsx as _jsx } from "react/jsx-runtime";
6
+ import { jsxs as _jsxs } from "react/jsx-runtime";
7
+ var ReactDiffNodeToolbar = /*#__PURE__*/memo(function (_ref) {
8
+ var editor = _ref.editor,
9
+ node = _ref.node;
10
+ return /*#__PURE__*/_jsxs(LexicalPortalContainer, {
11
+ editor: editor,
12
+ node: node,
13
+ children: [/*#__PURE__*/_jsx("button", {
14
+ "aria-label": "Accept change",
15
+ className: "toolbarButton accept",
16
+ onClick: function onClick() {
17
+ console.log('Accept change');
18
+ editor.dispatchCommand(LITEXML_DIFFNODE_COMMAND, {
19
+ action: DiffAction.Accept,
20
+ nodeKey: node.getKey()
21
+ });
22
+ },
23
+ title: "Accept",
24
+ type: "button",
25
+ children: /*#__PURE__*/_jsx(Check, {
26
+ size: 16
27
+ })
28
+ }), /*#__PURE__*/_jsx("button", {
29
+ "aria-label": "Reject change",
30
+ className: "toolbarButton reject",
31
+ onClick: function onClick() {
32
+ console.log('Reject change');
33
+ editor.dispatchCommand(LITEXML_DIFFNODE_COMMAND, {
34
+ action: DiffAction.Reject,
35
+ nodeKey: node.getKey()
36
+ });
37
+ },
38
+ title: "Reject",
39
+ type: "button",
40
+ children: /*#__PURE__*/_jsx(X, {
41
+ size: 16
42
+ })
43
+ })]
44
+ });
45
+ });
46
+ ReactDiffNodeToolbar.displayName = 'ReactDiffNodeToolbar';
47
+ export default ReactDiffNodeToolbar;
@@ -8,13 +8,28 @@ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" !=
8
8
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
9
9
  import { useLayoutEffect } from 'react';
10
10
  import { useLexicalComposerContext } from "../../../editor-kernel/react";
11
+ import { INodePlugin } from "../../inode";
11
12
  import { LitexmlPlugin } from "../plugin";
13
+ import ReactDiffNodeToolbar from "./DiffNodeToolbar";
14
+ import { useStyles } from "./style";
15
+ import { jsx as _jsx } from "react/jsx-runtime";
12
16
  export var ReactLiteXmlPlugin = function ReactLiteXmlPlugin() {
13
17
  var _useLexicalComposerCo = useLexicalComposerContext(),
14
18
  _useLexicalComposerCo2 = _slicedToArray(_useLexicalComposerCo, 1),
15
19
  editor = _useLexicalComposerCo2[0];
20
+ var _useStyles = useStyles(),
21
+ styles = _useStyles.styles;
16
22
  useLayoutEffect(function () {
17
- editor.registerPlugin(LitexmlPlugin);
23
+ editor.registerPlugin(INodePlugin);
24
+ editor.registerPlugin(LitexmlPlugin, {
25
+ decorator: function decorator(node, editor) {
26
+ return /*#__PURE__*/_jsx(ReactDiffNodeToolbar, {
27
+ editor: editor,
28
+ node: node
29
+ });
30
+ },
31
+ theme: styles
32
+ });
18
33
  }, [editor]);
19
34
  return null;
20
35
  };
@@ -0,0 +1 @@
1
+ export declare const useStyles: (props?: unknown) => import("antd-style").ReturnStyles<import("antd-style").SerializedStyles>;
@@ -0,0 +1,8 @@
1
+ var _templateObject;
2
+ function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
3
+ import { createStyles } from 'antd-style';
4
+ export var useStyles = createStyles(function (_ref) {
5
+ var css = _ref.css,
6
+ token = _ref.token;
7
+ return css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n position: relative;\n border: 1px solid ", ";\n\n .toolbar {\n position: absolute;\n z-index: 10;\n inset-block-start: 0;\n inset-inline-end: 0;\n\n display: flex;\n gap: 4px;\n align-items: center;\n\n padding: 4px;\n border: 1px solid #eee;\n border-radius: 4px;\n\n background: #fff;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 10%);\n }\n\n .toolbarButton {\n cursor: pointer;\n\n display: flex;\n align-items: center;\n justify-content: center;\n\n padding: 2px;\n border: none;\n\n background: none;\n }\n\n .toolbarButton:focus {\n border-radius: 3px;\n outline: 2px solid ", ";\n outline-offset: 2px;\n }\n\n .accept {\n color: ", ";\n }\n\n .reject {\n color: ", ";\n }\n\n &[data-diff-type='add'] .content {\n position: relative;\n background-color: ", ";\n }\n\n &[data-diff-type='remove'] .content {\n position: relative;\n background-color: ", ";\n\n > *:first-child p,\n > *:first-child span {\n text-decoration: line-through;\n }\n }\n\n &[data-diff-type='modify'] .content {\n position: relative;\n\n /* first child: original (deleted) */\n > *:first-child {\n opacity: 0.6;\n }\n\n /* visually indicate deletion with strike-through for text nodes */\n > *:first-child p,\n > *:first-child span {\n text-decoration: line-through;\n }\n\n /* second child: modified/new - normal appearance */\n > *:nth-child(2) {\n color: inherit;\n opacity: 1;\n }\n }\n "])), token.colorBorderSecondary, token.colorPrimary, token.colorSuccess, token.colorError, token.colorSuccessBgHover, token.colorErrorBgHover);
8
+ });
@@ -1,2 +1,5 @@
1
1
  import { LexicalEditor, LexicalNode } from 'lexical';
2
2
  export declare function $parseSerializedNodeImpl(serializedNode: any, editor: LexicalEditor): LexicalNode;
3
+ export declare function $cloneNode(node: LexicalNode, editor: LexicalEditor): LexicalNode;
4
+ export declare function idToChar(id: string | number): string;
5
+ export declare function charToId(char: string): string;
@@ -30,4 +30,51 @@ export function $parseSerializedNodeImpl(serializedNode, editor) {
30
30
  }
31
31
  }
32
32
  return node;
33
+ }
34
+ function exportNodeToJSON(node) {
35
+ var serializedNode = node.exportJSON();
36
+ var nodeClass = node.constructor;
37
+ if (serializedNode.type !== nodeClass.getType()) {
38
+ throw new Error("LexicalNode: Node ".concat(nodeClass.name, " does not match the serialized type. Check if .exportJSON() is implemented and it is returning the correct type."));
39
+ }
40
+ if ($isElementNode(node)) {
41
+ var serializedChildren = serializedNode.children;
42
+ if (!Array.isArray(serializedChildren)) {
43
+ throw new Error("LexicalNode: Node ".concat(nodeClass.name, " is an element but .exportJSON() does not have a children array."));
44
+ }
45
+ var children = node.getChildren();
46
+ var _iterator2 = _createForOfIteratorHelper(children),
47
+ _step2;
48
+ try {
49
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
50
+ var child = _step2.value;
51
+ var serializedChildNode = exportNodeToJSON(child);
52
+ serializedChildren.push(serializedChildNode);
53
+ }
54
+ } catch (err) {
55
+ _iterator2.e(err);
56
+ } finally {
57
+ _iterator2.f();
58
+ }
59
+ }
60
+
61
+ // @ts-expect-error
62
+ return serializedNode;
63
+ }
64
+ export function $cloneNode(node, editor) {
65
+ var json = exportNodeToJSON(node);
66
+ return $parseSerializedNodeImpl(json, editor);
67
+ }
68
+ var maxId = 1679616; // 36^4
69
+ var startId = 1000000; // to avoid short ids
70
+ var step = 7211; // a prime number to reduce collisions
71
+ var modInverse = 1394051; // modular inverse of step mod maxId
72
+
73
+ export function idToChar(id) {
74
+ var nId = (Number(id) * step + startId) % maxId;
75
+ return nId.toString(36).padStart(4, '0');
76
+ }
77
+ export function charToId(char) {
78
+ var nId = parseInt(char, 36);
79
+ return String((nId - startId + maxId) * modInverse % maxId);
33
80
  }
@@ -1,11 +1,13 @@
1
1
  import type { LexicalEditor } from 'lexical';
2
2
  import { DataSource } from "../../../editor-kernel";
3
3
  import type { IWriteOptions } from "../../../editor-kernel/data-source";
4
+ import type { IServiceID } from "../../../types";
4
5
  import type { MarkdownShortCutService } from '../service/shortcut';
5
6
  export default class MarkdownDataSource extends DataSource {
6
7
  protected dataType: string;
7
8
  protected markdownService: MarkdownShortCutService;
8
- constructor(dataType: string, markdownService: MarkdownShortCutService);
9
+ protected getService?: (<T>(serviceId: IServiceID<T>) => T | null) | undefined;
10
+ constructor(dataType: string, markdownService: MarkdownShortCutService, getService?: (<T>(serviceId: IServiceID<T>) => T | null) | undefined);
9
11
  read(editor: LexicalEditor, data: string): void;
10
12
  write(editor: LexicalEditor, options?: IWriteOptions): any;
11
13
  }
@@ -29,26 +29,30 @@ import { $isTableSelection } from '@lexical/table';
29
29
  import { $getCharacterOffsets, $getNodeByKey, $getRoot, $getSelection, $isElementNode, $isRangeSelection, $isTextNode } from 'lexical';
30
30
  import { DataSource } from "../../../editor-kernel";
31
31
  import { INodeHelper } from "../../../editor-kernel/inode/helper";
32
+ import { INodeService } from "../../inode";
32
33
  import { logger } from "../utils/logger";
33
34
  import { MarkdownWriterContext } from "./markdown-writer-context";
34
35
  import { parseMarkdownToLexical } from "./markdown/parse";
35
36
  var MarkdownDataSource = /*#__PURE__*/function (_DataSource) {
36
37
  _inherits(MarkdownDataSource, _DataSource);
37
38
  var _super = _createSuper(MarkdownDataSource);
38
- function MarkdownDataSource(dataType, markdownService) {
39
+ function MarkdownDataSource(dataType, markdownService, getService) {
39
40
  var _this;
40
41
  _classCallCheck(this, MarkdownDataSource);
41
42
  _this = _super.call(this, dataType);
42
43
  _this.dataType = dataType;
43
44
  _this.markdownService = markdownService;
45
+ _this.getService = getService;
44
46
  return _this;
45
47
  }
46
48
  _createClass(MarkdownDataSource, [{
47
49
  key: "read",
48
50
  value: function read(editor, data) {
51
+ var _this$getService;
49
52
  var inode = {
50
53
  root: parseMarkdownToLexical(data, this.markdownService.markdownReaders)
51
54
  };
55
+ (_this$getService = this.getService) === null || _this$getService === void 0 || (_this$getService = _this$getService.call(this, INodeService)) === null || _this$getService === void 0 || _this$getService.processNodeTree(inode);
52
56
  logger.debug('Parsed Lexical State:', inode);
53
57
  editor.setEditorState(editor.parseEditorState(inode));
54
58
  }
@@ -35,8 +35,9 @@ export var MarkdownPlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
35
35
  _this.config = config;
36
36
  _this.service = new MarkdownShortCutService(kernel);
37
37
  kernel.registerService(IMarkdownShortCutService, _this.service);
38
- // @todo To be implemented
39
- kernel.registerDataSource(new MarkdownDataSource('markdown', _this.service));
38
+ kernel.registerDataSource(new MarkdownDataSource('markdown', _this.service, function (serviceId) {
39
+ return kernel.requireService(serviceId);
40
+ }));
40
41
  return _this;
41
42
  }
42
43
  _createClass(MarkdownPlugin, [{
@@ -11,6 +11,7 @@ import { Space, notification } from 'antd';
11
11
  import { useLayoutEffect } from 'react';
12
12
  import { useLexicalComposerContext } from "../../../editor-kernel/react";
13
13
  import { useTranslation } from "../../../editor-kernel/react/useTranslation";
14
+ import { INodePlugin } from "../../inode";
14
15
  import { INSERT_MARKDOWN_COMMAND } from "../command";
15
16
  import { MarkdownPlugin } from "../plugin";
16
17
  import { jsx as _jsx } from "react/jsx-runtime";
@@ -25,6 +26,7 @@ var ReactMarkdownPlugin = function ReactMarkdownPlugin() {
25
26
  contextHolder = _notification$useNoti2[1];
26
27
  var t = useTranslation();
27
28
  useLayoutEffect(function () {
29
+ editor.registerPlugin(INodePlugin);
28
30
  editor.registerPlugin(MarkdownPlugin);
29
31
  var handleEvent = function handleEvent(_ref) {
30
32
  var markdown = _ref.markdown,
@@ -92,8 +92,18 @@ export var MathInlineNode = /*#__PURE__*/function (_DecoratorNode) {
92
92
  }, {
93
93
  key: "decorate",
94
94
  value: function decorate(editor) {
95
- var _getKernelFromEditor, _getKernelFromEditor$;
96
- return ((_getKernelFromEditor = getKernelFromEditor(editor)) === null || _getKernelFromEditor === void 0 || (_getKernelFromEditor$ = _getKernelFromEditor.getDecorator(MathInlineNode.getType())) === null || _getKernelFromEditor$ === void 0 ? void 0 : _getKernelFromEditor$(this, editor)) || null;
95
+ var _getKernelFromEditor;
96
+ var decorator = (_getKernelFromEditor = getKernelFromEditor(editor)) === null || _getKernelFromEditor === void 0 ? void 0 : _getKernelFromEditor.getDecorator(MathInlineNode.getType());
97
+ if (!decorator) {
98
+ return null;
99
+ }
100
+ if (typeof decorator === 'function') {
101
+ return decorator(this, editor);
102
+ }
103
+ return {
104
+ queryDOM: decorator.queryDOM,
105
+ render: decorator.render(this, editor)
106
+ };
97
107
  }
98
108
  }], [{
99
109
  key: "getType",
@@ -200,8 +210,18 @@ export var MathBlockNode = /*#__PURE__*/function (_DecoratorNode2) {
200
210
  }, {
201
211
  key: "decorate",
202
212
  value: function decorate(editor) {
203
- var _getKernelFromEditor2, _getKernelFromEditor3;
204
- return ((_getKernelFromEditor2 = getKernelFromEditor(editor)) === null || _getKernelFromEditor2 === void 0 || (_getKernelFromEditor3 = _getKernelFromEditor2.getDecorator(MathBlockNode.getType())) === null || _getKernelFromEditor3 === void 0 ? void 0 : _getKernelFromEditor3(this, editor)) || null;
213
+ var _getKernelFromEditor2;
214
+ var decorator = (_getKernelFromEditor2 = getKernelFromEditor(editor)) === null || _getKernelFromEditor2 === void 0 ? void 0 : _getKernelFromEditor2.getDecorator(MathBlockNode.getType());
215
+ if (!decorator) {
216
+ return null;
217
+ }
218
+ if (typeof decorator === 'function') {
219
+ return decorator(this, editor);
220
+ }
221
+ return {
222
+ queryDOM: decorator.queryDOM,
223
+ render: decorator.render(this, editor)
224
+ };
205
225
  }
206
226
  }], [{
207
227
  key: "getType",
@@ -94,8 +94,18 @@ export var MentionNode = /*#__PURE__*/function (_DecoratorNode) {
94
94
  }, {
95
95
  key: "decorate",
96
96
  value: function decorate(editor) {
97
- var _getKernelFromEditor, _getKernelFromEditor$;
98
- return ((_getKernelFromEditor = getKernelFromEditor(editor)) === null || _getKernelFromEditor === void 0 || (_getKernelFromEditor$ = _getKernelFromEditor.getDecorator('mention')) === null || _getKernelFromEditor$ === void 0 ? void 0 : _getKernelFromEditor$(this, editor)) || null;
97
+ var _getKernelFromEditor;
98
+ var decorator = (_getKernelFromEditor = getKernelFromEditor(editor)) === null || _getKernelFromEditor === void 0 ? void 0 : _getKernelFromEditor.getDecorator(MentionNode.getType());
99
+ if (!decorator) {
100
+ return null;
101
+ }
102
+ if (typeof decorator === 'function') {
103
+ return decorator(this, editor);
104
+ }
105
+ return {
106
+ queryDOM: decorator.queryDOM,
107
+ render: decorator.render(this, editor)
108
+ };
99
109
  }
100
110
  }], [{
101
111
  key: "getType",
@@ -1,11 +1,16 @@
1
1
  import type { HistoryState, HistoryStateEntry } from '@lexical/history';
2
- import type { CommandListener, CommandListenerPriority, CommandPayloadType, DecoratorNode, EditorState, LexicalCommand, LexicalEditor, LexicalNodeConfig } from 'lexical';
2
+ import type { CommandListener, CommandListenerPriority, CommandPayloadType, EditorState, LexicalCommand, LexicalEditor, LexicalNode, LexicalNodeConfig } from 'lexical';
3
3
  import type DataSource from "../editor-kernel/data-source";
4
4
  import type { HotkeyId } from "./hotkey";
5
5
  import type { HotkeyOptions, HotkeysEvent } from "../utils/hotkey/registerHotkey";
6
6
  import type { ILocaleKeys } from './locale';
7
7
  export type Commands = Map<LexicalCommand<unknown>, Array<Set<CommandListener<unknown>>>>;
8
8
  export type CommandsClean = Map<LexicalCommand<unknown>, () => void>;
9
+ export type IDecoratorFunc = (_node: LexicalNode, _editor: LexicalEditor) => any;
10
+ export type IDecorator = {
11
+ queryDOM: (_element: HTMLElement) => HTMLElement;
12
+ render: IDecoratorFunc;
13
+ } | IDecoratorFunc;
9
14
  /**
10
15
  * Service ID type
11
16
  */
@@ -206,7 +211,7 @@ export interface IEditorKernel extends IEditor {
206
211
  * Get editor Node decorator for specific Node rendering
207
212
  * @param name
208
213
  */
209
- getDecorator(name: string): ((_node: DecoratorNode<any>, _editor: LexicalEditor) => any) | undefined;
214
+ getDecorator(name: string): IDecorator | undefined;
210
215
  /**
211
216
  * Get editor history state
212
217
  */
@@ -229,7 +234,7 @@ export interface IEditorKernel extends IEditor {
229
234
  * @param name
230
235
  * @param decorator
231
236
  */
232
- registerDecorator(name: string, decorator: (_node: DecoratorNode<any>, _editor: LexicalEditor) => any): void;
237
+ registerDecorator(name: string, decorator: IDecorator): void;
233
238
  /**
234
239
  * Register Lexical Node
235
240
  * @param nodes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/editor",
3
- "version": "1.31.2",
3
+ "version": "1.33.0",
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",
@@ -13,7 +13,7 @@
13
13
  },
14
14
  "repository": {
15
15
  "type": "git",
16
- "url": "https://github.com/lobehub/lobe-editor.git"
16
+ "url": "git+https://github.com/lobehub/lobe-editor.git"
17
17
  },
18
18
  "license": "MIT",
19
19
  "author": "LobeHub <i@lobehub.com>",