@8btc/mditor 0.0.2 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.css +17 -15
- package/dist/index.js +598 -33
- package/dist/index.min.js +1 -1
- package/dist/method.d.ts +10 -10
- package/dist/method.js +3 -3
- package/dist/method.min.js +1 -1
- package/dist/ts/util/attachLineNumbers.d.ts +28 -0
- package/dist/types/index.d.ts +13 -1
- package/package.json +1 -1
- package/src/assets/less/_line-number.less +19 -12
- package/src/index.ts +17 -0
- package/src/ts/ir/input.ts +180 -66
- package/src/ts/ir/process.ts +129 -40
- package/src/ts/sv/inputEvent.ts +169 -64
- package/src/ts/sv/process.ts +109 -41
- package/src/ts/util/attachLineNumbers.ts +463 -0
- package/src/ts/wysiwyg/afterRenderEvent.ts +22 -7
- package/src/ts/wysiwyg/index.ts +494 -262
- package/src/ts/wysiwyg/input.ts +148 -64
- package/src/ts/wysiwyg/renderDomByMd.ts +26 -11
package/src/ts/sv/process.ts
CHANGED
|
@@ -1,39 +1,51 @@
|
|
|
1
|
-
import {getMarkdown} from "../markdown/getMarkdown";
|
|
2
|
-
import {accessLocalStorage} from "../util/compatibility";
|
|
3
|
-
import {scrollCenter} from "../util/editorCommonEvent";
|
|
4
|
-
import {hasClosestBlock, hasClosestByAttribute} from "../util/hasClosest";
|
|
5
|
-
import {hasClosestByTag} from "../util/hasClosestByHeadings";
|
|
6
|
-
import {log} from "../util/log";
|
|
7
|
-
import {getEditorRange, setRangeByWbr} from "../util/selection";
|
|
8
|
-
import {inputEvent} from "./inputEvent";
|
|
9
|
-
import {combineFootnote} from "./combineFootnote";
|
|
10
|
-
|
|
1
|
+
import { getMarkdown } from "../markdown/getMarkdown";
|
|
2
|
+
import { accessLocalStorage } from "../util/compatibility";
|
|
3
|
+
import { scrollCenter } from "../util/editorCommonEvent";
|
|
4
|
+
import { hasClosestBlock, hasClosestByAttribute } from "../util/hasClosest";
|
|
5
|
+
import { hasClosestByTag } from "../util/hasClosestByHeadings";
|
|
6
|
+
import { log } from "../util/log";
|
|
7
|
+
import { getEditorRange, setRangeByWbr } from "../util/selection";
|
|
8
|
+
import { inputEvent } from "./inputEvent";
|
|
9
|
+
import { combineFootnote } from "./combineFootnote";
|
|
10
|
+
import { attachLineNumbersToBlocksThrottled } from "../util/attachLineNumbers";
|
|
11
11
|
|
|
12
12
|
export const processPaste = (vditor: IVditor, text: string) => {
|
|
13
13
|
const range = getEditorRange(vditor);
|
|
14
14
|
range.extractContents();
|
|
15
15
|
range.insertNode(document.createTextNode(Lute.Caret));
|
|
16
16
|
range.insertNode(document.createTextNode(text));
|
|
17
|
-
let blockElement = hasClosestByAttribute(
|
|
17
|
+
let blockElement = hasClosestByAttribute(
|
|
18
|
+
range.startContainer,
|
|
19
|
+
"data-block",
|
|
20
|
+
"0"
|
|
21
|
+
);
|
|
18
22
|
if (!blockElement) {
|
|
19
23
|
blockElement = vditor.sv.element;
|
|
20
24
|
}
|
|
21
|
-
let spinHTML = vditor.lute.SpinVditorSVDOM(blockElement.textContent)
|
|
22
|
-
spinHTML =
|
|
23
|
-
|
|
25
|
+
let spinHTML = vditor.lute.SpinVditorSVDOM(blockElement.textContent);
|
|
26
|
+
spinHTML =
|
|
27
|
+
"<div data-block='0'>" +
|
|
28
|
+
spinHTML.replace(
|
|
29
|
+
/<span data-type="newline"><br \/><span style="display: none">\n<\/span><\/span><span data-type="newline"><br \/><span style="display: none">\n<\/span><\/span></g,
|
|
30
|
+
'<span data-type="newline"><br /><span style="display: none">\n</span></span><span data-type="newline"><br /><span style="display: none">\n</span></span></div><div data-block="0"><'
|
|
31
|
+
) +
|
|
24
32
|
"</div>";
|
|
25
33
|
if (blockElement.isEqualNode(vditor.sv.element)) {
|
|
26
34
|
blockElement.innerHTML = spinHTML;
|
|
27
35
|
} else {
|
|
28
36
|
blockElement.outerHTML = spinHTML;
|
|
29
37
|
}
|
|
30
|
-
combineFootnote(vditor.sv.element)
|
|
38
|
+
combineFootnote(vditor.sv.element);
|
|
31
39
|
setRangeByWbr(vditor.sv.element, range);
|
|
32
40
|
|
|
33
41
|
scrollCenter(vditor);
|
|
34
42
|
};
|
|
35
43
|
|
|
36
|
-
export const getSideByType = (
|
|
44
|
+
export const getSideByType = (
|
|
45
|
+
spanNode: Node,
|
|
46
|
+
type: string,
|
|
47
|
+
isPrevious = true
|
|
48
|
+
) => {
|
|
37
49
|
let sideElement = spanNode as Element;
|
|
38
50
|
if (sideElement.nodeType === 3) {
|
|
39
51
|
sideElement = sideElement.parentElement;
|
|
@@ -53,9 +65,13 @@ export const getSideByType = (spanNode: Node, type: string, isPrevious = true) =
|
|
|
53
65
|
|
|
54
66
|
export const processSpinVditorSVDOM = (html: string, vditor: IVditor) => {
|
|
55
67
|
log("SpinVditorSVDOM", html, "argument", vditor.options.debugger);
|
|
56
|
-
const spinHTML = vditor.lute.SpinVditorSVDOM(html)
|
|
57
|
-
html =
|
|
58
|
-
|
|
68
|
+
const spinHTML = vditor.lute.SpinVditorSVDOM(html);
|
|
69
|
+
html =
|
|
70
|
+
"<div data-block='0'>" +
|
|
71
|
+
spinHTML.replace(
|
|
72
|
+
/<span data-type="newline"><br \/><span style="display: none">\n<\/span><\/span><span data-type="newline"><br \/><span style="display: none">\n<\/span><\/span></g,
|
|
73
|
+
'<span data-type="newline"><br /><span style="display: none">\n</span></span><span data-type="newline"><br /><span style="display: none">\n</span></span></div><div data-block="0"><'
|
|
74
|
+
) +
|
|
59
75
|
"</div>";
|
|
60
76
|
log("SpinVditorSVDOM", html, "result", vditor.options.debugger);
|
|
61
77
|
return html;
|
|
@@ -65,27 +81,48 @@ export const processPreviousMarkers = (spanElement: HTMLElement) => {
|
|
|
65
81
|
const spanType = spanElement.getAttribute("data-type");
|
|
66
82
|
let previousElement = spanElement.previousElementSibling;
|
|
67
83
|
// 有内容的子列表/标题,在其 marker 后换行
|
|
68
|
-
let markerText =
|
|
69
|
-
spanType
|
|
70
|
-
|
|
71
|
-
|
|
84
|
+
let markerText =
|
|
85
|
+
spanType &&
|
|
86
|
+
spanType !== "text" &&
|
|
87
|
+
spanType !== "table" &&
|
|
88
|
+
spanType !== "heading-marker" &&
|
|
89
|
+
spanType !== "newline" &&
|
|
90
|
+
spanType !== "yaml-front-matter-open-marker" &&
|
|
91
|
+
spanType !== "yaml-front-matter-close-marker" &&
|
|
92
|
+
spanType !== "code-block-info" &&
|
|
93
|
+
spanType !== "code-block-close-marker" &&
|
|
94
|
+
spanType !== "code-block-open-marker"
|
|
95
|
+
? spanElement.textContent
|
|
96
|
+
: "";
|
|
72
97
|
let hasNL = false;
|
|
73
98
|
if (spanType === "newline") {
|
|
74
99
|
hasNL = true;
|
|
75
100
|
}
|
|
76
101
|
while (previousElement && !hasNL) {
|
|
77
102
|
const previousType = previousElement.getAttribute("data-type");
|
|
78
|
-
if (
|
|
79
|
-
previousType === "
|
|
103
|
+
if (
|
|
104
|
+
previousType === "li-marker" ||
|
|
105
|
+
previousType === "blockquote-marker" ||
|
|
106
|
+
previousType === "task-marker" ||
|
|
107
|
+
previousType === "padding"
|
|
108
|
+
) {
|
|
80
109
|
const previousText = previousElement.textContent;
|
|
81
|
-
if (
|
|
82
|
-
|
|
110
|
+
if (
|
|
111
|
+
previousType === "li-marker" &&
|
|
112
|
+
(spanType === "code-block-open-marker" ||
|
|
113
|
+
spanType === "code-block-info")
|
|
114
|
+
) {
|
|
83
115
|
// https://github.com/Vanessa219/vditor/issues/586
|
|
84
116
|
markerText = previousText.replace(/\S/g, " ") + markerText;
|
|
85
|
-
} else if (
|
|
86
|
-
|
|
117
|
+
} else if (
|
|
118
|
+
spanType === "code-block-close-marker" &&
|
|
119
|
+
previousElement.nextElementSibling.isSameNode(spanElement)
|
|
120
|
+
) {
|
|
87
121
|
// https://github.com/Vanessa219/vditor/issues/594
|
|
88
|
-
const openMarker = getSideByType(
|
|
122
|
+
const openMarker = getSideByType(
|
|
123
|
+
spanElement,
|
|
124
|
+
"code-block-open-marker"
|
|
125
|
+
);
|
|
89
126
|
if (openMarker && openMarker.previousElementSibling) {
|
|
90
127
|
previousElement = openMarker.previousElementSibling;
|
|
91
128
|
markerText = previousText + markerText;
|
|
@@ -101,11 +138,14 @@ export const processPreviousMarkers = (spanElement: HTMLElement) => {
|
|
|
101
138
|
return markerText;
|
|
102
139
|
};
|
|
103
140
|
|
|
104
|
-
export const processAfterRender = (
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
141
|
+
export const processAfterRender = (
|
|
142
|
+
vditor: IVditor,
|
|
143
|
+
options = {
|
|
144
|
+
enableAddUndoStack: true,
|
|
145
|
+
enableHint: false,
|
|
146
|
+
enableInput: true,
|
|
147
|
+
}
|
|
148
|
+
) => {
|
|
109
149
|
if (options.enableHint) {
|
|
110
150
|
vditor.hint.render(vditor);
|
|
111
151
|
}
|
|
@@ -137,6 +177,13 @@ export const processAfterRender = (vditor: IVditor, options = {
|
|
|
137
177
|
if (options.enableAddUndoStack && !vditor.sv.composingLock) {
|
|
138
178
|
vditor.undo.addToUndoStack(vditor);
|
|
139
179
|
}
|
|
180
|
+
try {
|
|
181
|
+
if (vditor.options.lineNumber) {
|
|
182
|
+
attachLineNumbersToBlocksThrottled(vditor.sv.element, text);
|
|
183
|
+
}
|
|
184
|
+
} catch {
|
|
185
|
+
void 0;
|
|
186
|
+
}
|
|
140
187
|
}, vditor.options.undoDelay);
|
|
141
188
|
};
|
|
142
189
|
|
|
@@ -150,7 +197,12 @@ export const processHeading = (vditor: IVditor, value: string) => {
|
|
|
150
197
|
document.execCommand("insertHTML", false, value);
|
|
151
198
|
};
|
|
152
199
|
|
|
153
|
-
export const processToolbar = (
|
|
200
|
+
export const processToolbar = (
|
|
201
|
+
vditor: IVditor,
|
|
202
|
+
actionBtn: Element,
|
|
203
|
+
prefix: string,
|
|
204
|
+
suffix: string
|
|
205
|
+
) => {
|
|
154
206
|
const range = getEditorRange(vditor);
|
|
155
207
|
const commandName = actionBtn.getAttribute("data-type");
|
|
156
208
|
// 添加
|
|
@@ -173,8 +225,15 @@ export const processToolbar = (vditor: IVditor, actionBtn: Element, prefix: stri
|
|
|
173
225
|
}
|
|
174
226
|
document.execCommand("insertHTML", false, html);
|
|
175
227
|
return;
|
|
176
|
-
} else if (
|
|
177
|
-
commandName === "
|
|
228
|
+
} else if (
|
|
229
|
+
commandName === "italic" ||
|
|
230
|
+
commandName === "bold" ||
|
|
231
|
+
commandName === "strike" ||
|
|
232
|
+
commandName === "inline-code" ||
|
|
233
|
+
commandName === "code" ||
|
|
234
|
+
commandName === "table" ||
|
|
235
|
+
commandName === "line"
|
|
236
|
+
) {
|
|
178
237
|
let html;
|
|
179
238
|
// https://github.com/Vanessa219/vditor/issues/563 代码块不需要后面的 ```
|
|
180
239
|
if (range.toString() === "") {
|
|
@@ -182,15 +241,24 @@ export const processToolbar = (vditor: IVditor, actionBtn: Element, prefix: stri
|
|
|
182
241
|
} else {
|
|
183
242
|
html = `${prefix}${range.toString()}${Lute.Caret}${commandName === "code" ? "" : suffix}`;
|
|
184
243
|
}
|
|
185
|
-
if (
|
|
244
|
+
if (
|
|
245
|
+
commandName === "table" ||
|
|
246
|
+
(commandName === "code" &&
|
|
247
|
+
spanElement &&
|
|
248
|
+
spanElement.textContent !== "")
|
|
249
|
+
) {
|
|
186
250
|
html = "\n\n" + html;
|
|
187
251
|
} else if (commandName === "line") {
|
|
188
252
|
html = `\n\n${prefix}\n${Lute.Caret}`;
|
|
189
253
|
}
|
|
190
254
|
document.execCommand("insertHTML", false, html);
|
|
191
255
|
return;
|
|
192
|
-
} else if (
|
|
193
|
-
commandName === "
|
|
256
|
+
} else if (
|
|
257
|
+
commandName === "check" ||
|
|
258
|
+
commandName === "list" ||
|
|
259
|
+
commandName === "ordered-list" ||
|
|
260
|
+
commandName === "quote"
|
|
261
|
+
) {
|
|
194
262
|
if (spanElement) {
|
|
195
263
|
let marker = "* ";
|
|
196
264
|
if (commandName === "check") {
|