x-star-editor 0.3.0 → 0.3.2
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/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/utils/container.js +37 -1
- package/dist/utils/handler.d.ts +1 -0
- package/dist/utils/handler.js +21 -47
- package/dist/utils/history.d.ts +11 -3
- package/dist/utils/history.js +28 -3
- package/dist/utils/markdown.js +5 -17
- package/dist/x-star-editor/index.d.ts +4 -0
- package/dist/x-star-editor/index.js +43 -15
- package/dist/x-star-md-editor/index.js +161 -152
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type { ToolbarItem } from './components/Toolbar';
|
|
2
2
|
export { createSelection, getRange } from './utils/container';
|
|
3
|
-
export { insertHandler, redoHandler, selectHandler, setHandler, toggleHandler, undoHandler, } from './utils/handler';
|
|
3
|
+
export { batchHandler, insertHandler, redoHandler, selectHandler, setHandler, toggleHandler, undoHandler, } from './utils/handler';
|
|
4
4
|
export type { Executor, Handler, KeyboardEventHandler } from './utils/handler';
|
|
5
5
|
export { toHTML, toMarkdown, toText } from './utils/markdown';
|
|
6
6
|
export { default as XStarEditor, useEditorRef } from './x-star-editor';
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { createSelection, getRange } from "./utils/container";
|
|
2
|
-
export { insertHandler, redoHandler, selectHandler, setHandler, toggleHandler, undoHandler } from "./utils/handler";
|
|
2
|
+
export { batchHandler, insertHandler, redoHandler, selectHandler, setHandler, toggleHandler, undoHandler } from "./utils/handler";
|
|
3
3
|
export { toHTML, toMarkdown, toText } from "./utils/markdown";
|
|
4
4
|
export { default as XStarEditor, useEditorRef } from "./x-star-editor";
|
|
5
5
|
export { default as XStarMdEditor, useMdEditorRef } from "./x-star-md-editor";
|
package/dist/utils/container.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import _createForOfIteratorHelper from "@babel/runtime/helpers/esm/createForOfIteratorHelper";
|
|
2
|
-
import { useRef } from 'react';
|
|
2
|
+
import { useEffect, useRef } from 'react';
|
|
3
3
|
import { editorRender } from "./markdown";
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -304,6 +304,42 @@ export var useContainer = function useContainer(ref) {
|
|
|
304
304
|
ref.current.scrollTop += bottomOffset;
|
|
305
305
|
}
|
|
306
306
|
};
|
|
307
|
+
|
|
308
|
+
// 确保光标不在零宽空格后
|
|
309
|
+
useEffect(function () {
|
|
310
|
+
var listener = function listener() {
|
|
311
|
+
var _ref$current, _anchorNode$nodeValue, _focusNode$nodeValue;
|
|
312
|
+
var selection = window.getSelection();
|
|
313
|
+
if (!selection || !selection.anchorNode || !selection.focusNode || !((_ref$current = ref.current) !== null && _ref$current !== void 0 && _ref$current.contains(selection.anchorNode))) {
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
var update = false;
|
|
317
|
+
var anchorNode = selection.anchorNode,
|
|
318
|
+
anchorOffset = selection.anchorOffset,
|
|
319
|
+
focusNode = selection.focusNode,
|
|
320
|
+
focusOffset = selection.focusOffset;
|
|
321
|
+
if (anchorNode.nodeType === Node.TEXT_NODE && ((_anchorNode$nodeValue = anchorNode.nodeValue) === null || _anchorNode$nodeValue === void 0 ? void 0 : _anchorNode$nodeValue[anchorOffset - 1]) === "\u200B") {
|
|
322
|
+
update = true;
|
|
323
|
+
anchorOffset--;
|
|
324
|
+
}
|
|
325
|
+
if (focusNode.nodeType === Node.TEXT_NODE && ((_focusNode$nodeValue = focusNode.nodeValue) === null || _focusNode$nodeValue === void 0 ? void 0 : _focusNode$nodeValue[focusOffset - 1]) === "\u200B") {
|
|
326
|
+
update = true;
|
|
327
|
+
focusOffset--;
|
|
328
|
+
}
|
|
329
|
+
if (update) {
|
|
330
|
+
selection.setBaseAndExtent(anchorNode, anchorOffset, focusNode, focusOffset);
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
document.addEventListener('selectionchange', listener, {
|
|
334
|
+
capture: true,
|
|
335
|
+
passive: true
|
|
336
|
+
});
|
|
337
|
+
return function () {
|
|
338
|
+
return document.removeEventListener('selectionchange', listener, {
|
|
339
|
+
capture: true
|
|
340
|
+
});
|
|
341
|
+
};
|
|
342
|
+
}, []);
|
|
307
343
|
return useRef({
|
|
308
344
|
getText: getText,
|
|
309
345
|
setText: setText,
|
package/dist/utils/handler.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ export declare const toggleHandler: (payload: ToggleAction['payload']) => Handle
|
|
|
15
15
|
export declare const setHandler: (payload: SetAction['payload']) => Handler;
|
|
16
16
|
export declare const undoHandler: () => Handler;
|
|
17
17
|
export declare const redoHandler: () => Handler;
|
|
18
|
+
export declare const batchHandler: () => Handler;
|
|
18
19
|
export declare const selectHandler: (selection: SelectAction['selection']) => Handler;
|
|
19
20
|
/**
|
|
20
21
|
* 执行函数
|
package/dist/utils/handler.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import _createForOfIteratorHelper from "@babel/runtime/helpers/esm/createForOfIteratorHelper";
|
|
2
2
|
import { createKeybindingsHandler } from 'tinykeys';
|
|
3
|
-
import { createSelection
|
|
3
|
+
import { createSelection } from "./container";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* 处理函数上下文
|
|
@@ -59,9 +59,17 @@ export var redoHandler = function redoHandler() {
|
|
|
59
59
|
});
|
|
60
60
|
};
|
|
61
61
|
};
|
|
62
|
-
export var
|
|
62
|
+
export var batchHandler = function batchHandler() {
|
|
63
63
|
return function (_ref6) {
|
|
64
64
|
var dispatch = _ref6.dispatch;
|
|
65
|
+
return dispatch({
|
|
66
|
+
type: 'batch'
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
export var selectHandler = function selectHandler(selection) {
|
|
71
|
+
return function (_ref7) {
|
|
72
|
+
var dispatch = _ref7.dispatch;
|
|
65
73
|
return dispatch({
|
|
66
74
|
type: 'select',
|
|
67
75
|
selection: selection
|
|
@@ -80,11 +88,11 @@ export var selectHandler = function selectHandler(selection) {
|
|
|
80
88
|
*/
|
|
81
89
|
|
|
82
90
|
export var getDefaultKeyboardEventHandlers = function getDefaultKeyboardEventHandlers() {
|
|
83
|
-
return [function (
|
|
84
|
-
var sourceCode =
|
|
85
|
-
selection =
|
|
86
|
-
dispatch =
|
|
87
|
-
e =
|
|
91
|
+
return [function (_ref8) {
|
|
92
|
+
var sourceCode = _ref8.sourceCode,
|
|
93
|
+
selection = _ref8.selection,
|
|
94
|
+
dispatch = _ref8.dispatch,
|
|
95
|
+
e = _ref8.e;
|
|
88
96
|
return createKeybindingsHandler({
|
|
89
97
|
Tab: function Tab(e) {
|
|
90
98
|
e.preventDefault();
|
|
@@ -108,56 +116,22 @@ export var getDefaultKeyboardEventHandlers = function getDefaultKeyboardEventHan
|
|
|
108
116
|
type: 'redo'
|
|
109
117
|
});
|
|
110
118
|
},
|
|
111
|
-
|
|
112
|
-
e.preventDefault();
|
|
113
|
-
var _getRange = getRange(selection),
|
|
114
|
-
startOffset = _getRange.startOffset,
|
|
115
|
-
endOffset = _getRange.endOffset;
|
|
116
|
-
if (startOffset < endOffset) {
|
|
117
|
-
dispatch({
|
|
118
|
-
type: 'select',
|
|
119
|
-
selection: createSelection(startOffset)
|
|
120
|
-
});
|
|
121
|
-
} else if (startOffset) {
|
|
122
|
-
dispatch({
|
|
123
|
-
type: 'select',
|
|
124
|
-
selection: createSelection(startOffset - 1)
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
},
|
|
128
|
-
'Shift+ArrowLeft': function ShiftArrowLeft(e) {
|
|
129
|
-
e.preventDefault();
|
|
119
|
+
ArrowRight: function ArrowRight(e) {
|
|
130
120
|
var anchorOffset = selection.anchorOffset,
|
|
131
121
|
focusOffset = selection.focusOffset;
|
|
132
|
-
if (focusOffset) {
|
|
133
|
-
|
|
134
|
-
type: 'select',
|
|
135
|
-
selection: createSelection(anchorOffset, focusOffset - 1)
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
},
|
|
139
|
-
ArrowRight: function ArrowRight(e) {
|
|
140
|
-
e.preventDefault();
|
|
141
|
-
var _getRange2 = getRange(selection),
|
|
142
|
-
startOffset = _getRange2.startOffset,
|
|
143
|
-
endOffset = _getRange2.endOffset;
|
|
144
|
-
if (startOffset < endOffset) {
|
|
122
|
+
if (anchorOffset === focusOffset && sourceCode[focusOffset] === '\n') {
|
|
123
|
+
e.preventDefault();
|
|
145
124
|
dispatch({
|
|
146
125
|
type: 'select',
|
|
147
|
-
selection: createSelection(
|
|
148
|
-
});
|
|
149
|
-
} else if (startOffset < sourceCode.length) {
|
|
150
|
-
dispatch({
|
|
151
|
-
type: 'select',
|
|
152
|
-
selection: createSelection(startOffset + 1)
|
|
126
|
+
selection: createSelection(focusOffset + 1)
|
|
153
127
|
});
|
|
154
128
|
}
|
|
155
129
|
},
|
|
156
130
|
'Shift+ArrowRight': function ShiftArrowRight(e) {
|
|
157
|
-
e.preventDefault();
|
|
158
131
|
var anchorOffset = selection.anchorOffset,
|
|
159
132
|
focusOffset = selection.focusOffset;
|
|
160
|
-
if (focusOffset
|
|
133
|
+
if (sourceCode[focusOffset] === '\n') {
|
|
134
|
+
e.preventDefault();
|
|
161
135
|
dispatch({
|
|
162
136
|
type: 'select',
|
|
163
137
|
selection: createSelection(anchorOffset, focusOffset + 1)
|
package/dist/utils/history.d.ts
CHANGED
|
@@ -44,7 +44,9 @@ type StateAction = InsertAction | ToggleAction | SetAction;
|
|
|
44
44
|
*/
|
|
45
45
|
interface History {
|
|
46
46
|
states: (State & {
|
|
47
|
-
action: StateAction
|
|
47
|
+
action: StateAction & {
|
|
48
|
+
batch?: boolean;
|
|
49
|
+
};
|
|
48
50
|
})[];
|
|
49
51
|
index: number;
|
|
50
52
|
selection: ContainerSelection;
|
|
@@ -55,15 +57,21 @@ export interface UndoAction {
|
|
|
55
57
|
export interface RedoAction {
|
|
56
58
|
type: 'redo';
|
|
57
59
|
}
|
|
60
|
+
export interface BatchAction {
|
|
61
|
+
type: 'batch';
|
|
62
|
+
selection?: ContainerSelection;
|
|
63
|
+
}
|
|
58
64
|
export interface SelectAction {
|
|
59
65
|
type: 'select';
|
|
60
66
|
selection: ContainerSelection;
|
|
61
67
|
}
|
|
62
|
-
type HistoryAction = UndoAction | RedoAction | SelectAction;
|
|
68
|
+
type HistoryAction = UndoAction | RedoAction | BatchAction | SelectAction;
|
|
63
69
|
export declare const useHistory: (initialSourceCode: string) => {
|
|
64
70
|
history: History;
|
|
65
71
|
sourceCode: string;
|
|
66
72
|
selection: ContainerSelection;
|
|
67
|
-
dispatch: import("react").Dispatch<
|
|
73
|
+
dispatch: import("react").Dispatch<HistoryAction | (StateAction & {
|
|
74
|
+
batch?: boolean | undefined;
|
|
75
|
+
})>;
|
|
68
76
|
};
|
|
69
77
|
export {};
|
package/dist/utils/history.js
CHANGED
|
@@ -132,8 +132,8 @@ var stateReducer = function stateReducer(_ref, action) {
|
|
|
132
132
|
url = _action$payload2.url,
|
|
133
133
|
description = _action$payload2.description;
|
|
134
134
|
return {
|
|
135
|
-
sourceCode: "".concat(before).concat(_type === '
|
|
136
|
-
selection: createSelection(startOffset + url.length + description.length + 4 + (_type === '
|
|
135
|
+
sourceCode: "".concat(before).concat(_type === 'image' ? '!' : '', "[").concat(description, "](").concat(url, ")").concat(after),
|
|
136
|
+
selection: createSelection(startOffset + url.length + description.length + 4 + (_type === 'image' ? 1 : 0))
|
|
137
137
|
};
|
|
138
138
|
}
|
|
139
139
|
case 'math':
|
|
@@ -214,6 +214,20 @@ var historyReducer = function historyReducer(_ref2, action) {
|
|
|
214
214
|
selection: states[index + 1].selection
|
|
215
215
|
};
|
|
216
216
|
}
|
|
217
|
+
case 'batch':
|
|
218
|
+
{
|
|
219
|
+
var _action$selection2, _action$selection3;
|
|
220
|
+
return {
|
|
221
|
+
states: [].concat(_toConsumableArray(states.slice(0, index)), [_objectSpread(_objectSpread({}, states[index]), {}, {
|
|
222
|
+
selection: (_action$selection2 = action.selection) !== null && _action$selection2 !== void 0 ? _action$selection2 : states[index].selection,
|
|
223
|
+
action: _objectSpread(_objectSpread({}, states[index].action), {}, {
|
|
224
|
+
batch: false
|
|
225
|
+
})
|
|
226
|
+
})]),
|
|
227
|
+
index: index,
|
|
228
|
+
selection: (_action$selection3 = action.selection) !== null && _action$selection3 !== void 0 ? _action$selection3 : selection
|
|
229
|
+
};
|
|
230
|
+
}
|
|
217
231
|
case 'select':
|
|
218
232
|
{
|
|
219
233
|
return {
|
|
@@ -233,8 +247,19 @@ var historyReducer = function historyReducer(_ref2, action) {
|
|
|
233
247
|
selection: selection
|
|
234
248
|
};
|
|
235
249
|
}
|
|
250
|
+
if (states[index].action.batch && action.batch) {
|
|
251
|
+
return {
|
|
252
|
+
states: [].concat(_toConsumableArray(states.slice(0, index)), [_objectSpread(_objectSpread({}, states[index]), state)]),
|
|
253
|
+
index: index,
|
|
254
|
+
selection: state.selection
|
|
255
|
+
};
|
|
256
|
+
}
|
|
236
257
|
return {
|
|
237
|
-
states: [].concat(_toConsumableArray(states.slice(index < 100 ? 0 : index - 99, index
|
|
258
|
+
states: [].concat(_toConsumableArray(states.slice(index < 100 ? 0 : index - 99, index)), [_objectSpread(_objectSpread({}, states[index]), {}, {
|
|
259
|
+
action: _objectSpread(_objectSpread({}, states[index].action), {}, {
|
|
260
|
+
batch: false
|
|
261
|
+
})
|
|
262
|
+
}), _objectSpread(_objectSpread({}, state), {}, {
|
|
238
263
|
action: action
|
|
239
264
|
})]),
|
|
240
265
|
index: index < 100 ? index + 1 : 100,
|
package/dist/utils/markdown.js
CHANGED
|
@@ -3,7 +3,6 @@ import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
|
3
3
|
import _regeneratorRuntime from "@babel/runtime/helpers/esm/regeneratorRuntime";
|
|
4
4
|
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
|
|
5
5
|
import _createForOfIteratorHelper from "@babel/runtime/helpers/esm/createForOfIteratorHelper";
|
|
6
|
-
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
|
|
7
6
|
import { toJsxRuntime } from 'hast-util-to-jsx-runtime';
|
|
8
7
|
import { toText as hastToText } from 'hast-util-to-text';
|
|
9
8
|
import { Fragment, jsx, jsxs } from 'react/jsx-runtime';
|
|
@@ -32,20 +31,6 @@ import rehypeRawPositions from "./rehype/rehype-raw-positions";
|
|
|
32
31
|
*/
|
|
33
32
|
var toMdastProcessor = unified().use(remarkParse).use(remarkGfm).use(remarkMath).freeze();
|
|
34
33
|
|
|
35
|
-
/**
|
|
36
|
-
* 带缓存的解析函数
|
|
37
|
-
*
|
|
38
|
-
* @param sourceCode Markdown 文本
|
|
39
|
-
* @returns Mdast 树
|
|
40
|
-
*/
|
|
41
|
-
var cachedParse = function () {
|
|
42
|
-
var cache = {};
|
|
43
|
-
return function (sourceCode) {
|
|
44
|
-
var _cache$sourceCode;
|
|
45
|
-
return (_cache$sourceCode = cache[sourceCode]) !== null && _cache$sourceCode !== void 0 ? _cache$sourceCode : (cache = _defineProperty({}, sourceCode, toMdastProcessor.parse(sourceCode)))[sourceCode];
|
|
46
|
-
};
|
|
47
|
-
}();
|
|
48
|
-
|
|
49
34
|
/**
|
|
50
35
|
* 将 Markdown 文本映射到 DOM 树,第一层为 `<div>` 块元素,第二层为 `<div>` 行元素,之后均为 `<span>` 元素
|
|
51
36
|
*
|
|
@@ -243,7 +228,7 @@ export var editorRender = function editorRender(sourceCode) {
|
|
|
243
228
|
}
|
|
244
229
|
addText(sourceCode.slice(scanOffset, parentEndOffset), true);
|
|
245
230
|
};
|
|
246
|
-
getChildren(
|
|
231
|
+
getChildren(toMdastProcessor.parse(sourceCode).children, sourceCode.length);
|
|
247
232
|
if (scanOffset <= sourceCode.length) {
|
|
248
233
|
// 添加最后一行文本
|
|
249
234
|
block.append(createLine(sourceCode.slice(scanOffset)));
|
|
@@ -289,7 +274,7 @@ export var preViewerRender = /*#__PURE__*/function () {
|
|
|
289
274
|
while (1) switch (_context.prev = _context.next) {
|
|
290
275
|
case 0:
|
|
291
276
|
_context.next = 2;
|
|
292
|
-
return toHastProcessor.run(
|
|
277
|
+
return toHastProcessor.run(toMdastProcessor.parse(sourceCode));
|
|
293
278
|
case 2:
|
|
294
279
|
return _context.abrupt("return", _context.sent);
|
|
295
280
|
case 3:
|
|
@@ -346,6 +331,9 @@ export var viewerRender = function viewerRender(root, schema) {
|
|
|
346
331
|
*/
|
|
347
332
|
export var postViewerRender = function postViewerRender(root, options) {
|
|
348
333
|
var components = _objectSpread(_objectSpread({}, options.customHTMLElements), {}, {
|
|
334
|
+
input: function input(props) {
|
|
335
|
+
return jsx('input', props);
|
|
336
|
+
},
|
|
349
337
|
custom: function custom(props) {
|
|
350
338
|
var _options$customBlocks;
|
|
351
339
|
return jsx((_options$customBlocks = options.customBlocks[props.meta]) !== null && _options$customBlocks !== void 0 ? _options$customBlocks : 'div', {
|
|
@@ -6,17 +6,40 @@ import React, { useEffect, useImperativeHandle, useRef, useState } from 'react';
|
|
|
6
6
|
import { prefix } from "../utils/global";
|
|
7
7
|
import XStarMdEditor, { useMdEditorRef } from "../x-star-md-editor";
|
|
8
8
|
import XStarMdViewer, { useMdViewerRef } from "../x-star-md-viewer";
|
|
9
|
-
var
|
|
10
|
-
var
|
|
9
|
+
var ViewerRenderWrapper = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
10
|
+
var children = _ref.children,
|
|
11
|
+
className = _ref.className,
|
|
11
12
|
style = _ref.style,
|
|
12
|
-
height = _ref.height
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
height = _ref.height;
|
|
14
|
+
var containerRef = useRef(null);
|
|
15
|
+
useImperativeHandle(ref, function () {
|
|
16
|
+
return {
|
|
17
|
+
getViewerContainer: function getViewerContainer() {
|
|
18
|
+
return containerRef.current;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
}, []);
|
|
22
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
23
|
+
ref: containerRef,
|
|
24
|
+
className: classNames("".concat(prefix, "md-viewer"), className),
|
|
25
|
+
style: _objectSpread(_objectSpread({}, style), {}, {
|
|
26
|
+
height: height
|
|
27
|
+
})
|
|
28
|
+
}, children);
|
|
29
|
+
});
|
|
30
|
+
var XStarEditor = /*#__PURE__*/React.forwardRef(function (_ref2, ref) {
|
|
31
|
+
var className = _ref2.className,
|
|
32
|
+
style = _ref2.style,
|
|
33
|
+
height = _ref2.height,
|
|
34
|
+
locale = _ref2.locale,
|
|
35
|
+
_ref2$initialValue = _ref2.initialValue,
|
|
36
|
+
initialValue = _ref2$initialValue === void 0 ? '' : _ref2$initialValue,
|
|
37
|
+
enableWebWorker = _ref2.enableWebWorker,
|
|
38
|
+
editorProps = _ref2.editorProps,
|
|
39
|
+
viewerProps = _ref2.viewerProps,
|
|
40
|
+
viewerRender = _ref2.viewerRender,
|
|
41
|
+
_onChange = _ref2.onChange,
|
|
42
|
+
onInsertFile = _ref2.onInsertFile;
|
|
20
43
|
var editorRef = useMdEditorRef();
|
|
21
44
|
var viewerRef = useMdViewerRef();
|
|
22
45
|
var containerRef = useRef(null);
|
|
@@ -94,10 +117,10 @@ var XStarEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
94
117
|
if (ignore || !editor || !viewer) {
|
|
95
118
|
return;
|
|
96
119
|
}
|
|
97
|
-
var
|
|
98
|
-
|
|
99
|
-
fromElement =
|
|
100
|
-
toElement =
|
|
120
|
+
var _ref3 = e.currentTarget === editor ? [editor, viewer] : [viewer, editor],
|
|
121
|
+
_ref4 = _slicedToArray(_ref3, 2),
|
|
122
|
+
fromElement = _ref4[0],
|
|
123
|
+
toElement = _ref4[1];
|
|
101
124
|
var _getOffsetTops = getOffsetTops(fromElement, toElement),
|
|
102
125
|
_getOffsetTops2 = _slicedToArray(_getOffsetTops, 2),
|
|
103
126
|
fromOffsetTops = _getOffsetTops2[0],
|
|
@@ -149,7 +172,12 @@ var XStarEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
149
172
|
_onChange === null || _onChange === void 0 ? void 0 : _onChange(value);
|
|
150
173
|
},
|
|
151
174
|
onInsertFile: onInsertFile
|
|
152
|
-
})), /*#__PURE__*/React.createElement(
|
|
175
|
+
})), viewerRender ? /*#__PURE__*/React.createElement(ViewerRenderWrapper, {
|
|
176
|
+
ref: viewerRef,
|
|
177
|
+
className: viewerProps === null || viewerProps === void 0 ? void 0 : viewerProps.className,
|
|
178
|
+
style: viewerProps === null || viewerProps === void 0 ? void 0 : viewerProps.style,
|
|
179
|
+
height: height
|
|
180
|
+
}, viewerRender(value)) : /*#__PURE__*/React.createElement(XStarMdViewer, _extends({
|
|
153
181
|
ref: viewerRef
|
|
154
182
|
}, viewerProps, {
|
|
155
183
|
height: height,
|
|
@@ -93,6 +93,7 @@ var XStarMdEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
93
93
|
case 'copy':
|
|
94
94
|
case 'cut':
|
|
95
95
|
{
|
|
96
|
+
// 防止传输其他类型数据
|
|
96
97
|
e.preventDefault();
|
|
97
98
|
if (startOffset < endOffset) {
|
|
98
99
|
e.clipboardData.setData('text/plain', sourceCode.slice(startOffset, endOffset));
|
|
@@ -114,9 +115,13 @@ var XStarMdEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
114
115
|
switch (e.type) {
|
|
115
116
|
case 'compositionend':
|
|
116
117
|
{
|
|
118
|
+
// 组合时不更新 DOM,组合结束统一更新
|
|
117
119
|
var _selection = getSelection();
|
|
118
120
|
container.setText(sourceCodeLatest.current);
|
|
119
121
|
container.setSelection(_selection);
|
|
122
|
+
dispatch({
|
|
123
|
+
type: 'batch'
|
|
124
|
+
});
|
|
120
125
|
break;
|
|
121
126
|
}
|
|
122
127
|
}
|
|
@@ -130,6 +135,7 @@ var XStarMdEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
130
135
|
case 'dragstart':
|
|
131
136
|
{
|
|
132
137
|
if (startOffset < endOffset) {
|
|
138
|
+
// 防止传输其他类型数据
|
|
133
139
|
e.dataTransfer.clearData();
|
|
134
140
|
e.dataTransfer.setData('text/plain', sourceCode.slice(startOffset, endOffset));
|
|
135
141
|
}
|
|
@@ -162,6 +168,7 @@ var XStarMdEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
162
168
|
switch (e.type) {
|
|
163
169
|
case 'keydown':
|
|
164
170
|
{
|
|
171
|
+
// 组合时不触发快捷键
|
|
165
172
|
if (!e.nativeEvent.isComposing) {
|
|
166
173
|
composeHandlers(options.keyboardEventHandlers)({
|
|
167
174
|
history: history,
|
|
@@ -178,163 +185,165 @@ var XStarMdEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
178
185
|
useEffect(function () {
|
|
179
186
|
var _containerRef$current;
|
|
180
187
|
var listener = function listener(e) {
|
|
181
|
-
|
|
182
|
-
|
|
188
|
+
var targetRange = e.getTargetRanges()[0];
|
|
189
|
+
if (!containerRef.current || !targetRange) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
var startOffset = container.getOffset(containerRef.current, targetRange.startContainer, targetRange.startOffset);
|
|
193
|
+
var endOffset = container.getOffset(containerRef.current, targetRange.endContainer, targetRange.endOffset);
|
|
194
|
+
var selection = createSelection(startOffset, endOffset);
|
|
195
|
+
switch (e.inputType) {
|
|
196
|
+
case 'insertText':
|
|
197
|
+
{
|
|
198
|
+
e.preventDefault();
|
|
199
|
+
if (e.data !== null) {
|
|
200
|
+
dispatch({
|
|
201
|
+
type: 'insert',
|
|
202
|
+
payload: {
|
|
203
|
+
text: e.data
|
|
204
|
+
},
|
|
205
|
+
selection: selection
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
break;
|
|
209
|
+
}
|
|
210
|
+
case 'insertReplacementText':
|
|
211
|
+
case 'insertFromDrop':
|
|
212
|
+
case 'insertFromPaste':
|
|
213
|
+
{
|
|
214
|
+
var _e$dataTransfer, _e$dataTransfer2;
|
|
215
|
+
e.preventDefault();
|
|
216
|
+
if ((_e$dataTransfer = e.dataTransfer) !== null && _e$dataTransfer !== void 0 && _e$dataTransfer.types.includes('text/plain')) {
|
|
217
|
+
dispatch({
|
|
218
|
+
type: 'insert',
|
|
219
|
+
payload: {
|
|
220
|
+
text: e.dataTransfer.getData('text/plain')
|
|
221
|
+
},
|
|
222
|
+
selection: selection,
|
|
223
|
+
batch: true
|
|
224
|
+
});
|
|
225
|
+
dispatch({
|
|
226
|
+
type: 'batch'
|
|
227
|
+
});
|
|
228
|
+
} else if ((_e$dataTransfer2 = e.dataTransfer) !== null && _e$dataTransfer2 !== void 0 && _e$dataTransfer2.types.includes('Files')) {
|
|
229
|
+
var _file = e.dataTransfer.files[0];
|
|
230
|
+
onInsertFile === null || onInsertFile === void 0 ? void 0 : onInsertFile(_file, {
|
|
231
|
+
description: _file.name,
|
|
232
|
+
image: _file.type.startsWith('image/')
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
237
|
+
case 'insertLineBreak':
|
|
238
|
+
case 'insertParagraph':
|
|
183
239
|
{
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
{
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
ignoreNext.current = true;
|
|
245
|
-
dispatch({
|
|
246
|
-
type: 'insert',
|
|
247
|
-
payload: {
|
|
248
|
-
text: e.data
|
|
249
|
-
},
|
|
250
|
-
selection: _selection2
|
|
251
|
-
});
|
|
252
|
-
}
|
|
253
|
-
break;
|
|
254
|
-
}
|
|
255
|
-
case 'deleteWordBackward':
|
|
256
|
-
case 'deleteWordForward':
|
|
257
|
-
case 'deleteContentBackward':
|
|
258
|
-
case 'deleteContentForward':
|
|
259
|
-
{
|
|
260
|
-
e.preventDefault();
|
|
261
|
-
if (startOffset < endOffset) {
|
|
262
|
-
dispatch({
|
|
263
|
-
type: 'insert',
|
|
264
|
-
payload: {
|
|
265
|
-
text: ''
|
|
266
|
-
},
|
|
267
|
-
selection: _selection2
|
|
268
|
-
});
|
|
269
|
-
} else if (e.inputType.endsWith('Backward')) {
|
|
270
|
-
if (startOffset) {
|
|
271
|
-
dispatch({
|
|
272
|
-
type: 'insert',
|
|
273
|
-
payload: {
|
|
274
|
-
text: ''
|
|
275
|
-
},
|
|
276
|
-
selection: createSelection(startOffset - 1, endOffset)
|
|
277
|
-
});
|
|
278
|
-
}
|
|
279
|
-
} else {
|
|
280
|
-
if (endOffset < sourceCodeLatest.current.length - 1) {
|
|
281
|
-
dispatch({
|
|
282
|
-
type: 'insert',
|
|
283
|
-
payload: {
|
|
284
|
-
text: ''
|
|
285
|
-
},
|
|
286
|
-
selection: createSelection(startOffset, endOffset + 1)
|
|
287
|
-
});
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
break;
|
|
291
|
-
}
|
|
292
|
-
case 'deleteByDrag':
|
|
293
|
-
case 'deleteCompositionText':
|
|
294
|
-
{
|
|
295
|
-
ignoreNext.current = true;
|
|
296
|
-
dispatch({
|
|
297
|
-
type: 'insert',
|
|
298
|
-
payload: {
|
|
299
|
-
text: ''
|
|
300
|
-
},
|
|
301
|
-
selection: _selection2
|
|
302
|
-
});
|
|
303
|
-
break;
|
|
304
|
-
}
|
|
305
|
-
case 'formatBold':
|
|
306
|
-
{
|
|
307
|
-
e.preventDefault();
|
|
308
|
-
dispatch({
|
|
309
|
-
type: 'toggle',
|
|
310
|
-
payload: {
|
|
311
|
-
type: 'strong'
|
|
312
|
-
},
|
|
313
|
-
selection: _selection2
|
|
314
|
-
});
|
|
315
|
-
break;
|
|
316
|
-
}
|
|
317
|
-
case 'formatItalic':
|
|
318
|
-
{
|
|
319
|
-
e.preventDefault();
|
|
320
|
-
dispatch({
|
|
321
|
-
type: 'toggle',
|
|
322
|
-
payload: {
|
|
323
|
-
type: 'emphasis'
|
|
324
|
-
},
|
|
325
|
-
selection: _selection2
|
|
326
|
-
});
|
|
327
|
-
break;
|
|
328
|
-
}
|
|
329
|
-
default:
|
|
330
|
-
{
|
|
331
|
-
e.preventDefault();
|
|
332
|
-
break;
|
|
333
|
-
}
|
|
240
|
+
e.preventDefault();
|
|
241
|
+
dispatch({
|
|
242
|
+
type: 'insert',
|
|
243
|
+
payload: {
|
|
244
|
+
text: '\n'
|
|
245
|
+
},
|
|
246
|
+
selection: selection
|
|
247
|
+
});
|
|
248
|
+
break;
|
|
249
|
+
}
|
|
250
|
+
case 'insertCompositionText':
|
|
251
|
+
case 'insertFromComposition':
|
|
252
|
+
{
|
|
253
|
+
// 避免 DOM 更新扰乱组合
|
|
254
|
+
ignoreNext.current = true;
|
|
255
|
+
if (e.data !== null) {
|
|
256
|
+
dispatch({
|
|
257
|
+
type: 'insert',
|
|
258
|
+
payload: {
|
|
259
|
+
text: e.data
|
|
260
|
+
},
|
|
261
|
+
selection: selection,
|
|
262
|
+
batch: true
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
break;
|
|
266
|
+
}
|
|
267
|
+
case 'deleteWordBackward':
|
|
268
|
+
case 'deleteWordForward':
|
|
269
|
+
case 'deleteContentBackward':
|
|
270
|
+
case 'deleteContentForward':
|
|
271
|
+
{
|
|
272
|
+
e.preventDefault();
|
|
273
|
+
if (startOffset < endOffset) {
|
|
274
|
+
dispatch({
|
|
275
|
+
type: 'insert',
|
|
276
|
+
payload: {
|
|
277
|
+
text: ''
|
|
278
|
+
},
|
|
279
|
+
selection: selection
|
|
280
|
+
});
|
|
281
|
+
} else if (e.inputType.endsWith('Backward')) {
|
|
282
|
+
if (startOffset) {
|
|
283
|
+
dispatch({
|
|
284
|
+
type: 'insert',
|
|
285
|
+
payload: {
|
|
286
|
+
text: ''
|
|
287
|
+
},
|
|
288
|
+
selection: createSelection(startOffset - 1, endOffset)
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
} else {
|
|
292
|
+
if (endOffset < sourceCodeLatest.current.length) {
|
|
293
|
+
dispatch({
|
|
294
|
+
type: 'insert',
|
|
295
|
+
payload: {
|
|
296
|
+
text: ''
|
|
297
|
+
},
|
|
298
|
+
selection: createSelection(startOffset, endOffset + 1)
|
|
299
|
+
});
|
|
334
300
|
}
|
|
335
301
|
}
|
|
336
302
|
break;
|
|
337
303
|
}
|
|
304
|
+
case 'deleteByDrag':
|
|
305
|
+
case 'deleteCompositionText':
|
|
306
|
+
{
|
|
307
|
+
ignoreNext.current = true;
|
|
308
|
+
dispatch({
|
|
309
|
+
type: 'insert',
|
|
310
|
+
payload: {
|
|
311
|
+
text: ''
|
|
312
|
+
},
|
|
313
|
+
selection: selection,
|
|
314
|
+
batch: true
|
|
315
|
+
});
|
|
316
|
+
break;
|
|
317
|
+
}
|
|
318
|
+
case 'formatBold':
|
|
319
|
+
{
|
|
320
|
+
e.preventDefault();
|
|
321
|
+
dispatch({
|
|
322
|
+
type: 'toggle',
|
|
323
|
+
payload: {
|
|
324
|
+
type: 'strong'
|
|
325
|
+
},
|
|
326
|
+
selection: selection
|
|
327
|
+
});
|
|
328
|
+
break;
|
|
329
|
+
}
|
|
330
|
+
case 'formatItalic':
|
|
331
|
+
{
|
|
332
|
+
e.preventDefault();
|
|
333
|
+
dispatch({
|
|
334
|
+
type: 'toggle',
|
|
335
|
+
payload: {
|
|
336
|
+
type: 'emphasis'
|
|
337
|
+
},
|
|
338
|
+
selection: selection
|
|
339
|
+
});
|
|
340
|
+
break;
|
|
341
|
+
}
|
|
342
|
+
default:
|
|
343
|
+
{
|
|
344
|
+
e.preventDefault();
|
|
345
|
+
break;
|
|
346
|
+
}
|
|
338
347
|
}
|
|
339
348
|
};
|
|
340
349
|
(_containerRef$current = containerRef.current) === null || _containerRef$current === void 0 ? void 0 : _containerRef$current.addEventListener('beforeinput', listener);
|