@lobehub/editor 1.31.2 → 1.32.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.
- package/es/const/hotkey.js +1 -1
- package/es/index.d.ts +1 -0
- package/es/index.js +1 -0
- package/es/plugins/common/plugin/register.js +37 -2
- package/es/plugins/image/node/block-image-node.js +1 -1
- package/es/plugins/image/plugin/index.js +33 -3
- package/es/plugins/image/react/components/Image.js +1 -1
- package/es/plugins/inode/index.d.ts +3 -0
- package/es/plugins/inode/index.js +3 -0
- package/es/plugins/inode/plugin/index.d.ts +16 -0
- package/es/plugins/inode/plugin/index.js +49 -0
- package/es/plugins/inode/react/index.d.ts +3 -0
- package/es/plugins/inode/react/index.js +22 -0
- package/es/plugins/inode/service/index.d.ts +25 -0
- package/es/plugins/inode/service/index.js +49 -0
- package/es/plugins/litexml/data-source/litexml-data-source.d.ts +3 -1
- package/es/plugins/litexml/data-source/litexml-data-source.js +10 -3
- package/es/plugins/litexml/plugin/index.js +3 -1
- package/es/plugins/litexml/react/index.js +2 -0
- package/es/plugins/litexml/utils/index.d.ts +2 -0
- package/es/plugins/litexml/utils/index.js +13 -0
- package/es/plugins/markdown/data-source/markdown-data-source.d.ts +3 -1
- package/es/plugins/markdown/data-source/markdown-data-source.js +5 -1
- package/es/plugins/markdown/plugin/index.js +3 -2
- package/es/plugins/markdown/react/index.js +2 -0
- package/package.json +2 -2
package/es/const/hotkey.js
CHANGED
|
@@ -40,7 +40,7 @@ export var HOTKEYS_REGISTRATION = [{
|
|
|
40
40
|
scopes: [HotkeyScopeEnum.Format, HotkeyScopeEnum.Plugin]
|
|
41
41
|
}, {
|
|
42
42
|
id: HotkeyEnum.Link,
|
|
43
|
-
keys: combineKeys([KeyEnum.Mod, 'k']),
|
|
43
|
+
keys: combineKeys([KeyEnum.Mod, KeyEnum.Shift, 'k']),
|
|
44
44
|
priority: COMMAND_PRIORITY_EDITOR,
|
|
45
45
|
scopes: [HotkeyScopeEnum.Format, HotkeyScopeEnum.Plugin]
|
|
46
46
|
},
|
package/es/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export * from './plugins/common';
|
|
|
7
7
|
export * from './plugins/file';
|
|
8
8
|
export * from './plugins/hr';
|
|
9
9
|
export * from './plugins/image';
|
|
10
|
+
export * from './plugins/inode';
|
|
10
11
|
export * from './plugins/link';
|
|
11
12
|
export * from './plugins/link-highlight';
|
|
12
13
|
export * from './plugins/list';
|
package/es/index.js
CHANGED
|
@@ -7,6 +7,7 @@ export * from "./plugins/common";
|
|
|
7
7
|
export * from "./plugins/file";
|
|
8
8
|
export * from "./plugins/hr";
|
|
9
9
|
export * from "./plugins/image";
|
|
10
|
+
export * from "./plugins/inode";
|
|
10
11
|
export * from "./plugins/link";
|
|
11
12
|
export * from "./plugins/link-highlight";
|
|
12
13
|
export * from "./plugins/list";
|
|
@@ -3,9 +3,10 @@ function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyri
|
|
|
3
3
|
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
4
4
|
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
5
5
|
import { $isCodeHighlightNode, $isCodeNode } from '@lexical/code';
|
|
6
|
-
import { $isHeadingNode } from '@lexical/rich-text';
|
|
6
|
+
import { $isHeadingNode, QuoteNode } from '@lexical/rich-text';
|
|
7
7
|
import { mergeRegister } from '@lexical/utils';
|
|
8
|
-
import { $createNodeSelection, $createParagraphNode, $getRoot, $getSelection, $isDecoratorNode, $isElementNode, $isLineBreakNode, $isNodeSelection, $isRangeSelection, $isRootOrShadowRoot, $isTextNode, $setSelection, COMMAND_PRIORITY_EDITOR, COMMAND_PRIORITY_NORMAL, FORMAT_TEXT_COMMAND, KEY_ARROW_DOWN_COMMAND, KEY_ARROW_RIGHT_COMMAND, KEY_ARROW_UP_COMMAND, KEY_BACKSPACE_COMMAND, REDO_COMMAND, UNDO_COMMAND } from 'lexical';
|
|
8
|
+
import { $createNodeSelection, $createParagraphNode, $getRoot, $getSelection, $isDecoratorNode, $isElementNode, $isLineBreakNode, $isNodeSelection, $isRangeSelection, $isRootOrShadowRoot, $isTextNode, $setSelection, COMMAND_PRIORITY_EDITOR, COMMAND_PRIORITY_LOW, COMMAND_PRIORITY_NORMAL, FORMAT_TEXT_COMMAND, KEY_ARROW_DOWN_COMMAND, KEY_ARROW_RIGHT_COMMAND, KEY_ARROW_UP_COMMAND, KEY_BACKSPACE_COMMAND, REDO_COMMAND, UNDO_COMMAND } from 'lexical';
|
|
9
|
+
import { $closest } from "../../../editor-kernel";
|
|
9
10
|
import { HotkeyEnum } from "../../../types/hotkey";
|
|
10
11
|
function resolveElement(element, isBackward, focusOffset) {
|
|
11
12
|
var parent = element.getParent();
|
|
@@ -246,6 +247,40 @@ export function registerRichKeydown(editor, kernel, options) {
|
|
|
246
247
|
}
|
|
247
248
|
return false;
|
|
248
249
|
}, COMMAND_PRIORITY_EDITOR), kernel.registerHighCommand(KEY_ARROW_DOWN_COMMAND, function (event) {
|
|
250
|
+
var selection = $getSelection();
|
|
251
|
+
if ($isRangeSelection(selection)) {
|
|
252
|
+
if (!selection.isCollapsed()) {
|
|
253
|
+
return false;
|
|
254
|
+
}
|
|
255
|
+
var focusNode = selection.focus.getNode();
|
|
256
|
+
var quotaNode = $closest(focusNode, function (node) {
|
|
257
|
+
return node.getType() === QuoteNode.getType();
|
|
258
|
+
});
|
|
259
|
+
if (!quotaNode) {
|
|
260
|
+
return false;
|
|
261
|
+
}
|
|
262
|
+
if (quotaNode.getNextSibling()) {
|
|
263
|
+
return false;
|
|
264
|
+
}
|
|
265
|
+
var lastChild = quotaNode.getLastChild();
|
|
266
|
+
if (!lastChild) {
|
|
267
|
+
return false;
|
|
268
|
+
}
|
|
269
|
+
if (!$closest(focusNode, function (node) {
|
|
270
|
+
return node === lastChild;
|
|
271
|
+
})) {
|
|
272
|
+
return false;
|
|
273
|
+
}
|
|
274
|
+
event.preventDefault();
|
|
275
|
+
editor.update(function () {
|
|
276
|
+
var paragraph = $createParagraphNode();
|
|
277
|
+
quotaNode.insertAfter(paragraph);
|
|
278
|
+
paragraph.select();
|
|
279
|
+
});
|
|
280
|
+
return true;
|
|
281
|
+
}
|
|
282
|
+
return false;
|
|
283
|
+
}, COMMAND_PRIORITY_LOW), kernel.registerHighCommand(KEY_ARROW_DOWN_COMMAND, function (event) {
|
|
249
284
|
var selection = $getSelection();
|
|
250
285
|
if ($isNodeSelection(selection)) {
|
|
251
286
|
// If selection is on a node, let's try and move selection
|
|
@@ -174,7 +174,7 @@ export function $createBlockImageNode(_ref) {
|
|
|
174
174
|
var altText = _ref.altText,
|
|
175
175
|
height = _ref.height,
|
|
176
176
|
_ref$maxWidth = _ref.maxWidth,
|
|
177
|
-
maxWidth = _ref$maxWidth === void 0 ?
|
|
177
|
+
maxWidth = _ref$maxWidth === void 0 ? 4200 : _ref$maxWidth,
|
|
178
178
|
src = _ref.src,
|
|
179
179
|
width = _ref.width,
|
|
180
180
|
key = _ref.key;
|
|
@@ -18,6 +18,7 @@ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol"
|
|
|
18
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
19
|
import { INodeHelper } from "../../../editor-kernel/inode/helper";
|
|
20
20
|
import { KernelPlugin } from "../../../editor-kernel/plugin";
|
|
21
|
+
import { INodeService } from "../../inode";
|
|
21
22
|
import { ILitexmlService } from "../../litexml";
|
|
22
23
|
import { IMarkdownShortCutService } from "../../markdown/service/shortcut";
|
|
23
24
|
import { IUploadService, UPLOAD_PRIORITY_HIGH } from "../../upload";
|
|
@@ -45,9 +46,10 @@ export var ImagePlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
|
45
46
|
key: "onInit",
|
|
46
47
|
value: function onInit(editor) {
|
|
47
48
|
var _this$config;
|
|
48
|
-
this.register(registerImageCommand(editor, this.config.handleUpload, (_this$config = this.config) === null || _this$config === void 0 ? void 0 : _this$config.defaultBlockImage));
|
|
49
|
+
this.register(registerImageCommand(editor, this.config.handleUpload, ((_this$config = this.config) === null || _this$config === void 0 ? void 0 : _this$config.defaultBlockImage) !== false));
|
|
49
50
|
this.registerMarkdown();
|
|
50
51
|
this.registerLiteXml();
|
|
52
|
+
this.registerINode();
|
|
51
53
|
this.registerUpload(editor);
|
|
52
54
|
}
|
|
53
55
|
}, {
|
|
@@ -70,7 +72,7 @@ export var ImagePlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
|
70
72
|
case 2:
|
|
71
73
|
imageWidth = _context.sent;
|
|
72
74
|
return _context.abrupt("return", editor.dispatchCommand(INSERT_IMAGE_COMMAND, {
|
|
73
|
-
block: (_this2$config = _this2.config) === null || _this2$config === void 0 ? void 0 : _this2$config.defaultBlockImage,
|
|
75
|
+
block: ((_this2$config = _this2.config) === null || _this2$config === void 0 ? void 0 : _this2$config.defaultBlockImage) !== false,
|
|
74
76
|
file: file,
|
|
75
77
|
maxWidth: imageWidth,
|
|
76
78
|
range: range
|
|
@@ -145,6 +147,8 @@ export var ImagePlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
|
145
147
|
}, {
|
|
146
148
|
key: "registerMarkdown",
|
|
147
149
|
value: function registerMarkdown() {
|
|
150
|
+
var _this$config2;
|
|
151
|
+
var defaultBlockImage = ((_this$config2 = this.config) === null || _this$config2 === void 0 ? void 0 : _this$config2.defaultBlockImage) !== false;
|
|
148
152
|
var markdownService = this.kernel.requireService(IMarkdownShortCutService);
|
|
149
153
|
if (!markdownService) {
|
|
150
154
|
return;
|
|
@@ -162,7 +166,7 @@ export var ImagePlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
|
162
166
|
markdownService.registerMarkdownReader('image', function (node) {
|
|
163
167
|
var altText = node.alt;
|
|
164
168
|
var src = node.url;
|
|
165
|
-
return INodeHelper.createTypeNode(ImageNode.getType(), {
|
|
169
|
+
return INodeHelper.createTypeNode(defaultBlockImage ? BlockImageNode.getType() : ImageNode.getType(), {
|
|
166
170
|
altText: altText,
|
|
167
171
|
showCaption: false,
|
|
168
172
|
src: src,
|
|
@@ -170,6 +174,32 @@ export var ImagePlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
|
170
174
|
});
|
|
171
175
|
});
|
|
172
176
|
}
|
|
177
|
+
}, {
|
|
178
|
+
key: "registerINode",
|
|
179
|
+
value: function registerINode() {
|
|
180
|
+
var service = this.kernel.requireService(INodeService);
|
|
181
|
+
if (!service) {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
service.registerProcessNodeTree(function (_ref2) {
|
|
185
|
+
var root = _ref2.root;
|
|
186
|
+
// Process the root node
|
|
187
|
+
var loopNodes = function loopNodes(node) {
|
|
188
|
+
if ('children' in node && Array.isArray(node.children)) {
|
|
189
|
+
if (node.type === 'paragraph' && node.children.length === 1 && node.children[0].type === BlockImageNode.getType()) {
|
|
190
|
+
return node.children[0];
|
|
191
|
+
}
|
|
192
|
+
node.children = node.children.map(function (child) {
|
|
193
|
+
return loopNodes(child);
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
return node;
|
|
197
|
+
};
|
|
198
|
+
root.children = root.children.map(function (child) {
|
|
199
|
+
return loopNodes(child);
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
}
|
|
173
203
|
}, {
|
|
174
204
|
key: "getImageWidth",
|
|
175
205
|
value: function getImageWidth(file) {
|
|
@@ -212,7 +212,7 @@ var Image = /*#__PURE__*/memo(function (_ref) {
|
|
|
212
212
|
children: [children, showScaleInfo && isSelected && scale !== 1 && /*#__PURE__*/_jsxs("div", {
|
|
213
213
|
className: styles.scaleInfo,
|
|
214
214
|
children: [Math.round(scale * 100), "%"]
|
|
215
|
-
}), isHovered && /*#__PURE__*/_jsxs(_Fragment, {
|
|
215
|
+
}), isHovered && node.status === 'uploaded' && /*#__PURE__*/_jsxs(_Fragment, {
|
|
216
216
|
children: [/*#__PURE__*/_jsx(ResizeHandle, {
|
|
217
217
|
imageRef: imageRef,
|
|
218
218
|
isBlock: isBlock,
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { IEditorPluginConstructor } from "../../../types";
|
|
2
|
+
/**
|
|
3
|
+
* NodePluginOptions - Configuration options for the Node plugin
|
|
4
|
+
*/
|
|
5
|
+
export interface INodePluginOptions {
|
|
6
|
+
/**
|
|
7
|
+
* Enable or disable the node data source
|
|
8
|
+
* @default true
|
|
9
|
+
*/
|
|
10
|
+
enabled?: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* LitexmlPlugin - A plugin that provides XML-based data source support
|
|
14
|
+
* Allows converting between Lexical editor state and XML format
|
|
15
|
+
*/
|
|
16
|
+
export declare const INodePlugin: IEditorPluginConstructor<INodePluginOptions>;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
var _class;
|
|
2
|
+
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); }
|
|
3
|
+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
4
|
+
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); } }
|
|
5
|
+
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
|
|
6
|
+
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); }
|
|
7
|
+
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
|
|
8
|
+
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); }; }
|
|
9
|
+
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); }
|
|
10
|
+
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
|
11
|
+
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; } }
|
|
12
|
+
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
|
|
13
|
+
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; }
|
|
14
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
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
|
+
import { KernelPlugin } from "../../../editor-kernel/plugin";
|
|
17
|
+
import { INodeService, NodeService } from "../service";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* NodePluginOptions - Configuration options for the Node plugin
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* LitexmlPlugin - A plugin that provides XML-based data source support
|
|
25
|
+
* Allows converting between Lexical editor state and XML format
|
|
26
|
+
*/
|
|
27
|
+
export var INodePlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
28
|
+
_inherits(INodePlugin, _KernelPlugin);
|
|
29
|
+
var _super = _createSuper(INodePlugin);
|
|
30
|
+
function INodePlugin(kernel, config) {
|
|
31
|
+
var _this;
|
|
32
|
+
_classCallCheck(this, INodePlugin);
|
|
33
|
+
_this = _super.call(this);
|
|
34
|
+
|
|
35
|
+
// Create and register the Node service
|
|
36
|
+
_this.kernel = kernel;
|
|
37
|
+
_this.config = config;
|
|
38
|
+
var nodeService = new NodeService();
|
|
39
|
+
kernel.registerService(INodeService, nodeService);
|
|
40
|
+
return _this;
|
|
41
|
+
}
|
|
42
|
+
_createClass(INodePlugin, [{
|
|
43
|
+
key: "onInit",
|
|
44
|
+
value: function onInit() {
|
|
45
|
+
// Plugin initialization logic can be added here if needed
|
|
46
|
+
}
|
|
47
|
+
}]);
|
|
48
|
+
return INodePlugin;
|
|
49
|
+
}(KernelPlugin), _defineProperty(_class, "pluginName", 'INodePlugin'), _class);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
4
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
5
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
6
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
7
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
8
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
9
|
+
import { useLayoutEffect } from 'react';
|
|
10
|
+
import { useLexicalComposerContext } from "../../../editor-kernel/react";
|
|
11
|
+
import { INodePlugin } from "../plugin";
|
|
12
|
+
export var ReactNodePlugin = function ReactNodePlugin() {
|
|
13
|
+
var _useLexicalComposerCo = useLexicalComposerContext(),
|
|
14
|
+
_useLexicalComposerCo2 = _slicedToArray(_useLexicalComposerCo, 1),
|
|
15
|
+
editor = _useLexicalComposerCo2[0];
|
|
16
|
+
useLayoutEffect(function () {
|
|
17
|
+
editor.registerPlugin(INodePlugin);
|
|
18
|
+
}, [editor]);
|
|
19
|
+
return null;
|
|
20
|
+
};
|
|
21
|
+
ReactNodePlugin.displayName = 'ReactNodePlugin';
|
|
22
|
+
export default ReactNodePlugin;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { IRootNode } from "../../../editor-kernel/inode";
|
|
2
|
+
export interface INodeService {
|
|
3
|
+
processNodeTree(inode: {
|
|
4
|
+
root: IRootNode;
|
|
5
|
+
}): void;
|
|
6
|
+
registerProcessNodeTree(process: (inode: {
|
|
7
|
+
root: IRootNode;
|
|
8
|
+
}) => void): void;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Service ID for Node service
|
|
12
|
+
*/
|
|
13
|
+
export declare const INodeService: import("../../../types").IServiceID<INodeService>;
|
|
14
|
+
/**
|
|
15
|
+
* Default implementation of INodeService
|
|
16
|
+
*/
|
|
17
|
+
export declare class NodeService implements INodeService {
|
|
18
|
+
private processNodeTreeHandlers;
|
|
19
|
+
registerProcessNodeTree(process: (inode: {
|
|
20
|
+
root: IRootNode;
|
|
21
|
+
}) => void): void;
|
|
22
|
+
processNodeTree(inode: {
|
|
23
|
+
root: IRootNode;
|
|
24
|
+
}): void;
|
|
25
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
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 _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
|
|
3
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
4
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
5
|
+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
6
|
+
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); } }
|
|
7
|
+
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
|
|
8
|
+
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; }
|
|
9
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
10
|
+
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); }
|
|
11
|
+
import { genServiceId } from "../../../editor-kernel";
|
|
12
|
+
/**
|
|
13
|
+
* Service ID for Node service
|
|
14
|
+
*/
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/no-redeclare, no-redeclare
|
|
16
|
+
export var INodeService = genServiceId('INodeService');
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Default implementation of INodeService
|
|
20
|
+
*/
|
|
21
|
+
export var NodeService = /*#__PURE__*/function () {
|
|
22
|
+
function NodeService() {
|
|
23
|
+
_classCallCheck(this, NodeService);
|
|
24
|
+
_defineProperty(this, "processNodeTreeHandlers", []);
|
|
25
|
+
}
|
|
26
|
+
_createClass(NodeService, [{
|
|
27
|
+
key: "registerProcessNodeTree",
|
|
28
|
+
value: function registerProcessNodeTree(process) {
|
|
29
|
+
this.processNodeTreeHandlers.push(process);
|
|
30
|
+
}
|
|
31
|
+
}, {
|
|
32
|
+
key: "processNodeTree",
|
|
33
|
+
value: function processNodeTree(inode) {
|
|
34
|
+
var _iterator = _createForOfIteratorHelper(this.processNodeTreeHandlers),
|
|
35
|
+
_step;
|
|
36
|
+
try {
|
|
37
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
38
|
+
var handler = _step.value;
|
|
39
|
+
handler(inode);
|
|
40
|
+
}
|
|
41
|
+
} catch (err) {
|
|
42
|
+
_iterator.e(err);
|
|
43
|
+
} finally {
|
|
44
|
+
_iterator.f();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}]);
|
|
48
|
+
return NodeService;
|
|
49
|
+
}();
|
|
@@ -1,6 +1,7 @@
|
|
|
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 { IServiceID } from "../../../types";
|
|
4
5
|
import type { ILitexmlService } from '../service/litexml-service';
|
|
5
6
|
/**
|
|
6
7
|
* LitexmlDataSource - Handles conversion between Lexical editor state and XML format
|
|
@@ -8,9 +9,10 @@ import type { ILitexmlService } from '../service/litexml-service';
|
|
|
8
9
|
*/
|
|
9
10
|
export default class LitexmlDataSource extends DataSource {
|
|
10
11
|
protected dataType: string;
|
|
12
|
+
protected getService?: (<T>(serviceId: IServiceID<T>) => T | null) | undefined;
|
|
11
13
|
private litexmlService;
|
|
12
14
|
private ctx;
|
|
13
|
-
constructor(dataType?: string, service?: ILitexmlService);
|
|
15
|
+
constructor(dataType?: string, getService?: (<T>(serviceId: IServiceID<T>) => T | null) | undefined, service?: ILitexmlService);
|
|
14
16
|
readLiteXMLToInode(litexml: string): any;
|
|
15
17
|
/**
|
|
16
18
|
* Parse XML string and set it to the editor
|
|
@@ -30,8 +30,10 @@ import { DOMParser } from '@xmldom/xmldom';
|
|
|
30
30
|
import { $getRoot, $getSelection, $isElementNode, $isRangeSelection } from 'lexical';
|
|
31
31
|
import { DataSource } from "../../../editor-kernel";
|
|
32
32
|
import { INodeHelper } from "../../../editor-kernel/inode/helper";
|
|
33
|
+
import { INodeService } from "../../inode";
|
|
33
34
|
import { createDebugLogger } from "../../../utils/debug";
|
|
34
35
|
import { LitexmlService } from "../service/litexml-service";
|
|
36
|
+
import { charToId, idToChar } from "../utils";
|
|
35
37
|
var logger = createDebugLogger('plugin', 'litexml');
|
|
36
38
|
var IXmlWriterContext = /*#__PURE__*/function () {
|
|
37
39
|
function IXmlWriterContext() {
|
|
@@ -60,23 +62,27 @@ var LitexmlDataSource = /*#__PURE__*/function (_DataSource) {
|
|
|
60
62
|
function LitexmlDataSource() {
|
|
61
63
|
var _this;
|
|
62
64
|
var dataType = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'litexml';
|
|
63
|
-
var
|
|
65
|
+
var getService = arguments.length > 1 ? arguments[1] : undefined;
|
|
66
|
+
var service = arguments.length > 2 ? arguments[2] : undefined;
|
|
64
67
|
_classCallCheck(this, LitexmlDataSource);
|
|
65
68
|
_this = _super.call(this, dataType);
|
|
66
69
|
_defineProperty(_assertThisInitialized(_this), "litexmlService", void 0);
|
|
67
70
|
_defineProperty(_assertThisInitialized(_this), "ctx", new IXmlWriterContext());
|
|
68
71
|
_this.dataType = dataType;
|
|
72
|
+
_this.getService = getService;
|
|
69
73
|
_this.litexmlService = service || new LitexmlService();
|
|
70
74
|
return _this;
|
|
71
75
|
}
|
|
72
76
|
_createClass(LitexmlDataSource, [{
|
|
73
77
|
key: "readLiteXMLToInode",
|
|
74
78
|
value: function readLiteXMLToInode(litexml) {
|
|
79
|
+
var _this$getService;
|
|
75
80
|
if (typeof litexml !== 'string') {
|
|
76
81
|
throw new Error('Invalid data type. Expected string, got ' + _typeof(litexml));
|
|
77
82
|
}
|
|
78
83
|
var xml = this.parseXMLString(litexml);
|
|
79
84
|
var inode = this.xmlToLexical(xml);
|
|
85
|
+
(_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);
|
|
80
86
|
logger.debug('Parsed XML to Lexical State:', inode);
|
|
81
87
|
return inode;
|
|
82
88
|
}
|
|
@@ -214,7 +220,8 @@ var LitexmlDataSource = /*#__PURE__*/function (_DataSource) {
|
|
|
214
220
|
if (Array.isArray(result)) {
|
|
215
221
|
INodeHelper.appendChild.apply(INodeHelper, [parentNode].concat(_toConsumableArray(result)));
|
|
216
222
|
} else if (result) {
|
|
217
|
-
|
|
223
|
+
var attrId = xmlElement.getAttribute('id');
|
|
224
|
+
result.id = attrId ? charToId(attrId) : undefined;
|
|
218
225
|
INodeHelper.appendChild(parentNode, result);
|
|
219
226
|
}
|
|
220
227
|
return; // Custom reader handled it
|
|
@@ -364,7 +371,7 @@ var LitexmlDataSource = /*#__PURE__*/function (_DataSource) {
|
|
|
364
371
|
var handled = writer(node, this.ctx, indent);
|
|
365
372
|
if (handled) {
|
|
366
373
|
var attrs = this.buildXMLAttributes(_objectSpread({
|
|
367
|
-
id: node.getKey()
|
|
374
|
+
id: idToChar(node.getKey())
|
|
368
375
|
}, handled.attributes));
|
|
369
376
|
var openTag = "".concat(indentStr, "<").concat(handled.tagName).concat(attrs, ">");
|
|
370
377
|
var closeTag = "</".concat(handled.tagName, ">");
|
|
@@ -40,7 +40,9 @@ export var LitexmlPlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
|
40
40
|
_this.config = config;
|
|
41
41
|
var litexmlService = new LitexmlService();
|
|
42
42
|
kernel.registerService(ILitexmlService, litexmlService);
|
|
43
|
-
_this.datasource = new LitexmlDataSource('litexml',
|
|
43
|
+
_this.datasource = new LitexmlDataSource('litexml', function (serviceId) {
|
|
44
|
+
return kernel.requireService(serviceId);
|
|
45
|
+
}, litexmlService);
|
|
44
46
|
|
|
45
47
|
// Register the litexml data source
|
|
46
48
|
if ((config === null || config === void 0 ? void 0 : config.enabled) !== false) {
|
|
@@ -8,12 +8,14 @@ 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";
|
|
12
13
|
export var ReactLiteXmlPlugin = function ReactLiteXmlPlugin() {
|
|
13
14
|
var _useLexicalComposerCo = useLexicalComposerContext(),
|
|
14
15
|
_useLexicalComposerCo2 = _slicedToArray(_useLexicalComposerCo, 1),
|
|
15
16
|
editor = _useLexicalComposerCo2[0];
|
|
16
17
|
useLayoutEffect(function () {
|
|
18
|
+
editor.registerPlugin(INodePlugin);
|
|
17
19
|
editor.registerPlugin(LitexmlPlugin);
|
|
18
20
|
}, [editor]);
|
|
19
21
|
return null;
|
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
import { LexicalEditor, LexicalNode } from 'lexical';
|
|
2
2
|
export declare function $parseSerializedNodeImpl(serializedNode: any, editor: LexicalEditor): LexicalNode;
|
|
3
|
+
export declare function idToChar(id: string | number): string;
|
|
4
|
+
export declare function charToId(char: string): string;
|
|
@@ -30,4 +30,17 @@ export function $parseSerializedNodeImpl(serializedNode, editor) {
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
return node;
|
|
33
|
+
}
|
|
34
|
+
var maxId = 1679616; // 36^4
|
|
35
|
+
var startId = 1000000; // to avoid short ids
|
|
36
|
+
var step = 7211; // a prime number to reduce collisions
|
|
37
|
+
var modInverse = 1394051; // modular inverse of step mod maxId
|
|
38
|
+
|
|
39
|
+
export function idToChar(id) {
|
|
40
|
+
var nId = (Number(id) * step + startId) % maxId;
|
|
41
|
+
return nId.toString(36).padStart(4, '0');
|
|
42
|
+
}
|
|
43
|
+
export function charToId(char) {
|
|
44
|
+
var nId = parseInt(char, 36);
|
|
45
|
+
return String((nId - startId + maxId) * modInverse % maxId);
|
|
33
46
|
}
|
|
@@ -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
|
-
|
|
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
|
-
|
|
39
|
-
|
|
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,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobehub/editor",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.32.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>",
|