x-star-editor 0.2.6 → 0.3.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/Toolbar.js +125 -38
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/themes/lark.css +353 -0
- package/dist/utils/container.d.ts +1 -1
- package/dist/utils/container.js +60 -113
- package/dist/utils/handler.d.ts +1 -2
- package/dist/utils/handler.js +14 -189
- package/dist/utils/history.d.ts +1 -9
- package/dist/utils/history.js +11 -48
- package/dist/x-star-md-editor/index.js +195 -120
- package/dist/x-star-md-viewer/index.d.ts +4 -0
- package/dist/x-star-md-viewer/index.js +6 -5
- package/package.json +1 -1
|
@@ -3,7 +3,7 @@ import classNames from 'classnames';
|
|
|
3
3
|
import React, { useEffect, useImperativeHandle, useMemo, useRef } from 'react';
|
|
4
4
|
import Toolbar, { getDefaultToolbarItemMap, getDefaultToolbarItems } from "../components/Toolbar";
|
|
5
5
|
import { LocaleProvider } from "../locales";
|
|
6
|
-
import { getRange, useContainer } from "../utils/container";
|
|
6
|
+
import { createSelection, getRange, useContainer } from "../utils/container";
|
|
7
7
|
import { prefix } from "../utils/global";
|
|
8
8
|
import { composeHandlers, getDefaultKeyboardEventHandlers } from "../utils/handler";
|
|
9
9
|
import { useHistory } from "../utils/history";
|
|
@@ -26,11 +26,14 @@ var XStarMdEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
26
26
|
sourceCode = _useHistory.sourceCode,
|
|
27
27
|
selection = _useHistory.selection,
|
|
28
28
|
dispatch = _useHistory.dispatch;
|
|
29
|
+
var ignoreNext = useRef(false);
|
|
29
30
|
var initialized = useRef(false);
|
|
30
31
|
|
|
31
32
|
// 将文本同步到容器
|
|
32
33
|
useEffect(function () {
|
|
33
|
-
|
|
34
|
+
if (!ignoreNext.current) {
|
|
35
|
+
container.setText(sourceCode);
|
|
36
|
+
}
|
|
34
37
|
if (initialized.current) {
|
|
35
38
|
onChange === null || onChange === void 0 ? void 0 : onChange(sourceCode);
|
|
36
39
|
}
|
|
@@ -38,16 +41,14 @@ var XStarMdEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
38
41
|
|
|
39
42
|
// 将选区同步到容器
|
|
40
43
|
useEffect(function () {
|
|
41
|
-
if (initialized.current) {
|
|
44
|
+
if (!ignoreNext.current && initialized.current) {
|
|
42
45
|
container.setSelection(selection);
|
|
43
46
|
}
|
|
44
47
|
}, [selection]);
|
|
45
48
|
useEffect(function () {
|
|
49
|
+
ignoreNext.current = false;
|
|
46
50
|
initialized.current = true;
|
|
47
|
-
|
|
48
|
-
initialized.current = false;
|
|
49
|
-
};
|
|
50
|
-
}, []);
|
|
51
|
+
}, [sourceCode, selection]);
|
|
51
52
|
var historyLatest = useRef(history);
|
|
52
53
|
historyLatest.current = history;
|
|
53
54
|
var sourceCodeLatest = useRef(sourceCode);
|
|
@@ -97,110 +98,41 @@ var XStarMdEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
97
98
|
e.clipboardData.setData('text/plain', sourceCode.slice(startOffset, endOffset));
|
|
98
99
|
if (e.type === 'cut') {
|
|
99
100
|
dispatch({
|
|
100
|
-
type: '
|
|
101
|
+
type: 'insert',
|
|
102
|
+
payload: {
|
|
103
|
+
text: ''
|
|
104
|
+
},
|
|
101
105
|
selection: selection
|
|
102
106
|
});
|
|
103
107
|
}
|
|
104
108
|
}
|
|
105
109
|
break;
|
|
106
110
|
}
|
|
107
|
-
case 'paste':
|
|
108
|
-
{
|
|
109
|
-
e.preventDefault();
|
|
110
|
-
if (e.clipboardData.types.includes('text/plain')) {
|
|
111
|
-
dispatch({
|
|
112
|
-
type: 'insert',
|
|
113
|
-
payload: {
|
|
114
|
-
text: e.clipboardData.getData('text/plain')
|
|
115
|
-
},
|
|
116
|
-
selection: selection
|
|
117
|
-
});
|
|
118
|
-
} else if (e.clipboardData.types.includes('Files')) {
|
|
119
|
-
var _file = e.clipboardData.files[0];
|
|
120
|
-
onInsertFile === null || onInsertFile === void 0 ? void 0 : onInsertFile(_file, {
|
|
121
|
-
description: _file.name,
|
|
122
|
-
image: _file.type.startsWith('image/')
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
break;
|
|
126
|
-
}
|
|
127
111
|
}
|
|
128
112
|
};
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* 开始组合时的选区
|
|
132
|
-
*/
|
|
133
|
-
var compositionStartSelection = useRef();
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* 容器同步控制器
|
|
137
|
-
*/
|
|
138
|
-
var syncController = useMemo(function () {
|
|
139
|
-
var timer = 0;
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* 将最新的文本和选区同步到容器
|
|
143
|
-
*/
|
|
144
|
-
var sync = function sync() {
|
|
145
|
-
if (compositionStartSelection.current) {
|
|
146
|
-
var _selection = getSelection();
|
|
147
|
-
container.setText(sourceCodeLatest.current);
|
|
148
|
-
container.setSelection(_selection);
|
|
149
|
-
compositionStartSelection.current = undefined;
|
|
150
|
-
}
|
|
151
|
-
timer = 0;
|
|
152
|
-
};
|
|
153
|
-
return {
|
|
154
|
-
/**
|
|
155
|
-
* 在下个事件循环中同步
|
|
156
|
-
*/
|
|
157
|
-
start: function start() {
|
|
158
|
-
if (!timer) {
|
|
159
|
-
timer = window.setTimeout(sync);
|
|
160
|
-
}
|
|
161
|
-
},
|
|
162
|
-
/**
|
|
163
|
-
* 立即执行下个事件循环中的同步
|
|
164
|
-
*/
|
|
165
|
-
flush: function flush() {
|
|
166
|
-
if (timer) {
|
|
167
|
-
window.clearTimeout(timer);
|
|
168
|
-
sync();
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
};
|
|
172
|
-
}, []);
|
|
173
113
|
var compositionEventHandler = function compositionEventHandler(e) {
|
|
174
114
|
switch (e.type) {
|
|
175
115
|
case 'compositionend':
|
|
176
116
|
{
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
case 'compositionstart':
|
|
181
|
-
{
|
|
182
|
-
syncController.flush();
|
|
183
|
-
compositionStartSelection.current = getSelection();
|
|
117
|
+
var _selection = getSelection();
|
|
118
|
+
container.setText(sourceCodeLatest.current);
|
|
119
|
+
container.setSelection(_selection);
|
|
184
120
|
break;
|
|
185
121
|
}
|
|
186
122
|
}
|
|
187
123
|
};
|
|
188
124
|
var dragEventHandler = function dragEventHandler(e) {
|
|
125
|
+
var selection = getSelection();
|
|
126
|
+
var _getRange2 = getRange(selection),
|
|
127
|
+
startOffset = _getRange2.startOffset,
|
|
128
|
+
endOffset = _getRange2.endOffset;
|
|
189
129
|
switch (e.type) {
|
|
190
|
-
case '
|
|
130
|
+
case 'dragstart':
|
|
191
131
|
{
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
type: 'set',
|
|
197
|
-
payload: {
|
|
198
|
-
sourceCode: container.getText(),
|
|
199
|
-
selection: getSelection()
|
|
200
|
-
},
|
|
201
|
-
selection: _selection2
|
|
202
|
-
});
|
|
203
|
-
});
|
|
132
|
+
if (startOffset < endOffset) {
|
|
133
|
+
e.dataTransfer.clearData();
|
|
134
|
+
e.dataTransfer.setData('text/plain', sourceCode.slice(startOffset, endOffset));
|
|
135
|
+
}
|
|
204
136
|
break;
|
|
205
137
|
}
|
|
206
138
|
}
|
|
@@ -214,26 +146,6 @@ var XStarMdEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
214
146
|
}
|
|
215
147
|
}
|
|
216
148
|
};
|
|
217
|
-
var formEventHandler = function formEventHandler(e) {
|
|
218
|
-
switch (e.type) {
|
|
219
|
-
case 'beforeinput':
|
|
220
|
-
{
|
|
221
|
-
e.preventDefault();
|
|
222
|
-
if ('data' in e && typeof e.data === 'string') {
|
|
223
|
-
var _compositionStartSele;
|
|
224
|
-
dispatch({
|
|
225
|
-
type: 'insert',
|
|
226
|
-
payload: {
|
|
227
|
-
text: e.data
|
|
228
|
-
},
|
|
229
|
-
selection: (_compositionStartSele = compositionStartSelection.current) !== null && _compositionStartSele !== void 0 ? _compositionStartSele : getSelection()
|
|
230
|
-
});
|
|
231
|
-
compositionStartSelection.current = undefined;
|
|
232
|
-
}
|
|
233
|
-
break;
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
};
|
|
237
149
|
var onInsertFileLatest = useRef(onInsertFile);
|
|
238
150
|
onInsertFileLatest.current = onInsertFile;
|
|
239
151
|
var options = useMemo(function () {
|
|
@@ -250,9 +162,7 @@ var XStarMdEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
250
162
|
switch (e.type) {
|
|
251
163
|
case 'keydown':
|
|
252
164
|
{
|
|
253
|
-
if (
|
|
254
|
-
e.preventDefault();
|
|
255
|
-
} else {
|
|
165
|
+
if (!e.nativeEvent.isComposing) {
|
|
256
166
|
composeHandlers(options.keyboardEventHandlers)({
|
|
257
167
|
history: history,
|
|
258
168
|
sourceCode: sourceCode,
|
|
@@ -265,6 +175,174 @@ var XStarMdEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
265
175
|
}
|
|
266
176
|
}
|
|
267
177
|
};
|
|
178
|
+
useEffect(function () {
|
|
179
|
+
var _containerRef$current;
|
|
180
|
+
var listener = function listener(e) {
|
|
181
|
+
switch (e.type) {
|
|
182
|
+
case 'beforeinput':
|
|
183
|
+
{
|
|
184
|
+
var targetRange = e.getTargetRanges()[0];
|
|
185
|
+
if (containerRef.current && targetRange) {
|
|
186
|
+
var startOffset = container.getOffset(containerRef.current, targetRange.startContainer, targetRange.startOffset);
|
|
187
|
+
var endOffset = container.getOffset(containerRef.current, targetRange.endContainer, targetRange.endOffset);
|
|
188
|
+
var _selection2 = createSelection(startOffset, endOffset);
|
|
189
|
+
switch (e.inputType) {
|
|
190
|
+
case 'insertText':
|
|
191
|
+
{
|
|
192
|
+
e.preventDefault();
|
|
193
|
+
if (e.data !== null) {
|
|
194
|
+
dispatch({
|
|
195
|
+
type: 'insert',
|
|
196
|
+
payload: {
|
|
197
|
+
text: e.data
|
|
198
|
+
},
|
|
199
|
+
selection: _selection2
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
break;
|
|
203
|
+
}
|
|
204
|
+
case 'insertReplacementText':
|
|
205
|
+
case 'insertFromDrop':
|
|
206
|
+
case 'insertFromPaste':
|
|
207
|
+
{
|
|
208
|
+
var _e$dataTransfer, _e$dataTransfer2;
|
|
209
|
+
e.preventDefault();
|
|
210
|
+
if ((_e$dataTransfer = e.dataTransfer) !== null && _e$dataTransfer !== void 0 && _e$dataTransfer.types.includes('text/plain')) {
|
|
211
|
+
dispatch({
|
|
212
|
+
type: 'insert',
|
|
213
|
+
payload: {
|
|
214
|
+
text: e.dataTransfer.getData('text/plain')
|
|
215
|
+
},
|
|
216
|
+
selection: _selection2
|
|
217
|
+
});
|
|
218
|
+
} else if ((_e$dataTransfer2 = e.dataTransfer) !== null && _e$dataTransfer2 !== void 0 && _e$dataTransfer2.types.includes('Files')) {
|
|
219
|
+
var _file = e.dataTransfer.files[0];
|
|
220
|
+
onInsertFile === null || onInsertFile === void 0 ? void 0 : onInsertFile(_file, {
|
|
221
|
+
description: _file.name,
|
|
222
|
+
image: _file.type.startsWith('image/')
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
break;
|
|
226
|
+
}
|
|
227
|
+
case 'insertLineBreak':
|
|
228
|
+
case 'insertParagraph':
|
|
229
|
+
{
|
|
230
|
+
e.preventDefault();
|
|
231
|
+
dispatch({
|
|
232
|
+
type: 'insert',
|
|
233
|
+
payload: {
|
|
234
|
+
text: '\n'
|
|
235
|
+
},
|
|
236
|
+
selection: _selection2
|
|
237
|
+
});
|
|
238
|
+
break;
|
|
239
|
+
}
|
|
240
|
+
case 'insertCompositionText':
|
|
241
|
+
case 'insertFromComposition':
|
|
242
|
+
{
|
|
243
|
+
if (e.data !== null) {
|
|
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
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
break;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
};
|
|
340
|
+
(_containerRef$current = containerRef.current) === null || _containerRef$current === void 0 ? void 0 : _containerRef$current.addEventListener('beforeinput', listener);
|
|
341
|
+
return function () {
|
|
342
|
+
var _containerRef$current2;
|
|
343
|
+
return (_containerRef$current2 = containerRef.current) === null || _containerRef$current2 === void 0 ? void 0 : _containerRef$current2.removeEventListener('beforeinput', listener);
|
|
344
|
+
};
|
|
345
|
+
}, []);
|
|
268
346
|
return /*#__PURE__*/React.createElement(LocaleProvider, {
|
|
269
347
|
locale: locale
|
|
270
348
|
}, /*#__PURE__*/React.createElement(Toolbar, {
|
|
@@ -280,15 +358,12 @@ var XStarMdEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
280
358
|
height: height
|
|
281
359
|
}),
|
|
282
360
|
contentEditable: true,
|
|
283
|
-
onBeforeInput: formEventHandler,
|
|
284
361
|
onBlur: focusEventHandler,
|
|
285
362
|
onCompositionEnd: compositionEventHandler,
|
|
286
|
-
onCompositionStart: compositionEventHandler,
|
|
287
363
|
onCopy: clipboardEventHandler,
|
|
288
364
|
onCut: clipboardEventHandler,
|
|
289
|
-
|
|
290
|
-
onKeyDown: keyboardEventHandler
|
|
291
|
-
onPaste: clipboardEventHandler
|
|
365
|
+
onDragStart: dragEventHandler,
|
|
366
|
+
onKeyDown: keyboardEventHandler
|
|
292
367
|
}));
|
|
293
368
|
});
|
|
294
369
|
if (process.env.NODE_ENV !== 'production') {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
|
+
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
|
|
2
3
|
import _regeneratorRuntime from "@babel/runtime/helpers/esm/regeneratorRuntime";
|
|
3
4
|
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
|
|
4
5
|
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
@@ -9,13 +10,11 @@ var workerRaw = "(()=>{var e={470:e=>{\"use strict\";var t=Object.prototype.hasO
|
|
|
9
10
|
import { prefix } from "../utils/global";
|
|
10
11
|
import { composeHandlers } from "../utils/handler";
|
|
11
12
|
import { getDefaultSchema, postViewerRender, preViewerRender, viewerRender } from "../utils/markdown";
|
|
12
|
-
var workerURL = URL.createObjectURL(new Blob([workerRaw], {
|
|
13
|
-
type: 'text/javascript'
|
|
14
|
-
}));
|
|
15
13
|
var XStarMdViewer = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
16
14
|
var className = _ref.className,
|
|
17
15
|
style = _ref.style,
|
|
18
16
|
height = _ref.height,
|
|
17
|
+
theme = _ref.theme,
|
|
19
18
|
_ref$value = _ref.value,
|
|
20
19
|
value = _ref$value === void 0 ? '' : _ref$value,
|
|
21
20
|
plugins = _ref.plugins,
|
|
@@ -44,7 +43,9 @@ var XStarMdViewer = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
44
43
|
var worker = useRef();
|
|
45
44
|
useEffect(function () {
|
|
46
45
|
if (enableWebWorker) {
|
|
47
|
-
worker.current = new Worker(
|
|
46
|
+
worker.current = new Worker(URL.createObjectURL(new Blob([workerRaw], {
|
|
47
|
+
type: 'text/javascript'
|
|
48
|
+
})));
|
|
48
49
|
worker.current.addEventListener('message', function (_ref2) {
|
|
49
50
|
var data = _ref2.data;
|
|
50
51
|
return setChildren(postViewerRender(data, optionsLatest.current));
|
|
@@ -79,7 +80,7 @@ var XStarMdViewer = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
79
80
|
}, [value, options]);
|
|
80
81
|
return /*#__PURE__*/React.createElement("div", {
|
|
81
82
|
ref: containerRef,
|
|
82
|
-
className: classNames("".concat(prefix, "md-viewer"), className),
|
|
83
|
+
className: classNames("".concat(prefix, "md-viewer"), _defineProperty({}, "".concat(prefix, "theme-").concat(theme), theme), className),
|
|
83
84
|
style: _objectSpread(_objectSpread({}, style), {}, {
|
|
84
85
|
height: height
|
|
85
86
|
})
|