x-star-editor 0.0.2 → 0.0.3
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/XStarEditor/index.d.ts +9 -4
- package/dist/XStarEditor/index.js +78 -24
- package/dist/XStarEditor/index.module.css +6 -6
- package/dist/XStarMdEditor/index.d.ts +1 -0
- package/dist/XStarMdEditor/index.js +4 -1
- package/dist/XStarMdEditor/index.module.css +0 -1
- package/dist/XStarMdViewer/index.d.ts +1 -0
- package/dist/XStarMdViewer/index.js +4 -1
- package/dist/XStarMdViewer/index.module.css +0 -1
- package/dist/components/FileInput.js +2 -2
- package/dist/components/FileInput.module.css +38 -38
- package/dist/components/Toolbar.js +1 -1
- package/dist/components/Toolbar.module.css +54 -55
- package/dist/index.d.ts +4 -4
- package/dist/index.js +3 -3
- package/dist/styles/prism.css +2 -2
- package/dist/utils/container.js +2 -2
- package/dist/utils/history.d.ts +1 -1
- package/dist/utils/markdown.js +70 -42
- package/package.json +1 -1
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type { XStarMdEditorProps } from '../XStarMdEditor';
|
|
3
|
-
import type { XStarMdViewerProps } from '../XStarMdViewer';
|
|
4
|
-
export interface
|
|
2
|
+
import type { XStarMdEditorHandle, XStarMdEditorProps } from '../XStarMdEditor';
|
|
3
|
+
import type { XStarMdViewerHandle, XStarMdViewerProps } from '../XStarMdViewer';
|
|
4
|
+
export interface XStarEditorHandle {
|
|
5
|
+
getEditor: () => XStarMdEditorHandle | null;
|
|
6
|
+
getViewer: () => XStarMdViewerHandle | null;
|
|
7
|
+
}
|
|
8
|
+
export interface XStarEditorProps {
|
|
5
9
|
height?: React.CSSProperties['height'];
|
|
6
10
|
initialValue?: string;
|
|
7
11
|
editorProps?: Omit<XStarMdEditorProps, 'initialValue' | 'onChange'>;
|
|
8
12
|
viewerProps?: Omit<XStarMdViewerProps, 'value'>;
|
|
9
13
|
onChange?: (value: string) => void;
|
|
10
14
|
}
|
|
11
|
-
declare const XStarEditor:
|
|
15
|
+
declare const XStarEditor: React.ForwardRefExoticComponent<XStarEditorProps & React.RefAttributes<XStarEditorHandle>>;
|
|
12
16
|
export default XStarEditor;
|
|
17
|
+
export declare const useEditorRef: () => React.RefObject<XStarEditorHandle>;
|
|
@@ -12,12 +12,12 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
|
|
|
12
12
|
function _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i.return && (_r = _i.return(), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } }
|
|
13
13
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
14
14
|
import classNames from 'classnames/bind';
|
|
15
|
-
import React, { useEffect, useRef, useState } from 'react';
|
|
16
|
-
import XStarMdEditor from "../XStarMdEditor";
|
|
17
|
-
import XStarMdViewer from "../XStarMdViewer";
|
|
15
|
+
import React, { useEffect, useImperativeHandle, useRef, useState } from 'react';
|
|
16
|
+
import XStarMdEditor, { useMdEditorRef } from "../XStarMdEditor";
|
|
17
|
+
import XStarMdViewer, { useMdViewerRef } from "../XStarMdViewer";
|
|
18
18
|
import styles from "./index.module.css";
|
|
19
19
|
var cx = classNames.bind(styles);
|
|
20
|
-
var XStarEditor = function
|
|
20
|
+
var XStarEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
21
21
|
var height = _ref.height,
|
|
22
22
|
initialValue = _ref.initialValue,
|
|
23
23
|
editorProps = _ref.editorProps,
|
|
@@ -27,44 +27,94 @@ var XStarEditor = function XStarEditor(_ref) {
|
|
|
27
27
|
_useState2 = _slicedToArray(_useState, 2),
|
|
28
28
|
value = _useState2[0],
|
|
29
29
|
setValue = _useState2[1];
|
|
30
|
-
var editorRef =
|
|
31
|
-
var viewerRef =
|
|
30
|
+
var editorRef = useMdEditorRef();
|
|
31
|
+
var viewerRef = useMdViewerRef();
|
|
32
|
+
useImperativeHandle(ref, function () {
|
|
33
|
+
return {
|
|
34
|
+
getEditor: function getEditor() {
|
|
35
|
+
return editorRef.current;
|
|
36
|
+
},
|
|
37
|
+
getViewer: function getViewer() {
|
|
38
|
+
return viewerRef.current;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
}, []);
|
|
42
|
+
|
|
43
|
+
// 同步滚动
|
|
32
44
|
useEffect(function () {
|
|
33
45
|
var _editorRef$current, _viewerRef$current;
|
|
34
46
|
var editor = (_editorRef$current = editorRef.current) === null || _editorRef$current === void 0 ? void 0 : _editorRef$current.getContainer();
|
|
35
47
|
var viewer = (_viewerRef$current = viewerRef.current) === null || _viewerRef$current === void 0 ? void 0 : _viewerRef$current.getContainer();
|
|
36
48
|
|
|
37
49
|
/**
|
|
38
|
-
*
|
|
50
|
+
* 获取两个父元素的子元素到各自父元素顶部的距离
|
|
39
51
|
*
|
|
40
|
-
* @param
|
|
41
|
-
* @param
|
|
42
|
-
* @returns
|
|
52
|
+
* @param fromElement 第一个父元素
|
|
53
|
+
* @param toElement 第二个父元素
|
|
54
|
+
* @returns 子元素到各自父元素顶部的距离
|
|
43
55
|
*/
|
|
44
|
-
var getOffsetTops = function getOffsetTops(
|
|
45
|
-
var
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
56
|
+
var getOffsetTops = function getOffsetTops(fromElement, toElement) {
|
|
57
|
+
var fromOffsetTops = [0];
|
|
58
|
+
var toOffsetTops = [0];
|
|
59
|
+
var fromLimit = fromElement.scrollHeight - fromElement.clientHeight;
|
|
60
|
+
var toLimit = toElement.scrollHeight - toElement.clientHeight;
|
|
61
|
+
if (fromLimit > 0 && toLimit > 0) {
|
|
62
|
+
for (var i = 0, j = 0; i < fromElement.children.length && j < toElement.children.length;) {
|
|
63
|
+
var _fromChild$getAttribu, _toChild$getAttribute;
|
|
64
|
+
var fromChild = fromElement.children[i];
|
|
65
|
+
var toChild = toElement.children[j];
|
|
66
|
+
var fromLine = parseInt((_fromChild$getAttribu = fromChild.getAttribute('line')) !== null && _fromChild$getAttribu !== void 0 ? _fromChild$getAttribu : '');
|
|
67
|
+
var toLine = parseInt((_toChild$getAttribute = toChild.getAttribute('line')) !== null && _toChild$getAttribute !== void 0 ? _toChild$getAttribute : '');
|
|
68
|
+
if (!(fromChild instanceof HTMLElement) || !fromLine) {
|
|
69
|
+
i++;
|
|
70
|
+
} else if (!(toChild instanceof HTMLElement) || !toLine) {
|
|
71
|
+
j++;
|
|
72
|
+
} else if (fromLine < toLine) {
|
|
73
|
+
i++;
|
|
74
|
+
} else if (fromLine > toLine) {
|
|
75
|
+
j++;
|
|
76
|
+
} else {
|
|
77
|
+
fromOffsetTops.push(fromChild.offsetTop);
|
|
78
|
+
toOffsetTops.push(toChild.offsetTop);
|
|
79
|
+
i++;
|
|
80
|
+
j++;
|
|
81
|
+
}
|
|
50
82
|
}
|
|
83
|
+
for (; fromOffsetTops[fromOffsetTops.length - 1] >= fromLimit || toOffsetTops[toOffsetTops.length - 1] >= toLimit;) {
|
|
84
|
+
fromOffsetTops.pop();
|
|
85
|
+
toOffsetTops.pop();
|
|
86
|
+
}
|
|
87
|
+
fromOffsetTops.push(fromLimit);
|
|
88
|
+
toOffsetTops.push(toLimit);
|
|
51
89
|
}
|
|
52
|
-
|
|
53
|
-
return offsetTops;
|
|
90
|
+
return [fromOffsetTops, toOffsetTops];
|
|
54
91
|
};
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* 是否忽略下一个滚动事件
|
|
95
|
+
*/
|
|
96
|
+
var ignoreNext = false;
|
|
55
97
|
var listener = function listener(e) {
|
|
56
|
-
|
|
98
|
+
var ignore = ignoreNext;
|
|
99
|
+
ignoreNext = false;
|
|
100
|
+
if (ignore || !editor || !viewer) {
|
|
57
101
|
return;
|
|
58
102
|
}
|
|
59
103
|
var _ref2 = e.currentTarget === editor ? [editor, viewer] : [viewer, editor],
|
|
60
104
|
_ref3 = _slicedToArray(_ref2, 2),
|
|
61
105
|
fromElement = _ref3[0],
|
|
62
106
|
toElement = _ref3[1];
|
|
63
|
-
var
|
|
64
|
-
|
|
107
|
+
var _getOffsetTops = getOffsetTops(fromElement, toElement),
|
|
108
|
+
_getOffsetTops2 = _slicedToArray(_getOffsetTops, 2),
|
|
109
|
+
fromOffsetTops = _getOffsetTops2[0],
|
|
110
|
+
toOffsetTops = _getOffsetTops2[1];
|
|
65
111
|
for (var i = 0; i < fromOffsetTops.length - 1; i++) {
|
|
66
112
|
if (fromOffsetTops[i] <= fromElement.scrollTop && fromElement.scrollTop < fromOffsetTops[i + 1]) {
|
|
67
|
-
|
|
113
|
+
var scrollTop = (fromElement.scrollTop - fromOffsetTops[i]) / (fromOffsetTops[i + 1] - fromOffsetTops[i]) * (toOffsetTops[i + 1] - toOffsetTops[i]) + toOffsetTops[i];
|
|
114
|
+
if (toElement.scrollTop !== scrollTop) {
|
|
115
|
+
ignoreNext = true;
|
|
116
|
+
toElement.scrollTop = scrollTop;
|
|
117
|
+
}
|
|
68
118
|
break;
|
|
69
119
|
}
|
|
70
120
|
}
|
|
@@ -110,5 +160,9 @@ var XStarEditor = function XStarEditor(_ref) {
|
|
|
110
160
|
}, viewerProps === null || viewerProps === void 0 ? void 0 : viewerProps.style),
|
|
111
161
|
value: value
|
|
112
162
|
})));
|
|
113
|
-
};
|
|
114
|
-
|
|
163
|
+
});
|
|
164
|
+
XStarEditor.displayName = 'XStarEditor';
|
|
165
|
+
export default XStarEditor;
|
|
166
|
+
export var useEditorRef = function useEditorRef() {
|
|
167
|
+
return useRef(null);
|
|
168
|
+
};
|
|
@@ -3,17 +3,17 @@
|
|
|
3
3
|
flex-wrap: wrap;
|
|
4
4
|
}
|
|
5
5
|
|
|
6
|
-
.
|
|
6
|
+
.container .toolbar {
|
|
7
|
+
width: 100%;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.container .editor {
|
|
7
11
|
flex: 1;
|
|
8
12
|
border-bottom-right-radius: 0;
|
|
9
13
|
}
|
|
10
14
|
|
|
11
|
-
.viewer {
|
|
15
|
+
.container .viewer {
|
|
12
16
|
flex: 1;
|
|
13
17
|
border-radius: 0;
|
|
14
18
|
border-bottom-right-radius: 0.2em;
|
|
15
19
|
}
|
|
16
|
-
|
|
17
|
-
.toolbar {
|
|
18
|
-
width: 100%;
|
|
19
|
-
}
|
|
@@ -29,3 +29,4 @@ export interface XStarMdEditorProps {
|
|
|
29
29
|
}
|
|
30
30
|
declare const XStarMdEditor: React.ForwardRefExoticComponent<XStarMdEditorProps & React.RefAttributes<XStarMdEditorHandle>>;
|
|
31
31
|
export default XStarMdEditor;
|
|
32
|
+
export declare const useMdEditorRef: () => React.RefObject<XStarMdEditorHandle>;
|
|
@@ -260,4 +260,7 @@ var XStarMdEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
260
260
|
}));
|
|
261
261
|
});
|
|
262
262
|
XStarMdEditor.displayName = 'XStarMdEditor';
|
|
263
|
-
export default XStarMdEditor;
|
|
263
|
+
export default XStarMdEditor;
|
|
264
|
+
export var useMdEditorRef = function useMdEditorRef() {
|
|
265
|
+
return useRef(null);
|
|
266
|
+
};
|
|
@@ -16,3 +16,4 @@ export interface XStarMdViewerProps {
|
|
|
16
16
|
}
|
|
17
17
|
declare const XStarMdViewer: React.ForwardRefExoticComponent<XStarMdViewerProps & React.RefAttributes<XStarMdViewerHandle>>;
|
|
18
18
|
export default XStarMdViewer;
|
|
19
|
+
export declare const useMdViewerRef: () => React.RefObject<XStarMdViewerHandle>;
|
|
@@ -30,4 +30,7 @@ var XStarMdViewer = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
30
30
|
})));
|
|
31
31
|
});
|
|
32
32
|
XStarMdViewer.displayName = 'XStarMdViewer';
|
|
33
|
-
export default XStarMdViewer;
|
|
33
|
+
export default XStarMdViewer;
|
|
34
|
+
export var useMdViewerRef = function useMdViewerRef() {
|
|
35
|
+
return useRef(null);
|
|
36
|
+
};
|
|
@@ -58,11 +58,11 @@ var FileInput = function FileInput(_ref) {
|
|
|
58
58
|
return setFile((_e$target$files = e.target.files) === null || _e$target$files === void 0 ? void 0 : _e$target$files[0]);
|
|
59
59
|
}
|
|
60
60
|
}), /*#__PURE__*/React.createElement("input", {
|
|
61
|
-
className: cx('input'
|
|
61
|
+
className: cx('input'),
|
|
62
62
|
readOnly: true,
|
|
63
63
|
value: (_file$name = file === null || file === void 0 ? void 0 : file.name) !== null && _file$name !== void 0 ? _file$name : ''
|
|
64
64
|
}), /*#__PURE__*/React.createElement("button", {
|
|
65
|
-
className: cx('button'
|
|
65
|
+
className: cx('button'),
|
|
66
66
|
type: "button"
|
|
67
67
|
}, "\u9009\u62E9\u6587\u4EF6"))) : /*#__PURE__*/React.createElement("label", {
|
|
68
68
|
className: cx('field')
|
|
@@ -2,44 +2,52 @@
|
|
|
2
2
|
margin: 0.5em 1em 1em 1em;
|
|
3
3
|
}
|
|
4
4
|
|
|
5
|
-
.tabs {
|
|
5
|
+
.container .tabs {
|
|
6
6
|
display: flex;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
.tab {
|
|
9
|
+
.container .tabs .tab {
|
|
10
10
|
padding: 0.4em 1em;
|
|
11
11
|
border-bottom: 1px solid #f5771280;
|
|
12
12
|
cursor: pointer;
|
|
13
13
|
user-select: none;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
.tab.active {
|
|
16
|
+
.container .tabs .tab.active {
|
|
17
17
|
color: #f57712;
|
|
18
18
|
border-bottom: 2px solid #f57712;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
.
|
|
22
|
-
margin: 0.8em;
|
|
21
|
+
.container .buttons {
|
|
23
22
|
display: flex;
|
|
24
|
-
flex-direction:
|
|
25
|
-
gap: 0.
|
|
26
|
-
font-size: 0.9em;
|
|
23
|
+
flex-direction: row-reverse;
|
|
24
|
+
gap: 0.4em;
|
|
27
25
|
}
|
|
28
26
|
|
|
29
|
-
.
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
27
|
+
.container .button {
|
|
28
|
+
padding: 0.4em 1em;
|
|
29
|
+
background-color: #f0f0f0;
|
|
30
|
+
border: 1px solid #d0d0d0;
|
|
31
|
+
border-radius: 0.2em;
|
|
32
|
+
cursor: pointer;
|
|
33
|
+
user-select: none;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
.
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
.container .button.primary {
|
|
37
|
+
color: #ffffff;
|
|
38
|
+
background-color: #f57712;
|
|
39
|
+
border: none;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.container .field {
|
|
43
|
+
margin: 0.8em;
|
|
44
|
+
display: flex;
|
|
45
|
+
flex-direction: column;
|
|
46
|
+
gap: 0.2em;
|
|
47
|
+
font-size: 0.9em;
|
|
40
48
|
}
|
|
41
49
|
|
|
42
|
-
.input {
|
|
50
|
+
.container .field .input {
|
|
43
51
|
width: 20em;
|
|
44
52
|
padding: 0.4em;
|
|
45
53
|
border: 1px solid #d0d0d0;
|
|
@@ -47,35 +55,27 @@
|
|
|
47
55
|
outline: none;
|
|
48
56
|
}
|
|
49
57
|
|
|
50
|
-
.input:focus {
|
|
58
|
+
.container .field .input:focus {
|
|
51
59
|
border: 1px solid #f57712;
|
|
52
60
|
}
|
|
53
61
|
|
|
54
|
-
.
|
|
55
|
-
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
.buttons {
|
|
62
|
+
.container .field .file-container {
|
|
63
|
+
position: relative;
|
|
59
64
|
display: flex;
|
|
60
|
-
|
|
61
|
-
|
|
65
|
+
align-items: center;
|
|
66
|
+
justify-content: space-between;
|
|
62
67
|
}
|
|
63
68
|
|
|
64
|
-
.
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
border-radius: 0.2em;
|
|
69
|
-
cursor: pointer;
|
|
70
|
-
user-select: none;
|
|
69
|
+
.container .field .file-container .hidden {
|
|
70
|
+
position: absolute;
|
|
71
|
+
inset: 0;
|
|
72
|
+
opacity: 0;
|
|
71
73
|
}
|
|
72
74
|
|
|
73
|
-
.
|
|
74
|
-
|
|
75
|
-
background-color: #f57712;
|
|
76
|
-
border: none;
|
|
75
|
+
.container .field .file-container .input {
|
|
76
|
+
width: 14em;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
.
|
|
79
|
+
.container .field .file-container .button {
|
|
80
80
|
padding: 0.3em 0.4em;
|
|
81
81
|
}
|
|
@@ -58,7 +58,7 @@ var Button = function Button(_ref) {
|
|
|
58
58
|
className: cx('button-container')
|
|
59
59
|
}, /*#__PURE__*/React.createElement("div", {
|
|
60
60
|
className: cx('button', {
|
|
61
|
-
|
|
61
|
+
active: tooltipOpen || popoverMount
|
|
62
62
|
}),
|
|
63
63
|
onClick: function onClick() {
|
|
64
64
|
setPopoverOpen(true);
|
|
@@ -1,8 +1,19 @@
|
|
|
1
|
-
.
|
|
1
|
+
.toolbar {
|
|
2
|
+
padding: 0.2em;
|
|
3
|
+
display: flex;
|
|
4
|
+
flex-wrap: wrap;
|
|
5
|
+
gap: 0.2em;
|
|
6
|
+
background-color: #f5771210;
|
|
7
|
+
border: 1px solid #f5771220;
|
|
8
|
+
border-top-left-radius: 0.2em;
|
|
9
|
+
border-top-right-radius: 0.2em;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.toolbar .button-container {
|
|
2
13
|
position: relative;
|
|
3
14
|
}
|
|
4
15
|
|
|
5
|
-
.button {
|
|
16
|
+
.toolbar .button-container .button {
|
|
6
17
|
width: 2em;
|
|
7
18
|
height: 2em;
|
|
8
19
|
display: flex;
|
|
@@ -14,13 +25,47 @@
|
|
|
14
25
|
user-select: none;
|
|
15
26
|
}
|
|
16
27
|
|
|
17
|
-
.button-
|
|
28
|
+
.toolbar .button-container .button.active {
|
|
18
29
|
background-color: #f8f8f8;
|
|
19
30
|
border: 1px solid #f5771280;
|
|
20
31
|
border-radius: 0.2em;
|
|
21
32
|
}
|
|
22
33
|
|
|
23
|
-
.
|
|
34
|
+
.toolbar .button-container .button .icon {
|
|
35
|
+
width: 45%;
|
|
36
|
+
height: 45%;
|
|
37
|
+
background-size: contain;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.toolbar .button-container .button .icon.code-library {
|
|
41
|
+
background-image: url(icons/code-library.svg);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.toolbar .button-container .button .icon.italic {
|
|
45
|
+
background-image: url(icons/italic.svg);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.toolbar .button-container .button .icon.bold {
|
|
49
|
+
background-image: url(icons/bold.svg);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.toolbar .button-container .button .icon.code {
|
|
53
|
+
background-image: url(icons/code.svg);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.toolbar .button-container .button .icon.link {
|
|
57
|
+
background-image: url(icons/link.svg);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.toolbar .button-container .button .icon.image {
|
|
61
|
+
background-image: url(icons/image.svg);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.toolbar .button-container .button .icon.strikethrough {
|
|
65
|
+
background-image: url(icons/strikethrough.svg);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.toolbar .button-container .button .tooltip {
|
|
24
69
|
position: absolute;
|
|
25
70
|
top: 3em;
|
|
26
71
|
width: max-content;
|
|
@@ -32,7 +77,7 @@
|
|
|
32
77
|
z-index: 2;
|
|
33
78
|
}
|
|
34
79
|
|
|
35
|
-
.tooltip::before {
|
|
80
|
+
.toolbar .button-container .button .tooltip::before {
|
|
36
81
|
content: '';
|
|
37
82
|
position: absolute;
|
|
38
83
|
top: -0.3em;
|
|
@@ -43,7 +88,7 @@
|
|
|
43
88
|
transform: rotate(45deg);
|
|
44
89
|
}
|
|
45
90
|
|
|
46
|
-
.popover {
|
|
91
|
+
.toolbar .button-container .popover {
|
|
47
92
|
position: absolute;
|
|
48
93
|
width: max-content;
|
|
49
94
|
background-color: #f8f8f8;
|
|
@@ -54,63 +99,17 @@
|
|
|
54
99
|
z-index: 1;
|
|
55
100
|
}
|
|
56
101
|
|
|
57
|
-
.option {
|
|
102
|
+
.toolbar .button-container .popover .option {
|
|
58
103
|
padding: 4px 8px;
|
|
59
104
|
cursor: pointer;
|
|
60
105
|
user-select: none;
|
|
61
106
|
}
|
|
62
107
|
|
|
63
|
-
.option:hover {
|
|
108
|
+
.toolbar .button-container .popover .option:hover {
|
|
64
109
|
background-color: #f0f0f0;
|
|
65
110
|
}
|
|
66
111
|
|
|
67
|
-
.
|
|
68
|
-
width: 45%;
|
|
69
|
-
height: 45%;
|
|
70
|
-
background-size: contain;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
.icon.code-library {
|
|
74
|
-
background-image: url(icons/code-library.svg);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
.icon.italic {
|
|
78
|
-
background-image: url(icons/italic.svg);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
.icon.bold {
|
|
82
|
-
background-image: url(icons/bold.svg);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
.icon.code {
|
|
86
|
-
background-image: url(icons/code.svg);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
.icon.link {
|
|
90
|
-
background-image: url(icons/link.svg);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
.icon.image {
|
|
94
|
-
background-image: url(icons/image.svg);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
.icon.strikethrough {
|
|
98
|
-
background-image: url(icons/strikethrough.svg);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
.toolbar {
|
|
102
|
-
margin: 0 -1px;
|
|
103
|
-
padding: 0.2em;
|
|
104
|
-
display: flex;
|
|
105
|
-
flex-wrap: wrap;
|
|
106
|
-
gap: 0.2em;
|
|
107
|
-
background-color: #f5771210;
|
|
108
|
-
border: 1px solid #f5771220;
|
|
109
|
-
border-top-left-radius: 0.2em;
|
|
110
|
-
border-top-right-radius: 0.2em;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
.divider {
|
|
112
|
+
.toolbar .divider {
|
|
114
113
|
margin: 0.4em;
|
|
115
114
|
border: 1px solid #f5771280;
|
|
116
115
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export { default as XStarEditor } from './XStarEditor';
|
|
2
|
-
export type {
|
|
3
|
-
export { default as XStarMdEditor } from './XStarMdEditor';
|
|
1
|
+
export { default as XStarEditor, useEditorRef } from './XStarEditor';
|
|
2
|
+
export type { XStarEditorHandle, XStarEditorProps } from './XStarEditor';
|
|
3
|
+
export { default as XStarMdEditor, useMdEditorRef } from './XStarMdEditor';
|
|
4
4
|
export type { XStarMdEditorHandle, XStarMdEditorPlugin, XStarMdEditorProps, } from './XStarMdEditor';
|
|
5
|
-
export { default as XStarMdViewer } from './XStarMdViewer';
|
|
5
|
+
export { default as XStarMdViewer, useMdViewerRef } from './XStarMdViewer';
|
|
6
6
|
export type { XStarMdViewerHandle, XStarMdViewerPlugin, XStarMdViewerProps, } from './XStarMdViewer';
|
|
7
7
|
export { createSelection, getRange } from './utils/container';
|
|
8
8
|
export { deleteHandler, insertHandler, redoHandler, selectHandler, setHandler, toggleHandler, undoHandler, } from './utils/handler';
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { default as XStarEditor } from "./XStarEditor";
|
|
2
|
-
export { default as XStarMdEditor } from "./XStarMdEditor";
|
|
3
|
-
export { default as XStarMdViewer } from "./XStarMdViewer";
|
|
1
|
+
export { default as XStarEditor, useEditorRef } from "./XStarEditor";
|
|
2
|
+
export { default as XStarMdEditor, useMdEditorRef } from "./XStarMdEditor";
|
|
3
|
+
export { default as XStarMdViewer, useMdViewerRef } from "./XStarMdViewer";
|
|
4
4
|
export { createSelection, getRange } from "./utils/container";
|
|
5
5
|
export { deleteHandler, insertHandler, redoHandler, selectHandler, setHandler, toggleHandler, undoHandler } from "./utils/handler";
|
package/dist/styles/prism.css
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
white-space: pre;
|
|
16
16
|
word-spacing: normal;
|
|
17
17
|
word-break: normal;
|
|
18
|
-
font-size:
|
|
18
|
+
font-size: 1em;
|
|
19
19
|
line-height: 1.2em;
|
|
20
20
|
|
|
21
21
|
-moz-tab-size: 4;
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
.x-star-md-viewer.x-star-md-viewer pre > code {
|
|
32
32
|
margin: 0;
|
|
33
33
|
color: #393a34;
|
|
34
|
-
font-size: 1em;
|
|
34
|
+
font-size: 1.1em;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
.x-star-md-viewer.x-star-md-viewer pre::-moz-selection,
|
package/dist/utils/container.js
CHANGED
|
@@ -238,7 +238,7 @@ export var useContainer = function useContainer() {
|
|
|
238
238
|
if (node.nodeType === Node.TEXT_NODE) {
|
|
239
239
|
if (node.nodeValue) {
|
|
240
240
|
offset += targetOffset;
|
|
241
|
-
if (node.nodeValue
|
|
241
|
+
if (targetOffset === node.nodeValue.length && node.nodeValue.endsWith("\u200B")) {
|
|
242
242
|
offset--;
|
|
243
243
|
}
|
|
244
244
|
}
|
|
@@ -298,7 +298,7 @@ export var useContainer = function useContainer() {
|
|
|
298
298
|
var traverse = function traverse(node) {
|
|
299
299
|
if (node.nodeType === Node.TEXT_NODE) {
|
|
300
300
|
if (node.nodeValue) {
|
|
301
|
-
if (offset < node.nodeValue.length) {
|
|
301
|
+
if (offset < node.nodeValue.length || offset === node.nodeValue.length && !node.nodeValue.endsWith("\u200B")) {
|
|
302
302
|
return node;
|
|
303
303
|
}
|
|
304
304
|
offset -= node.nodeValue.length;
|
package/dist/utils/history.d.ts
CHANGED
|
@@ -54,6 +54,6 @@ export interface SelectAction {
|
|
|
54
54
|
export declare const useHistory: (initialSourceCode: string) => {
|
|
55
55
|
sourceCode: string;
|
|
56
56
|
selection: ContainerSelection;
|
|
57
|
-
dispatch: import("react").Dispatch<
|
|
57
|
+
dispatch: import("react").Dispatch<ToggleAction | UndoAction | RedoAction | SelectAction | InsertAction | DeleteAction | SetAction>;
|
|
58
58
|
};
|
|
59
59
|
export {};
|
package/dist/utils/markdown.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
var _defaultSchema$tagNam, _defaultSchema$attrib, _defaultSchema$attrib2, _defaultSchema$attrib3, _defaultSchema$attrib4, _defaultSchema$attrib5, _defaultSchema$attrib6, _defaultSchema$attrib7, _defaultSchema$attrib8;
|
|
2
2
|
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
|
|
3
|
+
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
|
|
3
4
|
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
4
5
|
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
5
6
|
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
@@ -53,7 +54,25 @@ var processor = unified().use(remarkParse).use(remarkBreaks).use(remarkGfm).use(
|
|
|
53
54
|
}
|
|
54
55
|
}).use(rehypePrism, {
|
|
55
56
|
ignoreMissing: true
|
|
56
|
-
}).use(rehypeKatex).use(rehypeRaw).use(rehypeSanitize, schema).
|
|
57
|
+
}).use(rehypeKatex).use(rehypeRaw).use(rehypeSanitize, schema).use(function () {
|
|
58
|
+
return function (root) {
|
|
59
|
+
var _iterator = _createForOfIteratorHelper(root.children),
|
|
60
|
+
_step;
|
|
61
|
+
try {
|
|
62
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
63
|
+
var node = _step.value;
|
|
64
|
+
if ('properties' in node && node.properties) {
|
|
65
|
+
var _node$position;
|
|
66
|
+
node.properties.line = (_node$position = node.position) === null || _node$position === void 0 ? void 0 : _node$position.start.line;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
} catch (err) {
|
|
70
|
+
_iterator.e(err);
|
|
71
|
+
} finally {
|
|
72
|
+
_iterator.f();
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
}).freeze();
|
|
57
76
|
|
|
58
77
|
/**
|
|
59
78
|
* Mdast 节点
|
|
@@ -211,51 +230,60 @@ export var editorRender = function editorRender(sourceCode) {
|
|
|
211
230
|
* @param parentEndOffset 父节点终点偏移量
|
|
212
231
|
*/
|
|
213
232
|
var getChildren = function getChildren(nodes, parentEndOffset) {
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
233
|
+
var _iterator2 = _createForOfIteratorHelper(nodes),
|
|
234
|
+
_step2;
|
|
235
|
+
try {
|
|
236
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
237
|
+
var _node$position2, _node$position3;
|
|
238
|
+
var node = _step2.value;
|
|
239
|
+
var startOffset = (_node$position2 = node.position) === null || _node$position2 === void 0 ? void 0 : _node$position2.start.offset;
|
|
240
|
+
var endOffset = (_node$position3 = node.position) === null || _node$position3 === void 0 ? void 0 : _node$position3.end.offset;
|
|
241
|
+
if (startOffset === undefined || endOffset === undefined) {
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
// 由于 unified 的问题,起点偏移量可能小于扫描偏移量,应修正
|
|
245
|
+
if (startOffset < scanOffset) {
|
|
246
|
+
startOffset = scanOffset;
|
|
247
|
+
}
|
|
248
|
+
// 如果起点偏移量大于等于终点偏移量,则不用添加任何文本
|
|
249
|
+
if (startOffset >= endOffset) {
|
|
250
|
+
continue;
|
|
251
|
+
}
|
|
230
252
|
|
|
231
|
-
|
|
232
|
-
|
|
253
|
+
// 添加扫描偏移量与起点偏移量间的分隔文本
|
|
254
|
+
addText(sourceCode.slice(scanOffset, startOffset), true);
|
|
233
255
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
256
|
+
// 为 Mdast 节点创建 DOM 元素
|
|
257
|
+
stack.push({
|
|
258
|
+
node: node,
|
|
259
|
+
el: document.createElement(stack.length ? 'span' : 'div'),
|
|
260
|
+
first: true
|
|
261
|
+
});
|
|
262
|
+
if ('children' in node) {
|
|
263
|
+
getChildren(node.children, endOffset);
|
|
264
|
+
} else {
|
|
265
|
+
addText(sourceCode.slice(scanOffset, endOffset));
|
|
266
|
+
}
|
|
267
|
+
if (stack.length > 1) {
|
|
268
|
+
pushElement(stack.length - 1, true);
|
|
269
|
+
} else {
|
|
270
|
+
var _node$position4;
|
|
271
|
+
// 如果栈大小为 1,说明为块级元素终点
|
|
272
|
+
stack[0].el.append("\u200B");
|
|
273
|
+
pushElement(0, true);
|
|
274
|
+
block.setAttribute('line', "".concat((_node$position4 = node.position) === null || _node$position4 === void 0 ? void 0 : _node$position4.start.line));
|
|
275
|
+
pushBlock();
|
|
276
|
+
scanOffset++;
|
|
277
|
+
}
|
|
278
|
+
stack.pop();
|
|
254
279
|
}
|
|
255
|
-
stack.pop();
|
|
256
|
-
}
|
|
257
280
|
|
|
258
|
-
|
|
281
|
+
// 添加扫描偏移量与父节点终点偏移量间的分隔文本
|
|
282
|
+
} catch (err) {
|
|
283
|
+
_iterator2.e(err);
|
|
284
|
+
} finally {
|
|
285
|
+
_iterator2.f();
|
|
286
|
+
}
|
|
259
287
|
addText(sourceCode.slice(scanOffset, parentEndOffset), true);
|
|
260
288
|
};
|
|
261
289
|
getChildren(processor.parse(sourceCode).children, sourceCode.length);
|