@lobehub/editor 1.14.1 → 1.15.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/plugins/common/plugin/index.d.ts +14 -0
- package/es/plugins/common/plugin/index.js +109 -58
- package/es/plugins/common/react/ReactPlainText.js +12 -5
- package/es/plugins/common/react/style.d.ts +15 -1
- package/es/plugins/common/react/style.js +18 -11
- package/es/plugins/common/react/type.d.ts +10 -0
- package/es/plugins/markdown/plugin/index.d.ts +5 -0
- package/es/plugins/markdown/plugin/index.js +14 -7
- package/es/react/Editor/Editor.js +6 -0
- package/es/react/Editor/type.d.ts +15 -0
- package/package.json +1 -1
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
import type { IEditorPluginConstructor } from "../../../types";
|
|
2
2
|
export interface CommonPluginOptions {
|
|
3
3
|
enableHotkey?: boolean;
|
|
4
|
+
/**
|
|
5
|
+
* Enable/disable markdown shortcuts
|
|
6
|
+
* @default true - all formats enabled
|
|
7
|
+
*/
|
|
8
|
+
markdownOption?: boolean | {
|
|
9
|
+
bold?: boolean;
|
|
10
|
+
code?: boolean;
|
|
11
|
+
header?: boolean;
|
|
12
|
+
italic?: boolean;
|
|
13
|
+
quote?: boolean;
|
|
14
|
+
strikethrough?: boolean;
|
|
15
|
+
underline?: boolean;
|
|
16
|
+
underlineStrikethrough?: boolean;
|
|
17
|
+
};
|
|
4
18
|
theme?: {
|
|
5
19
|
quote?: string;
|
|
6
20
|
textBold?: string;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
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
2
|
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
4
3
|
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
5
4
|
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
5
|
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
|
|
7
6
|
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
8
7
|
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; }
|
|
8
|
+
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); }
|
|
9
9
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
10
10
|
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); } }
|
|
11
11
|
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
|
|
@@ -33,8 +33,8 @@ import TextDataSource from "../data-source/text-data-source";
|
|
|
33
33
|
import { patchBreakLine, registerBreakLineClick } from "../node/ElementDOMSlot";
|
|
34
34
|
import { CursorNode, registerCursorNode } from "../node/cursor";
|
|
35
35
|
import { createBlockNode } from "../utils";
|
|
36
|
-
import { registerHeaderBackspace, registerLastElement, registerRichKeydown } from "./register";
|
|
37
36
|
import { registerMDReader } from "./mdReader";
|
|
37
|
+
import { registerHeaderBackspace, registerLastElement, registerRichKeydown } from "./register";
|
|
38
38
|
patchBreakLine();
|
|
39
39
|
export var CommonPlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
40
40
|
_inherits(CommonPlugin, _KernelPlugin);
|
|
@@ -73,64 +73,112 @@ export var CommonPlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
|
73
73
|
_createClass(CommonPlugin, [{
|
|
74
74
|
key: "registerMarkdown",
|
|
75
75
|
value: function registerMarkdown(kernel) {
|
|
76
|
+
var _this$config$markdown, _this$config;
|
|
76
77
|
var markdownService = kernel.requireService(IMarkdownShortCutService);
|
|
77
78
|
if (!markdownService) {
|
|
78
79
|
return;
|
|
79
80
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
81
|
+
|
|
82
|
+
// Parse markdown options
|
|
83
|
+
var markdownOption = (_this$config$markdown = (_this$config = this.config) === null || _this$config === void 0 ? void 0 : _this$config.markdownOption) !== null && _this$config$markdown !== void 0 ? _this$config$markdown : true;
|
|
84
|
+
var isMarkdownEnabled = markdownOption !== false;
|
|
85
|
+
|
|
86
|
+
// Determine which formats are enabled
|
|
87
|
+
var formats = {
|
|
88
|
+
bold: true,
|
|
89
|
+
header: true,
|
|
90
|
+
italic: true,
|
|
91
|
+
quote: true,
|
|
92
|
+
strikethrough: true
|
|
93
|
+
// Note: code, underline, underlineStrikethrough are handled by other plugins/writers
|
|
94
|
+
};
|
|
95
|
+
if (_typeof(markdownOption) === 'object') {
|
|
96
|
+
var _markdownOption$bold, _markdownOption$heade, _markdownOption$itali, _markdownOption$quote, _markdownOption$strik;
|
|
97
|
+
formats.bold = (_markdownOption$bold = markdownOption.bold) !== null && _markdownOption$bold !== void 0 ? _markdownOption$bold : true;
|
|
98
|
+
formats.header = (_markdownOption$heade = markdownOption.header) !== null && _markdownOption$heade !== void 0 ? _markdownOption$heade : true;
|
|
99
|
+
formats.italic = (_markdownOption$itali = markdownOption.italic) !== null && _markdownOption$itali !== void 0 ? _markdownOption$itali : true;
|
|
100
|
+
formats.quote = (_markdownOption$quote = markdownOption.quote) !== null && _markdownOption$quote !== void 0 ? _markdownOption$quote : true;
|
|
101
|
+
formats.strikethrough = (_markdownOption$strik = markdownOption.strikethrough) !== null && _markdownOption$strik !== void 0 ? _markdownOption$strik : true;
|
|
102
|
+
}
|
|
103
|
+
if (!isMarkdownEnabled) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Register quote shortcut if enabled
|
|
108
|
+
if (formats.quote) {
|
|
109
|
+
markdownService.registerMarkdownShortCut({
|
|
110
|
+
regExp: /^>\s/,
|
|
111
|
+
replace: function replace(parentNode, children, _match, isImport) {
|
|
112
|
+
if (isImport) {
|
|
113
|
+
var previousNode = parentNode.getPreviousSibling();
|
|
114
|
+
if ($isQuoteNode(previousNode)) {
|
|
115
|
+
previousNode.splice(previousNode.getChildrenSize(), 0, [$createLineBreakNode()].concat(_toConsumableArray(children)));
|
|
116
|
+
parentNode.remove();
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
89
119
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
120
|
+
var node = $createQuoteNode();
|
|
121
|
+
node.append.apply(node, _toConsumableArray(children));
|
|
122
|
+
parentNode.replace(node);
|
|
123
|
+
if (!isImport) {
|
|
124
|
+
node.select(0, 0);
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
type: 'element'
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Register header shortcut if enabled
|
|
132
|
+
if (formats.header) {
|
|
133
|
+
markdownService.registerMarkdownShortCut({
|
|
134
|
+
regExp: /^(#{1,6})\s/,
|
|
135
|
+
replace: createBlockNode(function (match, parentNode) {
|
|
136
|
+
var tag = 'h' + match[1].length;
|
|
137
|
+
if ($isHeadingNode(parentNode) && parentNode.getTag() === tag) {
|
|
138
|
+
return $createParagraphNode();
|
|
139
|
+
}
|
|
140
|
+
return $createHeadingNode(tag);
|
|
141
|
+
}),
|
|
142
|
+
type: 'element'
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Register text format shortcuts based on enabled formats
|
|
147
|
+
var textFormatShortcuts = [];
|
|
148
|
+
if (formats.bold) {
|
|
149
|
+
textFormatShortcuts.push({
|
|
150
|
+
format: ['bold'],
|
|
151
|
+
tag: '**',
|
|
152
|
+
type: 'text-format'
|
|
153
|
+
}, {
|
|
154
|
+
format: ['bold'],
|
|
155
|
+
intraword: false,
|
|
156
|
+
tag: '__',
|
|
157
|
+
type: 'text-format'
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
if (formats.strikethrough) {
|
|
161
|
+
textFormatShortcuts.push({
|
|
162
|
+
format: ['strikethrough'],
|
|
163
|
+
tag: '~~',
|
|
164
|
+
type: 'text-format'
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
if (formats.italic) {
|
|
168
|
+
textFormatShortcuts.push({
|
|
169
|
+
format: ['italic'],
|
|
170
|
+
tag: '*',
|
|
171
|
+
type: 'text-format'
|
|
172
|
+
}, {
|
|
173
|
+
format: ['italic'],
|
|
174
|
+
intraword: false,
|
|
175
|
+
tag: '_',
|
|
176
|
+
type: 'text-format'
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Always register superscript and subscript (not in options)
|
|
181
|
+
textFormatShortcuts.push({
|
|
134
182
|
format: ['superscript'],
|
|
135
183
|
tag: '^',
|
|
136
184
|
type: 'text-format'
|
|
@@ -138,7 +186,10 @@ export var CommonPlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
|
138
186
|
format: ['subscript'],
|
|
139
187
|
tag: '~',
|
|
140
188
|
type: 'text-format'
|
|
141
|
-
}
|
|
189
|
+
});
|
|
190
|
+
if (textFormatShortcuts.length > 0) {
|
|
191
|
+
markdownService.registerMarkdownShortCuts(textFormatShortcuts);
|
|
192
|
+
}
|
|
142
193
|
markdownService.registerMarkdownWriter('paragraph', function (ctx) {
|
|
143
194
|
ctx.wrap('', '\n\n');
|
|
144
195
|
});
|
|
@@ -263,9 +314,9 @@ export var CommonPlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
|
263
314
|
}, {
|
|
264
315
|
key: "onInit",
|
|
265
316
|
value: function onInit(editor) {
|
|
266
|
-
var _this$
|
|
317
|
+
var _this$config2;
|
|
267
318
|
this.registerClears(registerRichText(editor), registerDragonSupport(editor), registerHistory(editor, createEmptyHistoryState(), 300), registerHeaderBackspace(editor), registerRichKeydown(editor, this.kernel, {
|
|
268
|
-
enableHotkey: (_this$
|
|
319
|
+
enableHotkey: (_this$config2 = this.config) === null || _this$config2 === void 0 ? void 0 : _this$config2.enableHotkey
|
|
269
320
|
}), registerCommands(editor), registerBreakLineClick(editor), registerCursorNode(editor), registerLastElement(editor));
|
|
270
321
|
this.registerMarkdown(this.kernel);
|
|
271
322
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
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); }
|
|
4
3
|
var _excluded = ["fontSize", "headerMultiple", "lineHeight", "marginMultiple"];
|
|
4
|
+
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); }
|
|
5
5
|
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; }
|
|
6
6
|
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; }
|
|
7
7
|
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; }
|
|
@@ -36,6 +36,10 @@ var ReactPlainText = /*#__PURE__*/memo(function (_ref) {
|
|
|
36
36
|
variant = _ref.variant,
|
|
37
37
|
_ref$enableHotkey = _ref.enableHotkey,
|
|
38
38
|
enableHotkey = _ref$enableHotkey === void 0 ? true : _ref$enableHotkey,
|
|
39
|
+
_ref$enablePasteMarkd = _ref.enablePasteMarkdown,
|
|
40
|
+
enablePasteMarkdown = _ref$enablePasteMarkd === void 0 ? true : _ref$enablePasteMarkd,
|
|
41
|
+
_ref$markdownOption = _ref.markdownOption,
|
|
42
|
+
markdownOption = _ref$markdownOption === void 0 ? true : _ref$markdownOption,
|
|
39
43
|
onKeyDown = _ref.onKeyDown,
|
|
40
44
|
onFocus = _ref.onFocus,
|
|
41
45
|
onBlur = _ref.onBlur,
|
|
@@ -59,7 +63,7 @@ var ReactPlainText = /*#__PURE__*/memo(function (_ref) {
|
|
|
59
63
|
_useLexicalComposerCo2 = _slicedToArray(_useLexicalComposerCo, 1),
|
|
60
64
|
editor = _useLexicalComposerCo2[0];
|
|
61
65
|
var decorators = useDecorators(editor, LexicalErrorBoundary);
|
|
62
|
-
var _useThemeStyles = useThemeStyles(),
|
|
66
|
+
var _useThemeStyles = useThemeStyles(markdownOption),
|
|
63
67
|
themeStyles = _useThemeStyles.styles;
|
|
64
68
|
var _useStyles = useStyles({
|
|
65
69
|
fontSize: fontSize,
|
|
@@ -79,12 +83,15 @@ var ReactPlainText = /*#__PURE__*/memo(function (_ref) {
|
|
|
79
83
|
content = _Children$only$props.content,
|
|
80
84
|
placeholder = _Children$only$props.placeholder;
|
|
81
85
|
useLayoutEffect(function () {
|
|
82
|
-
editor.registerPlugin(MarkdownPlugin
|
|
86
|
+
editor.registerPlugin(MarkdownPlugin, {
|
|
87
|
+
enablePasteMarkdown: enablePasteMarkdown
|
|
88
|
+
});
|
|
83
89
|
editor.registerPlugin(CommonPlugin, {
|
|
84
90
|
enableHotkey: enableHotkey,
|
|
91
|
+
markdownOption: markdownOption,
|
|
85
92
|
theme: restTheme ? _objectSpread(_objectSpread({}, themeStyles), restTheme) : themeStyles
|
|
86
93
|
});
|
|
87
|
-
}, [editor, enableHotkey, restTheme, themeStyles]);
|
|
94
|
+
}, [editor, enableHotkey, enablePasteMarkdown, markdownOption, restTheme, themeStyles]);
|
|
88
95
|
useEffect(function () {
|
|
89
96
|
var _editor$getLexicalEdi;
|
|
90
97
|
var container = editorContainerRef.current;
|
|
@@ -159,7 +166,7 @@ var ReactPlainText = /*#__PURE__*/memo(function (_ref) {
|
|
|
159
166
|
});
|
|
160
167
|
};
|
|
161
168
|
return /*#__PURE__*/_jsxs("div", {
|
|
162
|
-
className: cx(styles.root, styles.variant, className),
|
|
169
|
+
className: cx(styles.root, markdownOption === true && styles.variant, markdownOption === false && styles.noHeader, _typeof(markdownOption) === 'object' && markdownOption.header === true && styles.header, _typeof(markdownOption) === 'object' && markdownOption.header === false && styles.noHeader, _typeof(markdownOption) === 'object' && markdownOption.code === true && styles.code, _typeof(markdownOption) === 'object' && markdownOption.quote === true && styles.blockquote, className),
|
|
163
170
|
style: style,
|
|
164
171
|
children: [/*#__PURE__*/_jsx("div", {
|
|
165
172
|
contentEditable: true,
|
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
export declare const useThemeStyles: (props?:
|
|
1
|
+
export declare const useThemeStyles: (props?: boolean | {
|
|
2
|
+
bold?: boolean | undefined;
|
|
3
|
+
code?: boolean | undefined;
|
|
4
|
+
header?: boolean | undefined;
|
|
5
|
+
italic?: boolean | undefined;
|
|
6
|
+
quote?: boolean | undefined;
|
|
7
|
+
strikethrough?: boolean | undefined;
|
|
8
|
+
underline?: boolean | undefined;
|
|
9
|
+
underlineStrikethrough?: boolean | undefined;
|
|
10
|
+
} | undefined) => import("antd-style").ReturnStyles<{
|
|
2
11
|
quote: string;
|
|
3
12
|
textBold: import("antd-style").SerializedStyles;
|
|
4
13
|
textCode: string;
|
|
@@ -13,6 +22,11 @@ export declare const useStyles: (props?: {
|
|
|
13
22
|
lineHeight?: number | undefined;
|
|
14
23
|
marginMultiple?: number | undefined;
|
|
15
24
|
} | undefined) => import("antd-style").ReturnStyles<{
|
|
25
|
+
blockquote: import("antd-style").SerializedStyles;
|
|
26
|
+
code: import("antd-style").SerializedStyles;
|
|
27
|
+
header: import("antd-style").SerializedStyles;
|
|
28
|
+
noHeader: import("antd-style").SerializedStyles;
|
|
29
|
+
p: import("antd-style").SerializedStyles;
|
|
16
30
|
root: import("antd-style").SerializedStyles;
|
|
17
31
|
variant: string;
|
|
18
32
|
}>;
|
|
@@ -1,17 +1,19 @@
|
|
|
1
|
-
var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7, _templateObject8, _templateObject9, _templateObject10;
|
|
1
|
+
var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7, _templateObject8, _templateObject9, _templateObject10, _templateObject11, _templateObject12, _templateObject13, _templateObject14, _templateObject15, _templateObject16;
|
|
2
2
|
function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
|
|
3
|
+
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
4
|
import { createStyles } from 'antd-style';
|
|
4
5
|
export var useThemeStyles = createStyles(function (_ref) {
|
|
5
6
|
var css = _ref.css,
|
|
6
7
|
token = _ref.token;
|
|
8
|
+
var markdownOption = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
7
9
|
return {
|
|
8
10
|
quote: 'editor_quote',
|
|
9
|
-
textBold: css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n
|
|
11
|
+
textBold: markdownOption === true || _typeof(markdownOption) === 'object' && markdownOption.bold === true ? css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n font-weight: bold;\n "]))) : css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n font-weight: unset;\n "]))),
|
|
10
12
|
textCode: 'editor_code',
|
|
11
|
-
textItalic: css(
|
|
12
|
-
textStrikethrough: css(
|
|
13
|
-
textUnderline: css(
|
|
14
|
-
textUnderlineStrikethrough: css(
|
|
13
|
+
textItalic: markdownOption === true || _typeof(markdownOption) === 'object' && markdownOption.italic === true ? css(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n font-style: italic;\n "]))) : css(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["\n font-style: unset;\n "]))),
|
|
14
|
+
textStrikethrough: markdownOption === true || _typeof(markdownOption) === 'object' && markdownOption.strikethrough === true ? css(_templateObject5 || (_templateObject5 = _taggedTemplateLiteral(["\n color: ", ";\n text-decoration: line-through;\n "])), token.colorTextDescription) : css(_templateObject6 || (_templateObject6 = _taggedTemplateLiteral(["\n text-decoration: unset;\n "]))),
|
|
15
|
+
textUnderline: markdownOption === true || _typeof(markdownOption) === 'object' && markdownOption.strikethrough === true ? css(_templateObject7 || (_templateObject7 = _taggedTemplateLiteral(["\n text-decoration: underline;\n "]))) : css(_templateObject8 || (_templateObject8 = _taggedTemplateLiteral(["\n text-decoration: unset;\n "]))),
|
|
16
|
+
textUnderlineStrikethrough: markdownOption === true || _typeof(markdownOption) === 'object' && markdownOption.underlineStrikethrough === true ? css(_templateObject9 || (_templateObject9 = _taggedTemplateLiteral(["\n text-decoration: underline line-through;\n "]))) : css(_templateObject10 || (_templateObject10 = _taggedTemplateLiteral(["\n text-decoration: unset;\n "])))
|
|
15
17
|
};
|
|
16
18
|
});
|
|
17
19
|
export var useStyles = createStyles(function (_ref2, _ref3) {
|
|
@@ -26,12 +28,17 @@ export var useStyles = createStyles(function (_ref2, _ref3) {
|
|
|
26
28
|
marginMultiple = _ref3$marginMultiple === void 0 ? 2 : _ref3$marginMultiple,
|
|
27
29
|
_ref3$lineHeight = _ref3.lineHeight,
|
|
28
30
|
lineHeight = _ref3$lineHeight === void 0 ? 1.8 : _ref3$lineHeight;
|
|
29
|
-
var __root = css(
|
|
30
|
-
var header = css(
|
|
31
|
-
var p = css(
|
|
32
|
-
var blockquote = css(
|
|
33
|
-
var code = css(
|
|
31
|
+
var __root = css(_templateObject11 || (_templateObject11 = _taggedTemplateLiteral(["\n --lobe-markdown-font-size: ", "px;\n --lobe-markdown-header-multiple: ", ";\n --lobe-markdown-margin-multiple: ", ";\n --lobe-markdown-line-height: ", ";\n --lobe-markdown-border-radius: ", ";\n --lobe-markdown-border-color: ", ";\n\n position: relative;\n\n display: flex;\n flex-direction: column;\n\n width: 100%;\n max-width: 100%;\n height: 100%;\n\n font-size: var(--lobe-markdown-font-size);\n line-height: var(--lobe-markdown-line-height);\n word-break: break-word;\n\n @keyframes cursor-blink {\n to {\n visibility: hidden;\n }\n }\n\n [data-lexical-cursor='true'] {\n pointer-events: none;\n position: absolute;\n display: block;\n\n &::after {\n content: '';\n\n position: absolute;\n inset-block-start: -2px;\n\n display: block;\n\n width: 20px;\n border-block-start: 1px solid ", ";\n\n animation: cursor-blink 1.1s steps(2, start) infinite;\n }\n }\n "])), fontSize, headerMultiple, marginMultiple, lineHeight, token.borderRadiusLG, token.colorFillQuaternary, token.colorText);
|
|
32
|
+
var header = css(_templateObject12 || (_templateObject12 = _taggedTemplateLiteral(["\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n margin-block: max(\n calc(var(--lobe-markdown-header-multiple) * var(--lobe-markdown-margin-multiple) * 0.4em),\n var(--lobe-markdown-font-size)\n );\n font-weight: bold;\n line-height: 1.25;\n }\n\n h1 {\n font-size: calc(\n var(--lobe-markdown-font-size) * (1 + 1.5 * var(--lobe-markdown-header-multiple))\n );\n }\n\n h2 {\n font-size: calc(\n var(--lobe-markdown-font-size) * (1 + var(--lobe-markdown-header-multiple))\n );\n }\n\n h3 {\n font-size: calc(\n var(--lobe-markdown-font-size) * (1 + 0.5 * var(--lobe-markdown-header-multiple))\n );\n }\n\n h4 {\n font-size: calc(\n var(--lobe-markdown-font-size) * (1 + 0.25 * var(--lobe-markdown-header-multiple))\n );\n }\n\n h5,\n h6 {\n font-size: calc(var(--lobe-markdown-font-size) * 1);\n }\n "])));
|
|
33
|
+
var p = css(_templateObject13 || (_templateObject13 = _taggedTemplateLiteral(["\n p {\n margin-block: 4px;\n line-height: var(--lobe-markdown-line-height);\n letter-spacing: 0.02em;\n\n &:not(:first-child) {\n margin-block-start: calc(var(--lobe-markdown-margin-multiple) * 0.5em);\n }\n\n &:not(:last-child) {\n margin-block-end: calc(var(--lobe-markdown-margin-multiple) * 0.5em);\n }\n }\n "])));
|
|
34
|
+
var blockquote = css(_templateObject14 || (_templateObject14 = _taggedTemplateLiteral(["\n .editor_quote {\n margin-block: calc(var(--lobe-markdown-margin-multiple) * 0.5em);\n margin-inline: 0;\n padding-block: 0;\n padding-inline: 1em;\n border-inline-start: solid 4px ", ";\n\n color: ", ";\n }\n "])), token.colorBorder, token.colorTextSecondary);
|
|
35
|
+
var code = css(_templateObject15 || (_templateObject15 = _taggedTemplateLiteral(["\n .editor_code {\n display: inline;\n\n margin-inline: 0.25em;\n padding-block: 0.2em;\n padding-inline: 0.4em;\n border: 1px solid var(--lobe-markdown-border-color);\n border-radius: 0.25em;\n\n font-family: ", ";\n font-size: 0.875em;\n line-height: 1;\n word-break: break-word;\n white-space: break-spaces;\n\n background: ", ";\n }\n "])), token.fontFamilyCode, token.colorFillSecondary);
|
|
34
36
|
return {
|
|
37
|
+
blockquote: blockquote,
|
|
38
|
+
code: code,
|
|
39
|
+
header: header,
|
|
40
|
+
noHeader: css(_templateObject16 || (_templateObject16 = _taggedTemplateLiteral(["\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n margin-block: 4px;\n font-size: var(--lobe-markdown-font-size);\n line-height: var(--lobe-markdown-line-height);\n letter-spacing: 0.02em;\n\n &:not(:first-child) {\n margin-block-start: calc(var(--lobe-markdown-margin-multiple) * 0.5em);\n }\n\n &:not(:last-child) {\n margin-block-end: calc(var(--lobe-markdown-margin-multiple) * 0.5em);\n }\n }\n "]))),
|
|
41
|
+
p: p,
|
|
35
42
|
root: __root,
|
|
36
43
|
variant: cx(header, p, blockquote, code)
|
|
37
44
|
};
|
|
@@ -11,6 +11,16 @@ export interface ReactPlainTextProps {
|
|
|
11
11
|
children: ReactElement<ReactEditorContentProps>;
|
|
12
12
|
className?: string;
|
|
13
13
|
enableHotkey?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Enable automatic markdown formatting for pasted content
|
|
16
|
+
* @default true
|
|
17
|
+
*/
|
|
18
|
+
enablePasteMarkdown?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Enable/disable markdown shortcuts
|
|
21
|
+
* @default true - all formats enabled
|
|
22
|
+
*/
|
|
23
|
+
markdownOption?: CommonPluginOptions['markdownOption'];
|
|
14
24
|
onBlur?: (props: {
|
|
15
25
|
editor: IEditor;
|
|
16
26
|
event: FocusEvent<HTMLDivElement>;
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { IEditorPluginConstructor } from "../../../types";
|
|
2
2
|
export interface MarkdownPluginOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Enable automatic markdown formatting for pasted content
|
|
5
|
+
* @default true
|
|
6
|
+
*/
|
|
7
|
+
enablePasteMarkdown?: boolean;
|
|
3
8
|
}
|
|
4
9
|
export declare const MarkdownPlugin: IEditorPluginConstructor<MarkdownPluginOptions>;
|
|
@@ -16,22 +16,22 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
|
|
|
16
16
|
import { $isCodeNode } from '@lexical/code';
|
|
17
17
|
import { $getNodeByKey, $getSelection, $isRangeSelection, $isTextNode, COLLABORATION_TAG, COMMAND_PRIORITY_CRITICAL, HISTORIC_TAG, KEY_ENTER_COMMAND, PASTE_COMMAND } from 'lexical';
|
|
18
18
|
import { KernelPlugin } from "../../../editor-kernel/plugin";
|
|
19
|
+
import { createDebugLogger } from "../../../utils/debug";
|
|
19
20
|
import MarkdownDataSource from "../data-source/markdown-data-source";
|
|
20
21
|
import { parseMarkdownToLexical } from "../data-source/markdown/parse";
|
|
21
22
|
import { IMarkdownShortCutService, MarkdownShortCutService } from "../service/shortcut";
|
|
22
23
|
import { $generateNodesFromSerializedNodes, $insertGeneratedNodes, canContainTransformableMarkdown } from "../utils";
|
|
23
|
-
|
|
24
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
|
25
|
-
|
|
26
24
|
export var MarkdownPlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
27
25
|
_inherits(MarkdownPlugin, _KernelPlugin);
|
|
28
26
|
var _super = _createSuper(MarkdownPlugin);
|
|
29
|
-
function MarkdownPlugin(kernel) {
|
|
27
|
+
function MarkdownPlugin(kernel, config) {
|
|
30
28
|
var _this;
|
|
31
29
|
_classCallCheck(this, MarkdownPlugin);
|
|
32
30
|
_this = _super.call(this);
|
|
31
|
+
_defineProperty(_assertThisInitialized(_this), "logger", createDebugLogger('plugin', 'markdown'));
|
|
33
32
|
_defineProperty(_assertThisInitialized(_this), "service", void 0);
|
|
34
33
|
_this.kernel = kernel;
|
|
34
|
+
_this.config = config;
|
|
35
35
|
_this.service = new MarkdownShortCutService(kernel);
|
|
36
36
|
kernel.registerService(IMarkdownShortCutService, _this.service);
|
|
37
37
|
// @todo To be implemented
|
|
@@ -119,6 +119,13 @@ export var MarkdownPlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
|
119
119
|
return false;
|
|
120
120
|
}, COMMAND_PRIORITY_CRITICAL));
|
|
121
121
|
this.register(editor.registerCommand(PASTE_COMMAND, function (event) {
|
|
122
|
+
var _this2$config$enableP, _this2$config;
|
|
123
|
+
// Check if markdown paste formatting is enabled (default: true)
|
|
124
|
+
var enablePasteMarkdown = (_this2$config$enableP = (_this2$config = _this2.config) === null || _this2$config === void 0 ? void 0 : _this2$config.enablePasteMarkdown) !== null && _this2$config$enableP !== void 0 ? _this2$config$enableP : true;
|
|
125
|
+
if (!enablePasteMarkdown) {
|
|
126
|
+
_this2.logger.debug('paste markdown formatting is disabled');
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
122
129
|
if (!(event instanceof ClipboardEvent)) return false;
|
|
123
130
|
var clipboardData = event.clipboardData;
|
|
124
131
|
if (!clipboardData) return false;
|
|
@@ -133,13 +140,13 @@ export var MarkdownPlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
|
133
140
|
// If there's HTML content, it's a rich text paste
|
|
134
141
|
// Let Lexical's rich text handler process it
|
|
135
142
|
if (html && html.trim()) {
|
|
136
|
-
|
|
143
|
+
_this2.logger.debug('paste content analysis: HTML detected, letting Lexical handle it');
|
|
137
144
|
return false;
|
|
138
145
|
}
|
|
139
146
|
|
|
140
147
|
// Only handle plain text paste - check for markdown patterns
|
|
141
148
|
var hasMarkdownContent = _this2.detectMarkdownContent(text);
|
|
142
|
-
|
|
149
|
+
_this2.logger.debug('paste content analysis:', {
|
|
143
150
|
hasHTML: false,
|
|
144
151
|
hasMarkdown: hasMarkdownContent,
|
|
145
152
|
markdownPatterns: _this2.getMarkdownPatterns(text),
|
|
@@ -256,7 +263,7 @@ export var MarkdownPlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
|
256
263
|
$insertGeneratedNodes(editor, nodes, selection);
|
|
257
264
|
return true;
|
|
258
265
|
} catch (error) {
|
|
259
|
-
|
|
266
|
+
this.logger.error('Failed to handle markdown paste:', error);
|
|
260
267
|
}
|
|
261
268
|
return false;
|
|
262
269
|
}
|
|
@@ -40,6 +40,10 @@ var Editor = /*#__PURE__*/memo(function (_ref) {
|
|
|
40
40
|
onFocus = _ref.onFocus,
|
|
41
41
|
onBlur = _ref.onBlur,
|
|
42
42
|
autoFocus = _ref.autoFocus,
|
|
43
|
+
_ref$enablePasteMarkd = _ref.enablePasteMarkdown,
|
|
44
|
+
enablePasteMarkdown = _ref$enablePasteMarkd === void 0 ? true : _ref$enablePasteMarkd,
|
|
45
|
+
_ref$markdownOption = _ref.markdownOption,
|
|
46
|
+
markdownOption = _ref$markdownOption === void 0 ? true : _ref$markdownOption,
|
|
43
47
|
onCompositionStart = _ref.onCompositionStart,
|
|
44
48
|
onCompositionEnd = _ref.onCompositionEnd,
|
|
45
49
|
onContextMenu = _ref.onContextMenu;
|
|
@@ -86,6 +90,8 @@ var Editor = /*#__PURE__*/memo(function (_ref) {
|
|
|
86
90
|
children: [memoPlugins, memoSlash, memoMention, /*#__PURE__*/_jsx(ReactPlainText, {
|
|
87
91
|
autoFocus: autoFocus,
|
|
88
92
|
className: className,
|
|
93
|
+
enablePasteMarkdown: enablePasteMarkdown,
|
|
94
|
+
markdownOption: markdownOption,
|
|
89
95
|
onBlur: onBlur,
|
|
90
96
|
onChange: onChange,
|
|
91
97
|
onCompositionEnd: onCompositionEnd,
|
|
@@ -12,6 +12,21 @@ export interface EditorProps extends Partial<ReactEditorContentProps>, Omit<Reac
|
|
|
12
12
|
children?: ReactNode;
|
|
13
13
|
className?: string;
|
|
14
14
|
editor?: IEditor;
|
|
15
|
+
/**
|
|
16
|
+
* Enable automatic markdown formatting for pasted content
|
|
17
|
+
* @default true
|
|
18
|
+
*/
|
|
19
|
+
enablePasteMarkdown?: boolean;
|
|
20
|
+
markdownOption?: boolean | {
|
|
21
|
+
bold?: boolean;
|
|
22
|
+
code?: boolean;
|
|
23
|
+
header?: boolean;
|
|
24
|
+
italic?: boolean;
|
|
25
|
+
quote?: boolean;
|
|
26
|
+
strikethrough?: boolean;
|
|
27
|
+
underline?: boolean;
|
|
28
|
+
underlineStrikethrough?: boolean;
|
|
29
|
+
};
|
|
15
30
|
mentionOption?: MentionOption;
|
|
16
31
|
onInit?: (editor: IEditor) => void;
|
|
17
32
|
plugins?: EditorPlugin[];
|
package/package.json
CHANGED