x-star-editor 0.3.0 → 0.3.1
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 +14 -6
- package/dist/utils/history.d.ts +11 -3
- package/dist/utils/history.js +28 -3
- package/dist/utils/markdown.js +2 -17
- 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
|
@@ -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();
|
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:
|
|
@@ -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);
|