x-star-editor 0.1.1 → 0.2.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/dist/components/Fade.js +2 -7
- package/dist/components/FileInput.js +2 -10
- package/dist/components/Toolbar.js +17 -24
- package/dist/locales/index.js +6 -5
- package/dist/styles/index.css +52 -45
- package/dist/types/worker.js.d.ts +3 -0
- package/dist/utils/container.js +1 -3
- package/dist/utils/handler.js +230 -87
- package/dist/utils/history.js +3 -16
- package/dist/utils/markdown.d.ts +31 -29
- package/dist/utils/markdown.js +106 -62
- package/dist/x-star-editor/index.d.ts +21 -7
- package/dist/x-star-editor/index.js +20 -34
- package/dist/x-star-md-editor/index.d.ts +5 -1
- package/dist/x-star-md-editor/index.js +82 -53
- package/dist/x-star-md-viewer/index.d.ts +27 -2
- package/dist/x-star-md-viewer/index.js +52 -10
- package/package.json +6 -2
- package/workers-dist/markdown.worker.js +1 -0
- /package/dist/{utils → types}/jsx-runtime.d.ts +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
1
2
|
import classNames from 'classnames';
|
|
2
|
-
import React, { useEffect, useImperativeHandle, useRef } from 'react';
|
|
3
|
+
import React, { useEffect, useImperativeHandle, useMemo, useRef } from 'react';
|
|
3
4
|
import Toolbar, { getDefaultToolbarItemMap, getDefaultToolbarItems } from "../components/Toolbar";
|
|
4
5
|
import { LocaleProvider } from "../locales";
|
|
5
6
|
import { getRange, useContainer } from "../utils/container";
|
|
@@ -9,6 +10,7 @@ import { useHistory } from "../utils/history";
|
|
|
9
10
|
var XStarMdEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
10
11
|
var className = _ref.className,
|
|
11
12
|
style = _ref.style,
|
|
13
|
+
height = _ref.height,
|
|
12
14
|
toolbarClassName = _ref.toolbarClassName,
|
|
13
15
|
toolbarStyle = _ref.toolbarStyle,
|
|
14
16
|
locale = _ref.locale,
|
|
@@ -24,17 +26,12 @@ var XStarMdEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
24
26
|
selection = _useHistory.selection,
|
|
25
27
|
dispatch = _useHistory.dispatch;
|
|
26
28
|
var initialized = useRef(false);
|
|
27
|
-
var onChangeLatest = useRef(onChange);
|
|
28
|
-
onChangeLatest.current = onChange;
|
|
29
|
-
var onInsertFileLatest = useRef(onInsertFile);
|
|
30
|
-
onInsertFileLatest.current = onInsertFile;
|
|
31
29
|
|
|
32
30
|
// 将文本同步到容器
|
|
33
31
|
useEffect(function () {
|
|
34
32
|
container.setText(sourceCode);
|
|
35
33
|
if (initialized.current) {
|
|
36
|
-
|
|
37
|
-
(_onChangeLatest$curre = onChangeLatest.current) === null || _onChangeLatest$curre === void 0 ? void 0 : _onChangeLatest$curre.call(onChangeLatest, sourceCode);
|
|
34
|
+
onChange === null || onChange === void 0 ? void 0 : onChange(sourceCode);
|
|
38
35
|
}
|
|
39
36
|
}, [sourceCode]);
|
|
40
37
|
|
|
@@ -80,7 +77,7 @@ var XStarMdEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
80
77
|
useImperativeHandle(ref, function () {
|
|
81
78
|
return {
|
|
82
79
|
exec: exec,
|
|
83
|
-
|
|
80
|
+
getEditorContainer: function getEditorContainer() {
|
|
84
81
|
return container.ref.current;
|
|
85
82
|
}
|
|
86
83
|
};
|
|
@@ -96,7 +93,7 @@ var XStarMdEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
96
93
|
{
|
|
97
94
|
e.preventDefault();
|
|
98
95
|
if (startOffset < endOffset) {
|
|
99
|
-
e.clipboardData.setData('text/plain',
|
|
96
|
+
e.clipboardData.setData('text/plain', sourceCode.slice(startOffset, endOffset));
|
|
100
97
|
if (e.type === 'cut') {
|
|
101
98
|
dispatch({
|
|
102
99
|
type: 'delete',
|
|
@@ -118,9 +115,8 @@ var XStarMdEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
118
115
|
selection: selection
|
|
119
116
|
});
|
|
120
117
|
} else if (e.clipboardData.types.includes('Files')) {
|
|
121
|
-
var _onInsertFileLatest$c;
|
|
122
118
|
var _file = e.clipboardData.files[0];
|
|
123
|
-
|
|
119
|
+
onInsertFile === null || onInsertFile === void 0 ? void 0 : onInsertFile(_file, {
|
|
124
120
|
description: _file.name,
|
|
125
121
|
image: _file.type.startsWith('image/')
|
|
126
122
|
});
|
|
@@ -134,27 +130,55 @@ var XStarMdEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
134
130
|
* 开始组合时的选区
|
|
135
131
|
*/
|
|
136
132
|
var compositionStartSelection = useRef();
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* 容器同步控制器
|
|
136
|
+
*/
|
|
137
|
+
var syncController = useMemo(function () {
|
|
138
|
+
var timer = 0;
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* 将最新的文本和选区同步到容器
|
|
142
|
+
*/
|
|
143
|
+
var sync = function sync() {
|
|
144
|
+
if (compositionStartSelection.current) {
|
|
145
|
+
var _selection = getSelection();
|
|
146
|
+
container.setText(sourceCodeLatest.current);
|
|
147
|
+
container.setSelection(_selection);
|
|
148
|
+
compositionStartSelection.current = undefined;
|
|
149
|
+
}
|
|
150
|
+
timer = 0;
|
|
151
|
+
};
|
|
152
|
+
return {
|
|
153
|
+
/**
|
|
154
|
+
* 在下个事件循环中同步
|
|
155
|
+
*/
|
|
156
|
+
start: function start() {
|
|
157
|
+
if (!timer) {
|
|
158
|
+
timer = window.setTimeout(sync);
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
/**
|
|
162
|
+
* 立即执行下个事件循环中的同步
|
|
163
|
+
*/
|
|
164
|
+
flush: function flush() {
|
|
165
|
+
if (timer) {
|
|
166
|
+
window.clearTimeout(timer);
|
|
167
|
+
sync();
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
}, []);
|
|
137
172
|
var compositionEventHandler = function compositionEventHandler(e) {
|
|
138
173
|
switch (e.type) {
|
|
139
174
|
case 'compositionend':
|
|
140
175
|
{
|
|
141
|
-
|
|
142
|
-
dispatch({
|
|
143
|
-
type: 'insert',
|
|
144
|
-
payload: {
|
|
145
|
-
text: e.data
|
|
146
|
-
},
|
|
147
|
-
selection: compositionStartSelection.current
|
|
148
|
-
});
|
|
149
|
-
// 确保组合事件屏蔽表单和键盘事件
|
|
150
|
-
window.setTimeout(function () {
|
|
151
|
-
return compositionStartSelection.current = undefined;
|
|
152
|
-
});
|
|
153
|
-
}
|
|
176
|
+
syncController.start();
|
|
154
177
|
break;
|
|
155
178
|
}
|
|
156
179
|
case 'compositionstart':
|
|
157
180
|
{
|
|
181
|
+
syncController.flush();
|
|
158
182
|
compositionStartSelection.current = getSelection();
|
|
159
183
|
break;
|
|
160
184
|
}
|
|
@@ -164,7 +188,7 @@ var XStarMdEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
164
188
|
switch (e.type) {
|
|
165
189
|
case 'drop':
|
|
166
190
|
{
|
|
167
|
-
var
|
|
191
|
+
var _selection2 = getSelection();
|
|
168
192
|
window.setTimeout(function () {
|
|
169
193
|
container.normalize();
|
|
170
194
|
dispatch({
|
|
@@ -173,7 +197,7 @@ var XStarMdEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
173
197
|
sourceCode: container.getText(),
|
|
174
198
|
selection: getSelection()
|
|
175
199
|
},
|
|
176
|
-
selection:
|
|
200
|
+
selection: _selection2
|
|
177
201
|
});
|
|
178
202
|
});
|
|
179
203
|
break;
|
|
@@ -185,57 +209,60 @@ var XStarMdEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
185
209
|
case 'blur':
|
|
186
210
|
{
|
|
187
211
|
blurSelection.current = getSelection();
|
|
188
|
-
window.setTimeout(function () {
|
|
189
|
-
compositionStartSelection.current = undefined;
|
|
190
|
-
container.setText(sourceCodeLatest.current);
|
|
191
|
-
});
|
|
192
212
|
break;
|
|
193
213
|
}
|
|
194
214
|
}
|
|
195
215
|
};
|
|
196
216
|
var formEventHandler = function formEventHandler(e) {
|
|
197
|
-
if (compositionStartSelection.current) {
|
|
198
|
-
return;
|
|
199
|
-
}
|
|
200
217
|
switch (e.type) {
|
|
201
218
|
case 'beforeinput':
|
|
202
219
|
{
|
|
203
220
|
e.preventDefault();
|
|
204
221
|
if ('data' in e && typeof e.data === 'string') {
|
|
222
|
+
var _compositionStartSele;
|
|
205
223
|
dispatch({
|
|
206
224
|
type: 'insert',
|
|
207
225
|
payload: {
|
|
208
226
|
text: e.data
|
|
209
227
|
},
|
|
210
|
-
selection: getSelection()
|
|
228
|
+
selection: (_compositionStartSele = compositionStartSelection.current) !== null && _compositionStartSele !== void 0 ? _compositionStartSele : getSelection()
|
|
211
229
|
});
|
|
230
|
+
compositionStartSelection.current = undefined;
|
|
212
231
|
}
|
|
213
232
|
break;
|
|
214
233
|
}
|
|
215
234
|
}
|
|
216
235
|
};
|
|
217
|
-
var
|
|
218
|
-
|
|
236
|
+
var onInsertFileLatest = useRef(onInsertFile);
|
|
237
|
+
onInsertFileLatest.current = onInsertFile;
|
|
238
|
+
var options = useMemo(function () {
|
|
239
|
+
return composeHandlers(plugins)({
|
|
240
|
+
toolbarItemMap: getDefaultToolbarItemMap(locale, function () {
|
|
241
|
+
var _onInsertFileLatest$c;
|
|
242
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
243
|
+
args[_key] = arguments[_key];
|
|
244
|
+
}
|
|
245
|
+
return (_onInsertFileLatest$c = onInsertFileLatest.current) === null || _onInsertFileLatest$c === void 0 ? void 0 : _onInsertFileLatest$c.call.apply(_onInsertFileLatest$c, [onInsertFileLatest].concat(args));
|
|
246
|
+
}),
|
|
219
247
|
toolbarItems: getDefaultToolbarItems(),
|
|
220
248
|
keyboardEventHandlers: getDefaultKeyboardEventHandlers()
|
|
221
|
-
})
|
|
222
|
-
|
|
223
|
-
toolbarItems = _composeHandlers.toolbarItems,
|
|
224
|
-
keyboardEventHandlers = _composeHandlers.keyboardEventHandlers;
|
|
249
|
+
});
|
|
250
|
+
}, [locale, plugins]);
|
|
225
251
|
var keyboardEventHandler = function keyboardEventHandler(e) {
|
|
226
|
-
if (compositionStartSelection.current) {
|
|
227
|
-
return;
|
|
228
|
-
}
|
|
229
252
|
switch (e.type) {
|
|
230
253
|
case 'keydown':
|
|
231
254
|
{
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
255
|
+
if (compositionStartSelection.current) {
|
|
256
|
+
e.preventDefault();
|
|
257
|
+
} else {
|
|
258
|
+
composeHandlers(options.keyboardEventHandlers)({
|
|
259
|
+
history: history,
|
|
260
|
+
sourceCode: sourceCode,
|
|
261
|
+
selection: getSelection(),
|
|
262
|
+
dispatch: dispatch,
|
|
263
|
+
e: e
|
|
264
|
+
});
|
|
265
|
+
}
|
|
239
266
|
break;
|
|
240
267
|
}
|
|
241
268
|
}
|
|
@@ -245,13 +272,15 @@ var XStarMdEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
245
272
|
}, /*#__PURE__*/React.createElement(Toolbar, {
|
|
246
273
|
className: classNames(toolbarClassName),
|
|
247
274
|
style: toolbarStyle,
|
|
248
|
-
itemMap: toolbarItemMap,
|
|
249
|
-
items: toolbarItems,
|
|
275
|
+
itemMap: options.toolbarItemMap,
|
|
276
|
+
items: options.toolbarItems,
|
|
250
277
|
exec: exec
|
|
251
278
|
}), /*#__PURE__*/React.createElement("div", {
|
|
252
279
|
ref: container.ref,
|
|
253
280
|
className: classNames("".concat(prefix, "md-editor"), className),
|
|
254
|
-
style: style,
|
|
281
|
+
style: _objectSpread(_objectSpread({}, style), {}, {
|
|
282
|
+
height: height
|
|
283
|
+
}),
|
|
255
284
|
contentEditable: true,
|
|
256
285
|
onBeforeInput: formEventHandler,
|
|
257
286
|
onBlur: focusEventHandler,
|
|
@@ -1,10 +1,27 @@
|
|
|
1
|
+
import type { Components } from 'hast-util-to-jsx-runtime';
|
|
1
2
|
import React from 'react';
|
|
2
|
-
import type {
|
|
3
|
+
import type { Schema } from '../utils/markdown';
|
|
4
|
+
export interface ViewerOptions {
|
|
5
|
+
/**
|
|
6
|
+
* 自定义过滤模式
|
|
7
|
+
*/
|
|
8
|
+
customSchema: Schema;
|
|
9
|
+
/**
|
|
10
|
+
* 自定义 HTML 元素
|
|
11
|
+
*/
|
|
12
|
+
customHTMLElements: Partial<Components>;
|
|
13
|
+
/**
|
|
14
|
+
* 自定义块
|
|
15
|
+
*/
|
|
16
|
+
customBlocks: Partial<Record<string, React.ComponentType<{
|
|
17
|
+
children: string;
|
|
18
|
+
}>>>;
|
|
19
|
+
}
|
|
3
20
|
export interface XStarMdViewerPlugin {
|
|
4
21
|
(ctx: ViewerOptions): void;
|
|
5
22
|
}
|
|
6
23
|
export interface XStarMdViewerHandle {
|
|
7
|
-
|
|
24
|
+
getViewerContainer: () => HTMLDivElement;
|
|
8
25
|
}
|
|
9
26
|
export interface XStarMdViewerProps {
|
|
10
27
|
/**
|
|
@@ -15,6 +32,10 @@ export interface XStarMdViewerProps {
|
|
|
15
32
|
* CSS 样式
|
|
16
33
|
*/
|
|
17
34
|
style?: React.CSSProperties;
|
|
35
|
+
/**
|
|
36
|
+
* 浏览器的高度
|
|
37
|
+
*/
|
|
38
|
+
height?: React.CSSProperties['height'];
|
|
18
39
|
/**
|
|
19
40
|
* 文本
|
|
20
41
|
*/
|
|
@@ -23,6 +44,10 @@ export interface XStarMdViewerProps {
|
|
|
23
44
|
* 插件
|
|
24
45
|
*/
|
|
25
46
|
plugins?: XStarMdViewerPlugin[];
|
|
47
|
+
/**
|
|
48
|
+
* 是否启用 Web Worker
|
|
49
|
+
*/
|
|
50
|
+
enableWebWorker?: boolean;
|
|
26
51
|
}
|
|
27
52
|
declare const XStarMdViewer: React.ForwardRefExoticComponent<XStarMdViewerProps & React.RefAttributes<XStarMdViewerHandle>>;
|
|
28
53
|
export default XStarMdViewer;
|