x-star-editor 0.3.4 → 0.3.6
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/FileInput.d.ts +2 -1
- package/dist/components/FileInput.js +3 -1
- package/dist/components/Toolbar.js +21 -7
- package/dist/styles/index.css +4 -4
- package/dist/utils/container.d.ts +1 -0
- package/dist/utils/container.js +35 -38
- package/dist/utils/history.d.ts +2 -2
- package/dist/utils/history.js +22 -11
- package/dist/x-star-editor/index.d.ts +5 -1
- package/dist/x-star-editor/index.js +25 -7
- package/dist/x-star-md-editor/index.d.ts +4 -0
- package/dist/x-star-md-editor/index.js +17 -8
- package/package.json +1 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
interface FileInputProps {
|
|
3
|
+
image?: boolean;
|
|
3
4
|
onCancel: () => void;
|
|
4
5
|
onOk: (data: ({
|
|
5
6
|
type: 'file';
|
|
@@ -11,5 +12,5 @@ interface FileInputProps {
|
|
|
11
12
|
description: string;
|
|
12
13
|
}) => void;
|
|
13
14
|
}
|
|
14
|
-
declare const FileInput: ({ onCancel, onOk }: FileInputProps) => React.JSX.Element;
|
|
15
|
+
declare const FileInput: ({ image, onCancel, onOk }: FileInputProps) => React.JSX.Element;
|
|
15
16
|
export default FileInput;
|
|
@@ -6,7 +6,8 @@ import { useLocale } from "../locales";
|
|
|
6
6
|
import { prefix } from "../utils/global";
|
|
7
7
|
var FileInput = function FileInput(_ref) {
|
|
8
8
|
var _file$name;
|
|
9
|
-
var
|
|
9
|
+
var image = _ref.image,
|
|
10
|
+
onCancel = _ref.onCancel,
|
|
10
11
|
onOk = _ref.onOk;
|
|
11
12
|
var _useState = useState('file'),
|
|
12
13
|
_useState2 = _slicedToArray(_useState, 2),
|
|
@@ -47,6 +48,7 @@ var FileInput = function FileInput(_ref) {
|
|
|
47
48
|
}, /*#__PURE__*/React.createElement("input", {
|
|
48
49
|
className: classNames("".concat(prefix, "hidden")),
|
|
49
50
|
type: "file",
|
|
51
|
+
accept: image ? 'image/*' : undefined,
|
|
50
52
|
onChange: function onChange(e) {
|
|
51
53
|
var _e$target$files;
|
|
52
54
|
return setFile((_e$target$files = e.target.files) === null || _e$target$files === void 0 ? void 0 : _e$target$files[0]);
|
|
@@ -78,7 +78,7 @@ var Item = function Item(_ref) {
|
|
|
78
78
|
return /*#__PURE__*/React.createElement("div", {
|
|
79
79
|
className: classNames("".concat(prefix, "item-container"))
|
|
80
80
|
}, /*#__PURE__*/React.createElement("div", {
|
|
81
|
-
className: classNames("".concat(prefix, "item"), (_classNames = {}, _defineProperty(_classNames, "".concat(prefix, "disabled"), disabled), _defineProperty(_classNames, "".concat(prefix, "active"),
|
|
81
|
+
className: classNames("".concat(prefix, "item"), (_classNames = {}, _defineProperty(_classNames, "".concat(prefix, "disabled"), disabled), _defineProperty(_classNames, "".concat(prefix, "active"), popoverMount), _classNames)),
|
|
82
82
|
onClick: function onClick() {
|
|
83
83
|
if (!disabled) {
|
|
84
84
|
setTooltipOpen(false);
|
|
@@ -315,6 +315,7 @@ export var getDefaultToolbarItemMap = function getDefaultToolbarItemMap(locale,
|
|
|
315
315
|
tooltip: t('image'),
|
|
316
316
|
popoverRender: function popoverRender(exec, close) {
|
|
317
317
|
return /*#__PURE__*/React.createElement(FileInput, {
|
|
318
|
+
image: true,
|
|
318
319
|
onCancel: close,
|
|
319
320
|
onOk: function onOk(data) {
|
|
320
321
|
if (data.type === 'file') {
|
|
@@ -422,7 +423,12 @@ export var getDefaultToolbarItemMap = function getDefaultToolbarItemMap(locale,
|
|
|
422
423
|
children: /*#__PURE__*/React.createElement(SvgOrderedList, {
|
|
423
424
|
className: classNames("".concat(prefix, "icon"))
|
|
424
425
|
}),
|
|
425
|
-
tooltip: t('orderedList')
|
|
426
|
+
tooltip: t('orderedList'),
|
|
427
|
+
onClick: function onClick(exec) {
|
|
428
|
+
return exec(toggleHandler({
|
|
429
|
+
type: 'orderedList'
|
|
430
|
+
}));
|
|
431
|
+
}
|
|
426
432
|
},
|
|
427
433
|
redo: function redo(_ref5) {
|
|
428
434
|
var history = _ref5.history;
|
|
@@ -458,7 +464,12 @@ export var getDefaultToolbarItemMap = function getDefaultToolbarItemMap(locale,
|
|
|
458
464
|
children: /*#__PURE__*/React.createElement(SvgTaskList, {
|
|
459
465
|
className: classNames("".concat(prefix, "icon"))
|
|
460
466
|
}),
|
|
461
|
-
tooltip: t('taskList')
|
|
467
|
+
tooltip: t('taskList'),
|
|
468
|
+
onClick: function onClick(exec) {
|
|
469
|
+
return exec(toggleHandler({
|
|
470
|
+
type: 'taskList'
|
|
471
|
+
}));
|
|
472
|
+
}
|
|
462
473
|
},
|
|
463
474
|
thematicBreak: {
|
|
464
475
|
children: /*#__PURE__*/React.createElement(SvgThematicBreak, {
|
|
@@ -530,14 +541,17 @@ export var getDefaultToolbarItemMap = function getDefaultToolbarItemMap(locale,
|
|
|
530
541
|
children: /*#__PURE__*/React.createElement(SvgUnorderedList, {
|
|
531
542
|
className: classNames("".concat(prefix, "icon"))
|
|
532
543
|
}),
|
|
533
|
-
tooltip: t('unorderedList')
|
|
544
|
+
tooltip: t('unorderedList'),
|
|
545
|
+
onClick: function onClick(exec) {
|
|
546
|
+
return exec(toggleHandler({
|
|
547
|
+
type: 'unorderedList'
|
|
548
|
+
}));
|
|
549
|
+
}
|
|
534
550
|
}
|
|
535
551
|
};
|
|
536
552
|
};
|
|
537
553
|
export var getDefaultToolbarItems = function getDefaultToolbarItems() {
|
|
538
|
-
return [['heading', 'strong', 'emphasis', 'delete'], ['thematicBreak', 'blockquote' /** 'table' */], ['link', 'image', 'mermaid'], ['inlineCode', 'code', 'inlineMath', 'math'], ['undo', 'redo']
|
|
539
|
-
// ['orderedList', 'unorderedList', 'taskList'],
|
|
540
|
-
['toMarkdown', 'toHTML']
|
|
554
|
+
return [['heading', 'strong', 'emphasis', 'delete'], ['thematicBreak', 'blockquote' /** 'table' */], ['link', 'image', 'mermaid'], ['inlineCode', 'code', 'inlineMath', 'math'], ['orderedList', 'unorderedList', 'taskList'], ['toMarkdown', 'toHTML'], ['undo', 'redo']
|
|
541
555
|
// ['help'],
|
|
542
556
|
];
|
|
543
557
|
};
|
package/dist/styles/index.css
CHANGED
|
@@ -114,7 +114,7 @@
|
|
|
114
114
|
background-color: rgba(230, 247, 255, 0.7);
|
|
115
115
|
cursor: not-allowed;
|
|
116
116
|
}
|
|
117
|
-
.x-star-editor-toolbar .x-star-editor-item-container .x-star-editor-item.x-star-editor-active {
|
|
117
|
+
.x-star-editor-toolbar .x-star-editor-item-container .x-star-editor-item:hover, .x-star-editor-toolbar .x-star-editor-item-container .x-star-editor-item.x-star-editor-active {
|
|
118
118
|
background-color: #cbedfd;
|
|
119
119
|
}
|
|
120
120
|
.x-star-editor-toolbar .x-star-editor-item-container .x-star-editor-item .x-star-editor-icon {
|
|
@@ -179,7 +179,7 @@
|
|
|
179
179
|
.x-star-editor-editor.x-star-editor-fullscreen {
|
|
180
180
|
position: fixed;
|
|
181
181
|
inset: 0;
|
|
182
|
-
z-index:
|
|
182
|
+
z-index: 9999;
|
|
183
183
|
}
|
|
184
184
|
.x-star-editor-editor.x-star-editor-fullscreen > .x-star-editor-md-editor,
|
|
185
185
|
.x-star-editor-editor.x-star-editor-fullscreen > .x-star-editor-md-viewer {
|
|
@@ -237,10 +237,10 @@
|
|
|
237
237
|
background-color: #c1def1;
|
|
238
238
|
}
|
|
239
239
|
.x-star-editor-md-editor > :first-child {
|
|
240
|
-
margin-top:
|
|
240
|
+
margin-top: 0.5em;
|
|
241
241
|
}
|
|
242
242
|
.x-star-editor-md-editor > :last-child {
|
|
243
|
-
margin-bottom:
|
|
243
|
+
margin-bottom: 0.5em;
|
|
244
244
|
}
|
|
245
245
|
|
|
246
246
|
.x-star-editor-md-viewer {
|
|
@@ -41,4 +41,5 @@ export declare const useContainer: (ref: React.RefObject<HTMLDivElement>) => {
|
|
|
41
41
|
getOffset: (root: Node, targetNode: Node, targetOffset: number) => number;
|
|
42
42
|
getSelection: () => ContainerSelection;
|
|
43
43
|
setSelection: ({ anchorOffset, focusOffset }: ContainerSelection) => void;
|
|
44
|
+
normalizeSelection: () => void;
|
|
44
45
|
};
|
package/dist/utils/container.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import _createForOfIteratorHelper from "@babel/runtime/helpers/esm/createForOfIteratorHelper";
|
|
2
|
-
import {
|
|
2
|
+
import { useRef } from 'react';
|
|
3
3
|
import { editorRender } from "./markdown";
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -294,52 +294,49 @@ export var useContainer = function useContainer(ref) {
|
|
|
294
294
|
range.setEnd(focus.node, focus.offset);
|
|
295
295
|
var rangeRect = range.getBoundingClientRect();
|
|
296
296
|
var containerRect = ref.current.getBoundingClientRect();
|
|
297
|
-
var topOffset = rangeRect.top - containerRect.top;
|
|
298
|
-
var bottomOffset = rangeRect.bottom - containerRect.bottom;
|
|
297
|
+
var topOffset = Math.round(rangeRect.top - containerRect.top);
|
|
298
|
+
var bottomOffset = Math.round(rangeRect.bottom - containerRect.bottom);
|
|
299
299
|
|
|
300
300
|
// 将光标滚动到视口内
|
|
301
|
-
if (topOffset <
|
|
302
|
-
ref.current.scrollTop += topOffset;
|
|
303
|
-
} else if (bottomOffset >
|
|
304
|
-
ref.current.scrollTop += bottomOffset;
|
|
301
|
+
if (topOffset < 1) {
|
|
302
|
+
ref.current.scrollTop += topOffset - 1;
|
|
303
|
+
} else if (bottomOffset > -1) {
|
|
304
|
+
ref.current.scrollTop += bottomOffset + 1;
|
|
305
305
|
}
|
|
306
306
|
};
|
|
307
307
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
return function () {
|
|
335
|
-
return document.removeEventListener('selectionchange', listener);
|
|
336
|
-
};
|
|
337
|
-
}, []);
|
|
308
|
+
/**
|
|
309
|
+
* 标准化容器选区,确保光标不在零宽空格后
|
|
310
|
+
*/
|
|
311
|
+
var normalizeSelection = function normalizeSelection() {
|
|
312
|
+
var _anchorNode$nodeValue, _focusNode$nodeValue;
|
|
313
|
+
var selection = window.getSelection();
|
|
314
|
+
if (!selection || !selection.anchorNode || !selection.focusNode || !ref.current) {
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
var update = false;
|
|
318
|
+
var anchorNode = selection.anchorNode,
|
|
319
|
+
anchorOffset = selection.anchorOffset,
|
|
320
|
+
focusNode = selection.focusNode,
|
|
321
|
+
focusOffset = selection.focusOffset;
|
|
322
|
+
if (anchorNode.nodeType === Node.TEXT_NODE && ((_anchorNode$nodeValue = anchorNode.nodeValue) === null || _anchorNode$nodeValue === void 0 ? void 0 : _anchorNode$nodeValue[anchorOffset - 1]) === "\u200B") {
|
|
323
|
+
update = true;
|
|
324
|
+
anchorOffset--;
|
|
325
|
+
}
|
|
326
|
+
if (focusNode.nodeType === Node.TEXT_NODE && ((_focusNode$nodeValue = focusNode.nodeValue) === null || _focusNode$nodeValue === void 0 ? void 0 : _focusNode$nodeValue[focusOffset - 1]) === "\u200B") {
|
|
327
|
+
update = true;
|
|
328
|
+
focusOffset--;
|
|
329
|
+
}
|
|
330
|
+
if (update) {
|
|
331
|
+
selection.setBaseAndExtent(anchorNode, anchorOffset, focusNode, focusOffset);
|
|
332
|
+
}
|
|
333
|
+
};
|
|
338
334
|
return useRef({
|
|
339
335
|
getText: getText,
|
|
340
336
|
setText: setText,
|
|
341
337
|
getOffset: getOffset,
|
|
342
338
|
getSelection: getSelection,
|
|
343
|
-
setSelection: setSelection
|
|
339
|
+
setSelection: setSelection,
|
|
340
|
+
normalizeSelection: normalizeSelection
|
|
344
341
|
}).current;
|
|
345
342
|
};
|
package/dist/utils/history.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export interface InsertAction {
|
|
|
17
17
|
export interface ToggleAction {
|
|
18
18
|
type: 'toggle';
|
|
19
19
|
payload: {
|
|
20
|
-
type: 'blockquote' | 'delete' | 'emphasis' | 'inlineCode' | 'inlineMath' | 'math' | 'strong' | 'thematicBreak';
|
|
20
|
+
type: 'blockquote' | 'delete' | 'emphasis' | 'inlineCode' | 'inlineMath' | 'math' | 'orderedList' | 'strong' | 'taskList' | 'thematicBreak' | 'unorderedList';
|
|
21
21
|
} | {
|
|
22
22
|
type: 'code';
|
|
23
23
|
lang: string;
|
|
@@ -66,7 +66,7 @@ export interface SelectAction {
|
|
|
66
66
|
selection: ContainerSelection;
|
|
67
67
|
}
|
|
68
68
|
type HistoryAction = UndoAction | RedoAction | BatchAction | SelectAction;
|
|
69
|
-
export declare const useHistory: (initialSourceCode: string) => {
|
|
69
|
+
export declare const useHistory: (initialSourceCode: string, readOnly?: boolean) => {
|
|
70
70
|
history: History;
|
|
71
71
|
sourceCode: string;
|
|
72
72
|
selection: ContainerSelection;
|
package/dist/utils/history.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
2
2
|
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
3
3
|
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
|
|
4
|
-
import { useReducer } from 'react';
|
|
4
|
+
import { useReducer, useRef } from 'react';
|
|
5
5
|
import { createSelection, getRange } from "./container";
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -35,21 +35,26 @@ var stateReducer = function stateReducer(_ref, action) {
|
|
|
35
35
|
var lineAfter = sourceCode.slice(lineEndOffset);
|
|
36
36
|
switch (action.payload.type) {
|
|
37
37
|
case 'blockquote':
|
|
38
|
+
case 'orderedList':
|
|
39
|
+
case 'taskList':
|
|
40
|
+
case 'unorderedList':
|
|
38
41
|
{
|
|
42
|
+
var type = action.payload.type;
|
|
43
|
+
var prefixes = type === 'blockquote' ? ['>', '>'] : type === 'orderedList' ? ['\\d+\\.', '1.'] : type === 'taskList' ? ['[*+-] \\[[ x]]', '* [ ]'] : ['[*+-]', '*'];
|
|
39
44
|
var lines = sourceCode.slice(lineStartOffset, lineEndOffset).split('\n');
|
|
40
45
|
var values = lines.map(function (line) {
|
|
41
|
-
return
|
|
46
|
+
return new RegExp("^ {0,3}".concat(prefixes[0], " +")).test(line);
|
|
42
47
|
});
|
|
43
48
|
for (var i = 0; i < values.length; i++) {
|
|
44
49
|
if (values[i]) {
|
|
45
|
-
lines[i] = lines[i].replace(
|
|
50
|
+
lines[i] = lines[i].replace(new RegExp("^ {0,3}".concat(prefixes[0], " +")), '');
|
|
46
51
|
}
|
|
47
52
|
}
|
|
48
53
|
if (values.some(function (value) {
|
|
49
54
|
return !value;
|
|
50
55
|
})) {
|
|
51
56
|
for (var _i = 0; _i < lines.length; _i++) {
|
|
52
|
-
lines[_i] = "
|
|
57
|
+
lines[_i] = "".concat(prefixes[1], " ").concat(lines[_i]);
|
|
53
58
|
}
|
|
54
59
|
}
|
|
55
60
|
var _text = lines.join('\n');
|
|
@@ -76,8 +81,8 @@ var stateReducer = function stateReducer(_ref, action) {
|
|
|
76
81
|
case 'inlineMath':
|
|
77
82
|
case 'strong':
|
|
78
83
|
{
|
|
79
|
-
var
|
|
80
|
-
var delimiters =
|
|
84
|
+
var _type = action.payload.type;
|
|
85
|
+
var delimiters = _type === 'emphasis' ? ['*', '_'] : _type === 'strong' ? ['**', '__'] : _type === 'inlineCode' ? ['`'] : _type === 'delete' ? ['~~'] : ['$'];
|
|
81
86
|
var _text2 = sourceCode.slice(startOffset, endOffset);
|
|
82
87
|
for (var _i2 = 0, _delimiters = delimiters; _i2 < _delimiters.length; _i2++) {
|
|
83
88
|
var _delimiter = _delimiters[_i2];
|
|
@@ -128,12 +133,12 @@ var stateReducer = function stateReducer(_ref, action) {
|
|
|
128
133
|
case 'link':
|
|
129
134
|
{
|
|
130
135
|
var _action$payload2 = action.payload,
|
|
131
|
-
|
|
136
|
+
_type2 = _action$payload2.type,
|
|
132
137
|
url = _action$payload2.url,
|
|
133
138
|
description = _action$payload2.description;
|
|
134
139
|
return {
|
|
135
|
-
sourceCode: "".concat(before).concat(
|
|
136
|
-
selection: createSelection(startOffset + url.length + description.length + 4 + (
|
|
140
|
+
sourceCode: "".concat(before).concat(_type2 === 'image' ? '!' : '', "[").concat(description, "](").concat(url, ")").concat(after),
|
|
141
|
+
selection: createSelection(startOffset + url.length + description.length + 4 + (_type2 === 'image' ? 1 : 0))
|
|
137
142
|
};
|
|
138
143
|
}
|
|
139
144
|
case 'math':
|
|
@@ -268,7 +273,7 @@ var historyReducer = function historyReducer(_ref2, action) {
|
|
|
268
273
|
}
|
|
269
274
|
}
|
|
270
275
|
};
|
|
271
|
-
export var useHistory = function useHistory(initialSourceCode) {
|
|
276
|
+
export var useHistory = function useHistory(initialSourceCode, readOnly) {
|
|
272
277
|
var _useReducer = useReducer(historyReducer, initialSourceCode, function (text) {
|
|
273
278
|
var action = {
|
|
274
279
|
type: 'insert',
|
|
@@ -292,10 +297,16 @@ export var useHistory = function useHistory(initialSourceCode) {
|
|
|
292
297
|
_useReducer2 = _slicedToArray(_useReducer, 2),
|
|
293
298
|
history = _useReducer2[0],
|
|
294
299
|
dispatch = _useReducer2[1];
|
|
300
|
+
var readOnlyLatest = useRef(readOnly);
|
|
301
|
+
readOnlyLatest.current = readOnly;
|
|
295
302
|
return {
|
|
296
303
|
history: history,
|
|
297
304
|
sourceCode: history.states[history.index].sourceCode,
|
|
298
305
|
selection: history.selection,
|
|
299
|
-
dispatch:
|
|
306
|
+
dispatch: useRef(function (action) {
|
|
307
|
+
if (!readOnlyLatest.current) {
|
|
308
|
+
dispatch(action);
|
|
309
|
+
}
|
|
310
|
+
}).current
|
|
300
311
|
};
|
|
301
312
|
};
|
|
@@ -25,6 +25,10 @@ export interface XStarEditorProps {
|
|
|
25
25
|
* 初始文本
|
|
26
26
|
*/
|
|
27
27
|
initialValue?: string;
|
|
28
|
+
/**
|
|
29
|
+
* 是否只读
|
|
30
|
+
*/
|
|
31
|
+
readOnly?: XStarMdEditorProps['readOnly'];
|
|
28
32
|
/**
|
|
29
33
|
* 是否启用 Web Worker
|
|
30
34
|
*/
|
|
@@ -32,7 +36,7 @@ export interface XStarEditorProps {
|
|
|
32
36
|
/**
|
|
33
37
|
* 编辑器属性
|
|
34
38
|
*/
|
|
35
|
-
editorProps?: Omit<XStarMdEditorProps, 'height' | 'locale' | 'initialValue' | 'onChange' | 'onInsertFile'>;
|
|
39
|
+
editorProps?: Omit<XStarMdEditorProps, 'height' | 'locale' | 'initialValue' | 'readOnly' | 'onChange' | 'onInsertFile'>;
|
|
36
40
|
/**
|
|
37
41
|
* 查看器属性
|
|
38
42
|
*/
|
|
@@ -5,6 +5,7 @@ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
|
5
5
|
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
6
6
|
import classNames from 'classnames';
|
|
7
7
|
import React, { useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
|
|
8
|
+
import { createKeybindingsHandler } from 'tinykeys';
|
|
8
9
|
import SvgEditOnly from "../icons/EditOnly";
|
|
9
10
|
import SvgEnterFullscreen from "../icons/EnterFullscreen";
|
|
10
11
|
import SvgExitFullscreen from "../icons/ExitFullscreen";
|
|
@@ -42,6 +43,7 @@ var XStarEditor = /*#__PURE__*/React.forwardRef(function (_ref2, ref) {
|
|
|
42
43
|
locale = _ref2.locale,
|
|
43
44
|
_ref2$initialValue = _ref2.initialValue,
|
|
44
45
|
initialValue = _ref2$initialValue === void 0 ? '' : _ref2$initialValue,
|
|
46
|
+
readOnly = _ref2.readOnly,
|
|
45
47
|
enableWebWorker = _ref2.enableWebWorker,
|
|
46
48
|
editorProps = _ref2.editorProps,
|
|
47
49
|
viewerProps = _ref2.viewerProps,
|
|
@@ -64,6 +66,9 @@ var XStarEditor = /*#__PURE__*/React.forwardRef(function (_ref2, ref) {
|
|
|
64
66
|
var _editorRef$current, _viewerRef$current;
|
|
65
67
|
var editor = (_editorRef$current = editorRef.current) === null || _editorRef$current === void 0 ? void 0 : _editorRef$current.getEditorContainer();
|
|
66
68
|
var viewer = (_viewerRef$current = viewerRef.current) === null || _viewerRef$current === void 0 ? void 0 : _viewerRef$current.getViewerContainer();
|
|
69
|
+
if (!editor || !viewer) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
67
72
|
|
|
68
73
|
/**
|
|
69
74
|
* 获取两个父元素的子元素到各自父元素顶部的距离
|
|
@@ -122,7 +127,7 @@ var XStarEditor = /*#__PURE__*/React.forwardRef(function (_ref2, ref) {
|
|
|
122
127
|
var listener = function listener(e) {
|
|
123
128
|
var ignore = ignoreNext;
|
|
124
129
|
ignoreNext = false;
|
|
125
|
-
if (ignore
|
|
130
|
+
if (ignore) {
|
|
126
131
|
return;
|
|
127
132
|
}
|
|
128
133
|
var _ref3 = e.currentTarget === editor ? [editor, viewer] : [viewer, editor],
|
|
@@ -135,7 +140,7 @@ var XStarEditor = /*#__PURE__*/React.forwardRef(function (_ref2, ref) {
|
|
|
135
140
|
toOffsetTops = _getOffsetTops2[1];
|
|
136
141
|
for (var i = 0; i < fromOffsetTops.length - 1; i++) {
|
|
137
142
|
if (fromOffsetTops[i] <= fromElement.scrollTop && fromElement.scrollTop < fromOffsetTops[i + 1]) {
|
|
138
|
-
var scrollTop = (fromElement.scrollTop - fromOffsetTops[i]) / (fromOffsetTops[i + 1] - fromOffsetTops[i]) * (toOffsetTops[i + 1] - toOffsetTops[i]) + toOffsetTops[i];
|
|
143
|
+
var scrollTop = Math.round((fromElement.scrollTop - fromOffsetTops[i]) / (fromOffsetTops[i + 1] - fromOffsetTops[i]) * (toOffsetTops[i + 1] - toOffsetTops[i]) + toOffsetTops[i]);
|
|
139
144
|
if (toElement.scrollTop !== scrollTop) {
|
|
140
145
|
ignoreNext = true;
|
|
141
146
|
toElement.scrollTop = scrollTop;
|
|
@@ -144,11 +149,11 @@ var XStarEditor = /*#__PURE__*/React.forwardRef(function (_ref2, ref) {
|
|
|
144
149
|
}
|
|
145
150
|
}
|
|
146
151
|
};
|
|
147
|
-
editor
|
|
148
|
-
viewer
|
|
152
|
+
editor.addEventListener('scroll', listener);
|
|
153
|
+
viewer.addEventListener('scroll', listener);
|
|
149
154
|
return function () {
|
|
150
|
-
editor
|
|
151
|
-
viewer
|
|
155
|
+
editor.removeEventListener('scroll', listener);
|
|
156
|
+
viewer.removeEventListener('scroll', listener);
|
|
152
157
|
};
|
|
153
158
|
}, []);
|
|
154
159
|
var _useState = useState(initialValue),
|
|
@@ -202,13 +207,25 @@ var XStarEditor = /*#__PURE__*/React.forwardRef(function (_ref2, ref) {
|
|
|
202
207
|
}].concat(_toConsumableArray((_editorProps$plugins = editorProps === null || editorProps === void 0 ? void 0 : editorProps.plugins) !== null && _editorProps$plugins !== void 0 ? _editorProps$plugins : []));
|
|
203
208
|
}, [locale, editOnly, viewOnly, fullscreen, editorProps === null || editorProps === void 0 ? void 0 : editorProps.plugins]);
|
|
204
209
|
|
|
205
|
-
//
|
|
210
|
+
// 防止出现两个滚动条,按下 Esc 退出全屏
|
|
206
211
|
useEffect(function () {
|
|
207
212
|
if (fullscreen) {
|
|
208
213
|
var overflow = document.body.style.overflow;
|
|
214
|
+
var listener = createKeybindingsHandler({
|
|
215
|
+
Escape: function Escape(e) {
|
|
216
|
+
e.stopImmediatePropagation();
|
|
217
|
+
setFullscreen(false);
|
|
218
|
+
}
|
|
219
|
+
});
|
|
209
220
|
document.body.style.overflow = 'hidden';
|
|
221
|
+
document.addEventListener('keydown', listener, {
|
|
222
|
+
capture: true
|
|
223
|
+
});
|
|
210
224
|
return function () {
|
|
211
225
|
document.body.style.overflow = overflow;
|
|
226
|
+
document.removeEventListener('keydown', listener, {
|
|
227
|
+
capture: true
|
|
228
|
+
});
|
|
212
229
|
};
|
|
213
230
|
}
|
|
214
231
|
}, [fullscreen]);
|
|
@@ -223,6 +240,7 @@ var XStarEditor = /*#__PURE__*/React.forwardRef(function (_ref2, ref) {
|
|
|
223
240
|
height: height,
|
|
224
241
|
locale: locale,
|
|
225
242
|
initialValue: initialValue,
|
|
243
|
+
readOnly: viewOnly || readOnly,
|
|
226
244
|
plugins: editorPlugins,
|
|
227
245
|
onChange: function onChange(value) {
|
|
228
246
|
setValue(value);
|
|
@@ -16,12 +16,13 @@ var XStarMdEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
16
16
|
locale = _ref.locale,
|
|
17
17
|
_ref$initialValue = _ref.initialValue,
|
|
18
18
|
initialValue = _ref$initialValue === void 0 ? '' : _ref$initialValue,
|
|
19
|
+
readOnly = _ref.readOnly,
|
|
19
20
|
plugins = _ref.plugins,
|
|
20
21
|
onChange = _ref.onChange,
|
|
21
22
|
onInsertFile = _ref.onInsertFile;
|
|
22
23
|
var containerRef = useRef(null);
|
|
23
24
|
var container = useContainer(containerRef);
|
|
24
|
-
var _useHistory = useHistory(initialValue),
|
|
25
|
+
var _useHistory = useHistory(initialValue, readOnly),
|
|
25
26
|
history = _useHistory.history,
|
|
26
27
|
sourceCode = _useHistory.sourceCode,
|
|
27
28
|
selection = _useHistory.selection,
|
|
@@ -124,6 +125,11 @@ var XStarMdEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
124
125
|
});
|
|
125
126
|
break;
|
|
126
127
|
}
|
|
128
|
+
case 'compositionstart':
|
|
129
|
+
{
|
|
130
|
+
container.normalizeSelection();
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
127
133
|
}
|
|
128
134
|
};
|
|
129
135
|
var dragEventHandler = function dragEventHandler(e) {
|
|
@@ -183,14 +189,17 @@ var XStarMdEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
183
189
|
}
|
|
184
190
|
};
|
|
185
191
|
useEffect(function () {
|
|
186
|
-
var
|
|
192
|
+
var editor = containerRef.current;
|
|
193
|
+
if (!editor) {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
187
196
|
var listener = function listener(e) {
|
|
188
197
|
var targetRange = e.getTargetRanges()[0];
|
|
189
|
-
if (!targetRange
|
|
198
|
+
if (!targetRange) {
|
|
190
199
|
return;
|
|
191
200
|
}
|
|
192
|
-
var startOffset = container.getOffset(
|
|
193
|
-
var endOffset = container.getOffset(
|
|
201
|
+
var startOffset = container.getOffset(editor, targetRange.startContainer, targetRange.startOffset);
|
|
202
|
+
var endOffset = container.getOffset(editor, targetRange.endContainer, targetRange.endOffset);
|
|
194
203
|
var selection = createSelection(startOffset, endOffset);
|
|
195
204
|
switch (e.inputType) {
|
|
196
205
|
case 'insertText':
|
|
@@ -346,10 +355,9 @@ var XStarMdEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
346
355
|
}
|
|
347
356
|
}
|
|
348
357
|
};
|
|
349
|
-
|
|
358
|
+
editor.addEventListener('beforeinput', listener);
|
|
350
359
|
return function () {
|
|
351
|
-
|
|
352
|
-
return (_containerRef$current2 = containerRef.current) === null || _containerRef$current2 === void 0 ? void 0 : _containerRef$current2.removeEventListener('beforeinput', listener);
|
|
360
|
+
return editor.removeEventListener('beforeinput', listener);
|
|
353
361
|
};
|
|
354
362
|
}, []);
|
|
355
363
|
return /*#__PURE__*/React.createElement(LocaleProvider, {
|
|
@@ -369,6 +377,7 @@ var XStarMdEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
369
377
|
contentEditable: true,
|
|
370
378
|
onBlur: focusEventHandler,
|
|
371
379
|
onCompositionEnd: compositionEventHandler,
|
|
380
|
+
onCompositionStart: compositionEventHandler,
|
|
372
381
|
onCopy: clipboardEventHandler,
|
|
373
382
|
onCut: clipboardEventHandler,
|
|
374
383
|
onDragStart: dragEventHandler,
|