x-star-editor 0.0.8 → 0.1.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/Fade.d.ts +9 -0
- package/dist/components/Fade.js +38 -0
- package/dist/components/FileInput.js +11 -8
- package/dist/components/Toolbar.d.ts +9 -5
- package/dist/components/Toolbar.js +167 -100
- package/dist/index.d.ts +7 -7
- package/dist/index.js +4 -4
- package/dist/locales/en_US.d.ts +27 -0
- package/dist/locales/en_US.js +26 -0
- package/dist/locales/index.d.ts +115 -0
- package/dist/locales/index.js +41 -0
- package/dist/locales/zh_CN.d.ts +27 -0
- package/dist/locales/zh_CN.js +26 -0
- package/dist/styles/icons/blockquote.svg +18 -0
- package/dist/styles/icons/code.svg +18 -1
- package/dist/styles/icons/delete.svg +18 -0
- package/dist/styles/icons/emphasis.svg +18 -0
- package/dist/styles/icons/heading.svg +16 -0
- package/dist/styles/icons/image.svg +18 -1
- package/dist/styles/icons/inline-code.svg +19 -0
- package/dist/styles/icons/inline-math.svg +20 -0
- package/dist/styles/icons/link.svg +18 -1
- package/dist/styles/icons/math.svg +17 -0
- package/dist/styles/icons/redo.svg +18 -0
- package/dist/styles/icons/strong.svg +18 -0
- package/dist/styles/icons/thematic-break.svg +18 -0
- package/dist/styles/icons/undo.svg +18 -0
- package/dist/styles/index.css +358 -396
- package/dist/utils/container.js +23 -1
- package/dist/utils/global.d.ts +1 -1
- package/dist/utils/global.js +1 -1
- package/dist/utils/history.d.ts +20 -4
- package/dist/utils/history.js +89 -72
- package/dist/utils/markdown.d.ts +7 -0
- package/dist/utils/markdown.js +60 -57
- package/dist/{XStarEditor → x-star-editor}/index.d.ts +22 -3
- package/dist/{XStarEditor → x-star-editor}/index.js +30 -20
- package/dist/{XStarMdEditor → x-star-md-editor}/index.d.ts +31 -3
- package/dist/{XStarMdEditor → x-star-md-editor}/index.js +23 -14
- package/dist/{XStarMdViewer → x-star-md-viewer}/index.d.ts +12 -0
- package/dist/{XStarMdViewer → x-star-md-viewer}/index.js +3 -1
- package/package.json +6 -4
- package/dist/styles/icons/bold.svg +0 -1
- package/dist/styles/icons/code-library.svg +0 -1
- package/dist/styles/icons/italic.svg +0 -1
- package/dist/styles/icons/strikethrough.svg +0 -1
package/dist/utils/container.js
CHANGED
|
@@ -49,6 +49,16 @@ export var useContainer = function useContainer() {
|
|
|
49
49
|
*/
|
|
50
50
|
var ref = useRef(null);
|
|
51
51
|
|
|
52
|
+
/**
|
|
53
|
+
* 是否在遍历时忽略节点及其子节点
|
|
54
|
+
*
|
|
55
|
+
* @param node 节点
|
|
56
|
+
* @returns 是否忽略
|
|
57
|
+
*/
|
|
58
|
+
var isIgnore = function isIgnore(node) {
|
|
59
|
+
return node instanceof HTMLElement && node.dataset.ignore !== undefined;
|
|
60
|
+
};
|
|
61
|
+
|
|
52
62
|
/**
|
|
53
63
|
* 将 DOM 树规范化
|
|
54
64
|
*
|
|
@@ -59,6 +69,9 @@ export var useContainer = function useContainer() {
|
|
|
59
69
|
return;
|
|
60
70
|
}
|
|
61
71
|
var traverse = function traverse(node, depth) {
|
|
72
|
+
if (isIgnore(node)) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
62
75
|
if (depth === 2) {
|
|
63
76
|
var _node$lastChild;
|
|
64
77
|
// 检查行节点的末尾
|
|
@@ -102,6 +115,9 @@ export var useContainer = function useContainer() {
|
|
|
102
115
|
}
|
|
103
116
|
var text = '';
|
|
104
117
|
var traverse = function traverse(node) {
|
|
118
|
+
if (isIgnore(node)) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
105
121
|
if (node.nodeType === Node.TEXT_NODE) {
|
|
106
122
|
if (node.nodeValue) {
|
|
107
123
|
text += node.nodeValue;
|
|
@@ -152,7 +168,7 @@ export var useContainer = function useContainer() {
|
|
|
152
168
|
}
|
|
153
169
|
} else {
|
|
154
170
|
// 节点名称相同,更新属性和子节点
|
|
155
|
-
if (newChild instanceof
|
|
171
|
+
if (newChild instanceof HTMLElement && oldChild instanceof HTMLElement) {
|
|
156
172
|
var _iterator = _createForOfIteratorHelper(oldChild.getAttributeNames()),
|
|
157
173
|
_step;
|
|
158
174
|
try {
|
|
@@ -234,6 +250,9 @@ export var useContainer = function useContainer() {
|
|
|
234
250
|
}
|
|
235
251
|
var offset = 0;
|
|
236
252
|
var traverse = function traverse(node) {
|
|
253
|
+
if (isIgnore(node)) {
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
237
256
|
if (node === targetNode) {
|
|
238
257
|
if (node.nodeType === Node.TEXT_NODE) {
|
|
239
258
|
if (node.nodeValue) {
|
|
@@ -296,6 +315,9 @@ export var useContainer = function useContainer() {
|
|
|
296
315
|
}
|
|
297
316
|
var offset = targetOffset;
|
|
298
317
|
var traverse = function traverse(node) {
|
|
318
|
+
if (isIgnore(node)) {
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
299
321
|
if (node.nodeType === Node.TEXT_NODE) {
|
|
300
322
|
if (node.nodeValue) {
|
|
301
323
|
if (offset < node.nodeValue.length || offset === node.nodeValue.length && !node.nodeValue.endsWith("\u200B")) {
|
package/dist/utils/global.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const prefix = "x-star-";
|
|
1
|
+
export declare const prefix = "x-star-editor-";
|
package/dist/utils/global.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export var prefix = 'x-star-';
|
|
1
|
+
export var prefix = 'x-star-editor-';
|
package/dist/utils/history.d.ts
CHANGED
|
@@ -25,12 +25,15 @@ export interface DeleteAction {
|
|
|
25
25
|
export interface ToggleAction {
|
|
26
26
|
type: 'toggle';
|
|
27
27
|
payload: {
|
|
28
|
+
type: 'blockquote' | 'delete' | 'emphasis' | 'inlineCode' | 'inlineMath' | 'math' | 'strong' | 'thematicBreak';
|
|
29
|
+
} | {
|
|
30
|
+
type: 'code';
|
|
31
|
+
language: string;
|
|
32
|
+
} | {
|
|
28
33
|
type: 'heading';
|
|
29
34
|
depth: 1 | 2 | 3 | 4 | 5 | 6;
|
|
30
35
|
} | {
|
|
31
|
-
type: '
|
|
32
|
-
} | {
|
|
33
|
-
type: 'link' | 'image';
|
|
36
|
+
type: 'image' | 'link';
|
|
34
37
|
url: string;
|
|
35
38
|
description: string;
|
|
36
39
|
};
|
|
@@ -41,6 +44,17 @@ export interface SetAction {
|
|
|
41
44
|
payload: State;
|
|
42
45
|
selection: ContainerSelection;
|
|
43
46
|
}
|
|
47
|
+
type StateAction = InsertAction | DeleteAction | ToggleAction | SetAction;
|
|
48
|
+
/**
|
|
49
|
+
* 编辑器历史
|
|
50
|
+
*/
|
|
51
|
+
interface History {
|
|
52
|
+
states: (State & {
|
|
53
|
+
action: StateAction;
|
|
54
|
+
})[];
|
|
55
|
+
index: number;
|
|
56
|
+
selection: ContainerSelection;
|
|
57
|
+
}
|
|
44
58
|
export interface UndoAction {
|
|
45
59
|
type: 'undo';
|
|
46
60
|
}
|
|
@@ -51,9 +65,11 @@ export interface SelectAction {
|
|
|
51
65
|
type: 'select';
|
|
52
66
|
selection: ContainerSelection;
|
|
53
67
|
}
|
|
68
|
+
type HistoryAction = UndoAction | RedoAction | SelectAction;
|
|
54
69
|
export declare const useHistory: (initialSourceCode: string) => {
|
|
70
|
+
history: History;
|
|
55
71
|
sourceCode: string;
|
|
56
72
|
selection: ContainerSelection;
|
|
57
|
-
dispatch: import("react").Dispatch<
|
|
73
|
+
dispatch: import("react").Dispatch<StateAction | HistoryAction>;
|
|
58
74
|
};
|
|
59
75
|
export {};
|
package/dist/utils/history.js
CHANGED
|
@@ -84,26 +84,22 @@ var stateReducer = function stateReducer(_ref, action) {
|
|
|
84
84
|
var lineBefore = sourceCode.slice(0, lineStartOffset);
|
|
85
85
|
var lineAfter = sourceCode.slice(lineEndOffset);
|
|
86
86
|
switch (action.payload.type) {
|
|
87
|
-
case '
|
|
87
|
+
case 'blockquote':
|
|
88
88
|
{
|
|
89
|
-
var depth = action.payload.depth;
|
|
90
89
|
var lines = sourceCode.slice(lineStartOffset, lineEndOffset).split('\n');
|
|
91
90
|
var values = lines.map(function (line) {
|
|
92
|
-
return
|
|
93
|
-
return new RegExp("^ {0,3}#{".concat(value, "} +")).test(line);
|
|
94
|
-
});
|
|
91
|
+
return /^ {0,3}> */.test(line);
|
|
95
92
|
});
|
|
96
93
|
for (var i = 0; i < values.length; i++) {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
lines[i] = lines[i].replace(new RegExp("^ {0,3}#{".concat(value, "} +")), '');
|
|
94
|
+
if (values[i]) {
|
|
95
|
+
lines[i] = lines[i].replace(/^ {0,3}> */, '');
|
|
100
96
|
}
|
|
101
97
|
}
|
|
102
98
|
if (values.some(function (value) {
|
|
103
|
-
return value
|
|
99
|
+
return !value;
|
|
104
100
|
})) {
|
|
105
101
|
for (var _i = 0; _i < lines.length; _i++) {
|
|
106
|
-
lines[_i] = "
|
|
102
|
+
lines[_i] = "> ".concat(lines[_i]);
|
|
107
103
|
}
|
|
108
104
|
}
|
|
109
105
|
var _text = lines.join('\n');
|
|
@@ -112,83 +108,92 @@ var stateReducer = function stateReducer(_ref, action) {
|
|
|
112
108
|
selection: createSelection(lineStartOffset + _text.length)
|
|
113
109
|
};
|
|
114
110
|
}
|
|
115
|
-
case '
|
|
111
|
+
case 'code':
|
|
116
112
|
{
|
|
113
|
+
var language = action.payload.language;
|
|
117
114
|
return {
|
|
118
|
-
sourceCode: "".concat(sourceCode.slice(0, lineEndOffset), "\n
|
|
119
|
-
selection: createSelection(lineEndOffset +
|
|
115
|
+
sourceCode: "".concat(sourceCode.slice(0, lineEndOffset), "\n```").concat(language, " showLineNumbers\n\n```\n").concat(lineAfter),
|
|
116
|
+
selection: createSelection(lineEndOffset + language.length + 21)
|
|
120
117
|
};
|
|
121
118
|
}
|
|
122
|
-
case '
|
|
119
|
+
case 'delete':
|
|
120
|
+
case 'emphasis':
|
|
121
|
+
case 'inlineCode':
|
|
122
|
+
case 'inlineMath':
|
|
123
|
+
case 'strong':
|
|
124
|
+
{
|
|
125
|
+
var type = action.payload.type;
|
|
126
|
+
var delimiters = type === 'emphasis' ? ['*', '_'] : type === 'strong' ? ['**', '__'] : type === 'inlineCode' ? ['`'] : type === 'delete' ? ['~~'] : ['$'];
|
|
127
|
+
var _text2 = sourceCode.slice(startOffset, endOffset);
|
|
128
|
+
for (var _i2 = 0, _delimiters = delimiters; _i2 < _delimiters.length; _i2++) {
|
|
129
|
+
var _delimiter = _delimiters[_i2];
|
|
130
|
+
if (before.endsWith(_delimiter) && after.startsWith(_delimiter)) {
|
|
131
|
+
// 删除分隔文本
|
|
132
|
+
return {
|
|
133
|
+
sourceCode: "".concat(before.slice(0, before.length - _delimiter.length)).concat(_text2).concat(after.slice(_delimiter.length)),
|
|
134
|
+
selection: createSelection(anchorOffset - _delimiter.length, focusOffset - _delimiter.length)
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
var delimiter = delimiters[0];
|
|
139
|
+
// 插入分隔文本
|
|
140
|
+
return {
|
|
141
|
+
sourceCode: "".concat(before).concat(delimiter).concat(_text2).concat(delimiter).concat(after),
|
|
142
|
+
selection: createSelection(anchorOffset + delimiter.length, focusOffset + delimiter.length)
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
case 'heading':
|
|
123
146
|
{
|
|
147
|
+
var depth = action.payload.depth;
|
|
124
148
|
var _lines = sourceCode.slice(lineStartOffset, lineEndOffset).split('\n');
|
|
125
149
|
var _values = _lines.map(function (line) {
|
|
126
|
-
return
|
|
150
|
+
return [1, 2, 3, 4, 5, 6].find(function (value) {
|
|
151
|
+
return new RegExp("^ {0,3}#{".concat(value, "} +")).test(line);
|
|
152
|
+
});
|
|
127
153
|
});
|
|
128
|
-
for (var
|
|
129
|
-
|
|
130
|
-
|
|
154
|
+
for (var _i3 = 0; _i3 < _values.length; _i3++) {
|
|
155
|
+
var value = _values[_i3];
|
|
156
|
+
if (value) {
|
|
157
|
+
_lines[_i3] = _lines[_i3].replace(new RegExp("^ {0,3}#{".concat(value, "} +")), '');
|
|
131
158
|
}
|
|
132
159
|
}
|
|
133
160
|
if (_values.some(function (value) {
|
|
134
|
-
return
|
|
161
|
+
return value !== depth;
|
|
135
162
|
})) {
|
|
136
|
-
for (var
|
|
137
|
-
_lines[
|
|
163
|
+
for (var _i4 = 0; _i4 < _lines.length; _i4++) {
|
|
164
|
+
_lines[_i4] = "".concat('#'.repeat(depth), " ").concat(_lines[_i4]);
|
|
138
165
|
}
|
|
139
166
|
}
|
|
140
|
-
var
|
|
167
|
+
var _text3 = _lines.join('\n');
|
|
141
168
|
return {
|
|
142
|
-
sourceCode: "".concat(lineBefore).concat(
|
|
143
|
-
selection: createSelection(lineStartOffset +
|
|
169
|
+
sourceCode: "".concat(lineBefore).concat(_text3).concat(lineAfter),
|
|
170
|
+
selection: createSelection(lineStartOffset + _text3.length)
|
|
144
171
|
};
|
|
145
172
|
}
|
|
146
|
-
case '
|
|
147
|
-
case '
|
|
173
|
+
case 'image':
|
|
174
|
+
case 'link':
|
|
148
175
|
{
|
|
149
|
-
var
|
|
150
|
-
|
|
176
|
+
var _action$payload2 = action.payload,
|
|
177
|
+
_type = _action$payload2.type,
|
|
178
|
+
url = _action$payload2.url,
|
|
179
|
+
description = _action$payload2.description;
|
|
151
180
|
return {
|
|
152
|
-
sourceCode: "".concat(
|
|
153
|
-
selection: createSelection(
|
|
181
|
+
sourceCode: "".concat(before).concat(_type === 'link' ? '' : '!', "[").concat(description, "](").concat(url, ")").concat(after),
|
|
182
|
+
selection: createSelection(startOffset + url.length + description.length + 4 + (_type === 'link' ? 0 : 1))
|
|
154
183
|
};
|
|
155
184
|
}
|
|
156
|
-
case '
|
|
157
|
-
case 'strong':
|
|
158
|
-
case 'inlineCode':
|
|
159
|
-
case 'delete':
|
|
160
|
-
case 'inlineMath':
|
|
185
|
+
case 'math':
|
|
161
186
|
{
|
|
162
|
-
var _type = action.payload.type;
|
|
163
|
-
var delimiters = _type === 'emphasis' ? ['*', '_'] : _type === 'strong' ? ['**', '__'] : _type === 'inlineCode' ? ['`'] : _type === 'delete' ? ['~~'] : ['$'];
|
|
164
|
-
var _text3 = sourceCode.slice(startOffset, endOffset);
|
|
165
|
-
for (var _i4 = 0, _delimiters = delimiters; _i4 < _delimiters.length; _i4++) {
|
|
166
|
-
var _delimiter = _delimiters[_i4];
|
|
167
|
-
if (before.endsWith(_delimiter) && after.startsWith(_delimiter)) {
|
|
168
|
-
// 删除分隔文本
|
|
169
|
-
return {
|
|
170
|
-
sourceCode: "".concat(before.slice(0, before.length - _delimiter.length)).concat(_text3).concat(after.slice(_delimiter.length)),
|
|
171
|
-
selection: createSelection(anchorOffset - _delimiter.length, focusOffset - _delimiter.length)
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
var _delimiter2 = delimiters[0];
|
|
176
|
-
// 插入分隔文本
|
|
177
187
|
return {
|
|
178
|
-
sourceCode: "".concat(
|
|
179
|
-
selection: createSelection(
|
|
188
|
+
sourceCode: "".concat(sourceCode.slice(0, lineEndOffset), "\n$$\n\n$$\n").concat(lineAfter),
|
|
189
|
+
selection: createSelection(lineEndOffset + 4)
|
|
180
190
|
};
|
|
181
191
|
}
|
|
182
|
-
case '
|
|
183
|
-
case 'image':
|
|
192
|
+
case 'thematicBreak':
|
|
184
193
|
{
|
|
185
|
-
var _action$payload2 = action.payload,
|
|
186
|
-
_type2 = _action$payload2.type,
|
|
187
|
-
url = _action$payload2.url,
|
|
188
|
-
description = _action$payload2.description;
|
|
189
194
|
return {
|
|
190
|
-
sourceCode: "".concat(
|
|
191
|
-
selection: createSelection(
|
|
195
|
+
sourceCode: "".concat(sourceCode.slice(0, lineEndOffset), "\n***\n").concat(lineAfter),
|
|
196
|
+
selection: createSelection(lineEndOffset + 5)
|
|
192
197
|
};
|
|
193
198
|
}
|
|
194
199
|
default:
|
|
@@ -237,7 +242,7 @@ var historyReducer = function historyReducer(_ref2, action) {
|
|
|
237
242
|
return {
|
|
238
243
|
states: states,
|
|
239
244
|
index: index - 1,
|
|
240
|
-
selection: states[index].
|
|
245
|
+
selection: states[index].action.selection
|
|
241
246
|
};
|
|
242
247
|
}
|
|
243
248
|
case 'redo':
|
|
@@ -275,29 +280,41 @@ var historyReducer = function historyReducer(_ref2, action) {
|
|
|
275
280
|
};
|
|
276
281
|
}
|
|
277
282
|
return {
|
|
278
|
-
states: [].concat(_toConsumableArray(states.slice(index <
|
|
279
|
-
|
|
283
|
+
states: [].concat(_toConsumableArray(states.slice(index < 100 ? 0 : index - 99, index + 1)), [_objectSpread(_objectSpread({}, state), {}, {
|
|
284
|
+
action: action
|
|
280
285
|
})]),
|
|
281
|
-
index: index <
|
|
286
|
+
index: index < 100 ? index + 1 : 100,
|
|
282
287
|
selection: state.selection
|
|
283
288
|
};
|
|
284
289
|
}
|
|
285
290
|
}
|
|
286
291
|
};
|
|
287
292
|
export var useHistory = function useHistory(initialSourceCode) {
|
|
288
|
-
var _useReducer = useReducer(historyReducer, {
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
293
|
+
var _useReducer = useReducer(historyReducer, initialSourceCode, function (text) {
|
|
294
|
+
var action = {
|
|
295
|
+
type: 'insert',
|
|
296
|
+
payload: {
|
|
297
|
+
text: text
|
|
298
|
+
},
|
|
299
|
+
selection: createSelection(0)
|
|
300
|
+
};
|
|
301
|
+
var state = stateReducer({
|
|
302
|
+
sourceCode: '',
|
|
303
|
+
selection: createSelection(0)
|
|
304
|
+
}, action);
|
|
305
|
+
return {
|
|
306
|
+
states: [_objectSpread(_objectSpread({}, state), {}, {
|
|
307
|
+
action: action
|
|
308
|
+
})],
|
|
309
|
+
index: 0,
|
|
310
|
+
selection: state.selection
|
|
311
|
+
};
|
|
296
312
|
}),
|
|
297
313
|
_useReducer2 = _slicedToArray(_useReducer, 2),
|
|
298
314
|
history = _useReducer2[0],
|
|
299
315
|
dispatch = _useReducer2[1];
|
|
300
316
|
return {
|
|
317
|
+
history: history,
|
|
301
318
|
sourceCode: history.states[history.index].sourceCode,
|
|
302
319
|
selection: history.selection,
|
|
303
320
|
dispatch: dispatch
|
package/dist/utils/markdown.d.ts
CHANGED
|
@@ -56,4 +56,11 @@ export declare const toHTML: (sourceCode: string) => string;
|
|
|
56
56
|
* @returns Markdown 文本
|
|
57
57
|
*/
|
|
58
58
|
export declare const toMarkdown: (sourceCode: string) => string;
|
|
59
|
+
/**
|
|
60
|
+
* 将 Markdown 文本转成纯文本
|
|
61
|
+
*
|
|
62
|
+
* @param sourceCode Markdown 文本
|
|
63
|
+
* @returns 纯文本
|
|
64
|
+
*/
|
|
65
|
+
export declare const toText: (sourceCode: string) => string;
|
|
59
66
|
export {};
|
package/dist/utils/markdown.js
CHANGED
|
@@ -25,19 +25,23 @@ import remarkMath from 'remark-math';
|
|
|
25
25
|
import remarkParse from 'remark-parse';
|
|
26
26
|
import remarkRehype from 'remark-rehype';
|
|
27
27
|
import remarkStringify from 'remark-stringify';
|
|
28
|
+
import strip from 'strip-markdown';
|
|
28
29
|
import { unified } from 'unified';
|
|
29
30
|
import { prefix } from "./global";
|
|
30
31
|
export var getDefaultSchema = function getDefaultSchema() {
|
|
31
|
-
var _defaultSchema$
|
|
32
|
+
var _defaultSchema$attrib, _defaultSchema$attrib2, _defaultSchema$attrib3, _defaultSchema$attrib4, _defaultSchema$attrib5, _defaultSchema$attrib6, _defaultSchema$attrib7, _defaultSchema$attrib8, _defaultSchema$protoc, _defaultSchema$protoc2, _defaultSchema$tagNam;
|
|
32
33
|
return _objectSpread(_objectSpread({}, defaultSchema), {}, {
|
|
33
|
-
tagNames: [].concat(_toConsumableArray((_defaultSchema$tagNam = defaultSchema.tagNames) !== null && _defaultSchema$tagNam !== void 0 ? _defaultSchema$tagNam : []), ['custom']),
|
|
34
34
|
attributes: _objectSpread(_objectSpread({}, defaultSchema.attributes), {}, {
|
|
35
35
|
pre: [].concat(_toConsumableArray((_defaultSchema$attrib = (_defaultSchema$attrib2 = defaultSchema.attributes) === null || _defaultSchema$attrib2 === void 0 ? void 0 : _defaultSchema$attrib2.pre) !== null && _defaultSchema$attrib !== void 0 ? _defaultSchema$attrib : []), ['className', 'style']),
|
|
36
36
|
code: [].concat(_toConsumableArray((_defaultSchema$attrib3 = (_defaultSchema$attrib4 = defaultSchema.attributes) === null || _defaultSchema$attrib4 === void 0 ? void 0 : _defaultSchema$attrib4.code) !== null && _defaultSchema$attrib3 !== void 0 ? _defaultSchema$attrib3 : []), ['className', 'style']),
|
|
37
37
|
div: [].concat(_toConsumableArray((_defaultSchema$attrib5 = (_defaultSchema$attrib6 = defaultSchema.attributes) === null || _defaultSchema$attrib6 === void 0 ? void 0 : _defaultSchema$attrib6.div) !== null && _defaultSchema$attrib5 !== void 0 ? _defaultSchema$attrib5 : []), ['className', 'style']),
|
|
38
38
|
span: [].concat(_toConsumableArray((_defaultSchema$attrib7 = (_defaultSchema$attrib8 = defaultSchema.attributes) === null || _defaultSchema$attrib8 === void 0 ? void 0 : _defaultSchema$attrib8.span) !== null && _defaultSchema$attrib7 !== void 0 ? _defaultSchema$attrib7 : []), ['className', 'style', 'line']),
|
|
39
39
|
custom: ['meta', 'value']
|
|
40
|
-
})
|
|
40
|
+
}),
|
|
41
|
+
protocols: _objectSpread(_objectSpread({}, defaultSchema.protocols), {}, {
|
|
42
|
+
src: [].concat(_toConsumableArray((_defaultSchema$protoc = (_defaultSchema$protoc2 = defaultSchema.protocols) === null || _defaultSchema$protoc2 === void 0 ? void 0 : _defaultSchema$protoc2.src) !== null && _defaultSchema$protoc !== void 0 ? _defaultSchema$protoc : []), ['data'])
|
|
43
|
+
}),
|
|
44
|
+
tagNames: [].concat(_toConsumableArray((_defaultSchema$tagNam = defaultSchema.tagNames) !== null && _defaultSchema$tagNam !== void 0 ? _defaultSchema$tagNam : []), ['custom'])
|
|
41
45
|
});
|
|
42
46
|
};
|
|
43
47
|
|
|
@@ -59,25 +63,7 @@ var processor = unified().use(remarkParse).use(remarkBreaks).use(remarkGfm).use(
|
|
|
59
63
|
}
|
|
60
64
|
}).use(rehypePrism, {
|
|
61
65
|
ignoreMissing: true
|
|
62
|
-
}).use(rehypeKatex).use(rehypeRaw).
|
|
63
|
-
return function (root) {
|
|
64
|
-
var _iterator = _createForOfIteratorHelper(root.children),
|
|
65
|
-
_step;
|
|
66
|
-
try {
|
|
67
|
-
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
68
|
-
var node = _step.value;
|
|
69
|
-
if ('properties' in node && node.properties) {
|
|
70
|
-
var _node$position;
|
|
71
|
-
node.properties.line = (_node$position = node.position) === null || _node$position === void 0 ? void 0 : _node$position.start.line;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
} catch (err) {
|
|
75
|
-
_iterator.e(err);
|
|
76
|
-
} finally {
|
|
77
|
-
_iterator.f();
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
}).freeze();
|
|
66
|
+
}).use(rehypeKatex).use(rehypeRaw).freeze();
|
|
81
67
|
|
|
82
68
|
/**
|
|
83
69
|
* Mdast 节点
|
|
@@ -93,7 +79,7 @@ export var editorRender = function editorRender(sourceCode) {
|
|
|
93
79
|
/**
|
|
94
80
|
* CSS 类名前缀
|
|
95
81
|
*/
|
|
96
|
-
var
|
|
82
|
+
var mdPrefix = "".concat(prefix, "md-");
|
|
97
83
|
|
|
98
84
|
/**
|
|
99
85
|
* 扫描偏移量,表示已经添加到 DOM 树的文本
|
|
@@ -101,7 +87,7 @@ export var editorRender = function editorRender(sourceCode) {
|
|
|
101
87
|
var scanOffset = 0;
|
|
102
88
|
|
|
103
89
|
/**
|
|
104
|
-
* 遍历 Mdast 树时的栈,保存 Mdast 节点、对应的 DOM
|
|
90
|
+
* 遍历 Mdast 树时的栈,保存 Mdast 节点、对应的 DOM 元素、为第几个子元素
|
|
105
91
|
*/
|
|
106
92
|
var stack = [];
|
|
107
93
|
|
|
@@ -122,47 +108,35 @@ export var editorRender = function editorRender(sourceCode) {
|
|
|
122
108
|
* @returns 子节点是否为流内容
|
|
123
109
|
*/
|
|
124
110
|
var isFlowContent = function isFlowContent(node) {
|
|
125
|
-
return node.type === 'blockquote' || node.type === '
|
|
111
|
+
return node.type === 'blockquote' || node.type === 'footnoteDefinition' || node.type === 'listItem';
|
|
126
112
|
};
|
|
127
113
|
|
|
128
114
|
/**
|
|
129
115
|
* 将栈中指定索引的 DOM 元素推到对应的父元素中
|
|
130
116
|
*
|
|
131
117
|
* @param index 索引
|
|
132
|
-
* @param last 是否为 Mdast 节点的最后一个子元素,默认为 `false`
|
|
133
118
|
*/
|
|
134
119
|
var pushElement = function pushElement(index) {
|
|
135
|
-
var
|
|
136
|
-
var _stack$index = stack[index],
|
|
137
|
-
node = _stack$index.node,
|
|
138
|
-
first = _stack$index.first;
|
|
120
|
+
var node = stack[index].node;
|
|
139
121
|
|
|
140
122
|
// 如果节点为流内容,则将样式添加到该行的 `<div>` 元素上,否则添加到该节点的元素上
|
|
141
123
|
var styleElement = stack[index && !isFlowContent(stack[index - 1].node) ? index : 0].el;
|
|
142
|
-
styleElement.classList.add("".concat(
|
|
124
|
+
styleElement.classList.add("".concat(mdPrefix).concat(node.type));
|
|
143
125
|
if (node.type === 'heading') {
|
|
144
|
-
styleElement.classList.add("".concat(
|
|
145
|
-
} else if (node.type === 'html' || node.type === 'code' || node.type === 'math') {
|
|
146
|
-
if (first) {
|
|
147
|
-
styleElement.classList.add("".concat(classNamePrefix, "first"));
|
|
148
|
-
}
|
|
149
|
-
if (last) {
|
|
150
|
-
styleElement.classList.add("".concat(classNamePrefix, "last"));
|
|
151
|
-
}
|
|
126
|
+
styleElement.classList.add("".concat(mdPrefix, "heading").concat(node.depth));
|
|
152
127
|
}
|
|
153
128
|
|
|
154
129
|
// 如果索引为 0,则父节点为块级元素,否则为前一个索引的 DOM 元素
|
|
155
130
|
var parentElement = index ? stack[index - 1].el : block;
|
|
156
131
|
parentElement.append(stack[index].el);
|
|
157
132
|
stack[index].el = document.createElement(index ? 'span' : 'div');
|
|
158
|
-
stack[index].
|
|
133
|
+
stack[index].counter++;
|
|
159
134
|
};
|
|
160
135
|
|
|
161
136
|
/**
|
|
162
137
|
* 将块级元素推到 DOM 树根元素中
|
|
163
138
|
*/
|
|
164
139
|
var pushBlock = function pushBlock() {
|
|
165
|
-
block.classList.add("".concat(classNamePrefix, "block"));
|
|
166
140
|
el.append(block);
|
|
167
141
|
block = document.createElement('div');
|
|
168
142
|
};
|
|
@@ -176,7 +150,7 @@ export var editorRender = function editorRender(sourceCode) {
|
|
|
176
150
|
var createDelimiter = function createDelimiter(text) {
|
|
177
151
|
var temp = document.createElement('span');
|
|
178
152
|
temp.append(text);
|
|
179
|
-
temp.classList.add("".concat(
|
|
153
|
+
temp.classList.add("".concat(mdPrefix, "delimiter"));
|
|
180
154
|
return temp;
|
|
181
155
|
};
|
|
182
156
|
|
|
@@ -235,14 +209,14 @@ export var editorRender = function editorRender(sourceCode) {
|
|
|
235
209
|
* @param parentEndOffset 父节点终点偏移量
|
|
236
210
|
*/
|
|
237
211
|
var getChildren = function getChildren(nodes, parentEndOffset) {
|
|
238
|
-
var
|
|
239
|
-
|
|
212
|
+
var _iterator = _createForOfIteratorHelper(nodes),
|
|
213
|
+
_step;
|
|
240
214
|
try {
|
|
241
|
-
for (
|
|
242
|
-
var _node$
|
|
243
|
-
var node =
|
|
244
|
-
var startOffset = (_node$
|
|
245
|
-
var endOffset = (_node$
|
|
215
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
216
|
+
var _node$position, _node$position2;
|
|
217
|
+
var node = _step.value;
|
|
218
|
+
var startOffset = (_node$position = node.position) === null || _node$position === void 0 ? void 0 : _node$position.start.offset;
|
|
219
|
+
var endOffset = (_node$position2 = node.position) === null || _node$position2 === void 0 ? void 0 : _node$position2.end.offset;
|
|
246
220
|
if (startOffset === undefined || endOffset === undefined) {
|
|
247
221
|
continue;
|
|
248
222
|
}
|
|
@@ -262,7 +236,7 @@ export var editorRender = function editorRender(sourceCode) {
|
|
|
262
236
|
stack.push({
|
|
263
237
|
node: node,
|
|
264
238
|
el: document.createElement(stack.length ? 'span' : 'div'),
|
|
265
|
-
|
|
239
|
+
counter: 0
|
|
266
240
|
});
|
|
267
241
|
if ('children' in node) {
|
|
268
242
|
getChildren(node.children, endOffset);
|
|
@@ -270,13 +244,13 @@ export var editorRender = function editorRender(sourceCode) {
|
|
|
270
244
|
addText(sourceCode.slice(scanOffset, endOffset));
|
|
271
245
|
}
|
|
272
246
|
if (stack.length > 1) {
|
|
273
|
-
pushElement(stack.length - 1
|
|
247
|
+
pushElement(stack.length - 1);
|
|
274
248
|
} else {
|
|
275
|
-
var _node$
|
|
249
|
+
var _node$position3;
|
|
276
250
|
// 如果栈大小为 1,说明为块级元素终点
|
|
277
251
|
stack[0].el.append("\u200B");
|
|
278
|
-
pushElement(0
|
|
279
|
-
block.
|
|
252
|
+
pushElement(0);
|
|
253
|
+
block.dataset.line = "".concat((_node$position3 = node.position) === null || _node$position3 === void 0 ? void 0 : _node$position3.start.line);
|
|
280
254
|
pushBlock();
|
|
281
255
|
scanOffset++;
|
|
282
256
|
}
|
|
@@ -285,9 +259,9 @@ export var editorRender = function editorRender(sourceCode) {
|
|
|
285
259
|
|
|
286
260
|
// 添加扫描偏移量与父节点终点偏移量间的分隔文本
|
|
287
261
|
} catch (err) {
|
|
288
|
-
|
|
262
|
+
_iterator.e(err);
|
|
289
263
|
} finally {
|
|
290
|
-
|
|
264
|
+
_iterator.f();
|
|
291
265
|
}
|
|
292
266
|
addText(sourceCode.slice(scanOffset, parentEndOffset), true);
|
|
293
267
|
};
|
|
@@ -307,7 +281,25 @@ export var editorRender = function editorRender(sourceCode) {
|
|
|
307
281
|
* @returns React 虚拟 DOM 树
|
|
308
282
|
*/
|
|
309
283
|
export var viewerRender = function viewerRender(sourceCode, options) {
|
|
310
|
-
return toJsxRuntime(processor().use(rehypeSanitize, options.customSchema).
|
|
284
|
+
return toJsxRuntime(processor().use(rehypeSanitize, options.customSchema).use(function () {
|
|
285
|
+
return function (root) {
|
|
286
|
+
var _iterator2 = _createForOfIteratorHelper(root.children),
|
|
287
|
+
_step2;
|
|
288
|
+
try {
|
|
289
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
290
|
+
var node = _step2.value;
|
|
291
|
+
if ('properties' in node && node.properties) {
|
|
292
|
+
var _node$position4;
|
|
293
|
+
node.properties['data-line'] = (_node$position4 = node.position) === null || _node$position4 === void 0 ? void 0 : _node$position4.start.line;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
} catch (err) {
|
|
297
|
+
_iterator2.e(err);
|
|
298
|
+
} finally {
|
|
299
|
+
_iterator2.f();
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
}).runSync(processor.parse(sourceCode)), {
|
|
311
303
|
Fragment: Fragment,
|
|
312
304
|
jsx: jsx,
|
|
313
305
|
jsxs: jsxs,
|
|
@@ -347,4 +339,15 @@ var toMarkdownProcessor = unified().use(rehypeRemark).use(remarkGfm).use(remarkB
|
|
|
347
339
|
*/
|
|
348
340
|
export var toMarkdown = function toMarkdown(sourceCode) {
|
|
349
341
|
return toMarkdownProcessor.stringify(toMarkdownProcessor.runSync(toHastProcessor.runSync(toHastProcessor.parse(sourceCode))));
|
|
342
|
+
};
|
|
343
|
+
var toTextProcessor = unified().use(strip).freeze();
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* 将 Markdown 文本转成纯文本
|
|
347
|
+
*
|
|
348
|
+
* @param sourceCode Markdown 文本
|
|
349
|
+
* @returns 纯文本
|
|
350
|
+
*/
|
|
351
|
+
export var toText = function toText(sourceCode) {
|
|
352
|
+
return toTextProcessor.processSync(sourceCode).toString();
|
|
350
353
|
};
|
|
@@ -1,15 +1,34 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type { XStarMdEditorHandle, XStarMdEditorProps } from '../
|
|
3
|
-
import type { XStarMdViewerHandle, XStarMdViewerProps } from '../
|
|
2
|
+
import type { XStarMdEditorHandle, XStarMdEditorProps } from '../x-star-md-editor';
|
|
3
|
+
import type { XStarMdViewerHandle, XStarMdViewerProps } from '../x-star-md-viewer';
|
|
4
4
|
export interface XStarEditorHandle {
|
|
5
5
|
getEditor: () => XStarMdEditorHandle | null;
|
|
6
6
|
getViewer: () => XStarMdViewerHandle | null;
|
|
7
7
|
}
|
|
8
8
|
export interface XStarEditorProps {
|
|
9
|
+
/**
|
|
10
|
+
* 编辑器和浏览器的高度(不包括工具栏)
|
|
11
|
+
*/
|
|
9
12
|
height?: React.CSSProperties['height'];
|
|
13
|
+
/**
|
|
14
|
+
* 语言
|
|
15
|
+
*/
|
|
16
|
+
locale?: string;
|
|
17
|
+
/**
|
|
18
|
+
* 初始文本
|
|
19
|
+
*/
|
|
10
20
|
initialValue?: string;
|
|
11
|
-
|
|
21
|
+
/**
|
|
22
|
+
* 编辑器属性
|
|
23
|
+
*/
|
|
24
|
+
editorProps?: Omit<XStarMdEditorProps, 'locale' | 'initialValue' | 'onChange'>;
|
|
25
|
+
/**
|
|
26
|
+
* 浏览器属性
|
|
27
|
+
*/
|
|
12
28
|
viewerProps?: Omit<XStarMdViewerProps, 'value'>;
|
|
29
|
+
/**
|
|
30
|
+
* 文本变化回调函数
|
|
31
|
+
*/
|
|
13
32
|
onChange?: (value: string) => void;
|
|
14
33
|
}
|
|
15
34
|
declare const XStarEditor: React.ForwardRefExoticComponent<XStarEditorProps & React.RefAttributes<XStarEditorHandle>>;
|