@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/ir/process.ts
CHANGED
|
@@ -1,29 +1,56 @@
|
|
|
1
|
-
import {Constants} from "../constants";
|
|
2
|
-
import {getMarkdown} from "../markdown/getMarkdown";
|
|
3
|
-
import {removeCurrentToolbar} from "../toolbar/setToolbar";
|
|
4
|
-
import {accessLocalStorage} from "../util/compatibility";
|
|
5
|
-
import {listToggle} from "../util/fixBrowserBehavior";
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
import { Constants } from "../constants";
|
|
2
|
+
import { getMarkdown } from "../markdown/getMarkdown";
|
|
3
|
+
import { removeCurrentToolbar } from "../toolbar/setToolbar";
|
|
4
|
+
import { accessLocalStorage } from "../util/compatibility";
|
|
5
|
+
import { listToggle } from "../util/fixBrowserBehavior";
|
|
6
|
+
import {
|
|
7
|
+
hasClosestBlock,
|
|
8
|
+
hasClosestByAttribute,
|
|
9
|
+
hasClosestByClassName,
|
|
10
|
+
hasClosestByMatchTag,
|
|
11
|
+
} from "../util/hasClosest";
|
|
12
|
+
import {
|
|
13
|
+
getEditorRange,
|
|
14
|
+
getSelectPosition,
|
|
15
|
+
setRangeByWbr,
|
|
16
|
+
setSelectionFocus,
|
|
17
|
+
} from "../util/selection";
|
|
18
|
+
import { highlightToolbarIR } from "./highlightToolbarIR";
|
|
19
|
+
import { input } from "./input";
|
|
20
|
+
import { attachLineNumbersToBlocksThrottled } from "../util/attachLineNumbers";
|
|
10
21
|
|
|
11
22
|
export const processHint = (vditor: IVditor) => {
|
|
12
23
|
vditor.hint.render(vditor);
|
|
13
24
|
const startContainer = getEditorRange(vditor).startContainer;
|
|
14
25
|
// 代码块语言提示
|
|
15
|
-
const preBeforeElement = hasClosestByAttribute(
|
|
26
|
+
const preBeforeElement = hasClosestByAttribute(
|
|
27
|
+
startContainer,
|
|
28
|
+
"data-type",
|
|
29
|
+
"code-block-info"
|
|
30
|
+
);
|
|
16
31
|
if (preBeforeElement) {
|
|
17
|
-
if (
|
|
18
|
-
preBeforeElement.textContent
|
|
32
|
+
if (
|
|
33
|
+
preBeforeElement.textContent.replace(Constants.ZWSP, "") === "" &&
|
|
34
|
+
vditor.hint.recentLanguage
|
|
35
|
+
) {
|
|
36
|
+
preBeforeElement.textContent =
|
|
37
|
+
Constants.ZWSP + vditor.hint.recentLanguage;
|
|
19
38
|
const range = getEditorRange(vditor);
|
|
20
39
|
range.selectNodeContents(preBeforeElement);
|
|
21
40
|
} else {
|
|
22
41
|
const matchLangData: IHintData[] = [];
|
|
23
|
-
const key =
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
42
|
+
const key = preBeforeElement.textContent
|
|
43
|
+
.substring(
|
|
44
|
+
0,
|
|
45
|
+
getSelectPosition(preBeforeElement, vditor.ir.element).start
|
|
46
|
+
)
|
|
47
|
+
.replace(Constants.ZWSP, "");
|
|
48
|
+
(
|
|
49
|
+
vditor.options.preview.hljs.langs ||
|
|
50
|
+
Constants.ALIAS_CODE_LANGUAGES.concat(
|
|
51
|
+
(window.hljs?.listLanguages() ?? []).sort()
|
|
52
|
+
)
|
|
53
|
+
).forEach((keyName) => {
|
|
27
54
|
if (keyName.indexOf(key.toLowerCase()) > -1) {
|
|
28
55
|
matchLangData.push({
|
|
29
56
|
html: keyName,
|
|
@@ -36,11 +63,14 @@ export const processHint = (vditor: IVditor) => {
|
|
|
36
63
|
}
|
|
37
64
|
};
|
|
38
65
|
|
|
39
|
-
export const processAfterRender = (
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
66
|
+
export const processAfterRender = (
|
|
67
|
+
vditor: IVditor,
|
|
68
|
+
options = {
|
|
69
|
+
enableAddUndoStack: true,
|
|
70
|
+
enableHint: false,
|
|
71
|
+
enableInput: true,
|
|
72
|
+
}
|
|
73
|
+
) => {
|
|
44
74
|
if (options.enableHint) {
|
|
45
75
|
processHint(vditor);
|
|
46
76
|
}
|
|
@@ -73,14 +103,26 @@ export const processAfterRender = (vditor: IVditor, options = {
|
|
|
73
103
|
if (options.enableAddUndoStack) {
|
|
74
104
|
vditor.undo.addToUndoStack(vditor);
|
|
75
105
|
}
|
|
106
|
+
|
|
107
|
+
try {
|
|
108
|
+
if (vditor.options.lineNumber) {
|
|
109
|
+
attachLineNumbersToBlocksThrottled(vditor.ir.element, text);
|
|
110
|
+
}
|
|
111
|
+
} catch {
|
|
112
|
+
void 0;
|
|
113
|
+
}
|
|
76
114
|
}, vditor.options.undoDelay);
|
|
77
115
|
};
|
|
78
116
|
|
|
79
117
|
export const processHeading = (vditor: IVditor, value: string) => {
|
|
80
118
|
const range = getEditorRange(vditor);
|
|
81
|
-
const headingElement =
|
|
119
|
+
const headingElement =
|
|
120
|
+
hasClosestBlock(range.startContainer) ||
|
|
121
|
+
(range.startContainer as HTMLElement);
|
|
82
122
|
if (headingElement) {
|
|
83
|
-
const headingMarkerElement = headingElement.querySelector(
|
|
123
|
+
const headingMarkerElement = headingElement.querySelector(
|
|
124
|
+
".vditor-ir__marker--heading"
|
|
125
|
+
);
|
|
84
126
|
if (headingMarkerElement) {
|
|
85
127
|
headingMarkerElement.innerHTML = value;
|
|
86
128
|
} else {
|
|
@@ -94,18 +136,30 @@ export const processHeading = (vditor: IVditor, value: string) => {
|
|
|
94
136
|
};
|
|
95
137
|
|
|
96
138
|
const removeInline = (range: Range, vditor: IVditor, type: string) => {
|
|
97
|
-
const inlineElement = hasClosestByAttribute(
|
|
139
|
+
const inlineElement = hasClosestByAttribute(
|
|
140
|
+
range.startContainer,
|
|
141
|
+
"data-type",
|
|
142
|
+
type
|
|
143
|
+
) as HTMLElement;
|
|
98
144
|
if (inlineElement) {
|
|
99
145
|
inlineElement.firstElementChild.remove();
|
|
100
146
|
inlineElement.lastElementChild.remove();
|
|
101
147
|
range.insertNode(document.createElement("wbr"));
|
|
102
148
|
const tempElement = document.createElement("div");
|
|
103
|
-
tempElement.innerHTML = vditor.lute.SpinVditorIRDOM(
|
|
104
|
-
|
|
149
|
+
tempElement.innerHTML = vditor.lute.SpinVditorIRDOM(
|
|
150
|
+
inlineElement.outerHTML
|
|
151
|
+
);
|
|
152
|
+
inlineElement.outerHTML =
|
|
153
|
+
tempElement.firstElementChild.innerHTML.trim();
|
|
105
154
|
}
|
|
106
155
|
};
|
|
107
156
|
|
|
108
|
-
export const processToolbar = (
|
|
157
|
+
export const processToolbar = (
|
|
158
|
+
vditor: IVditor,
|
|
159
|
+
actionBtn: Element,
|
|
160
|
+
prefix: string,
|
|
161
|
+
suffix: string
|
|
162
|
+
) => {
|
|
109
163
|
const range = getEditorRange(vditor);
|
|
110
164
|
const commandName = actionBtn.getAttribute("data-type");
|
|
111
165
|
let typeElement = range.startContainer as HTMLElement;
|
|
@@ -116,21 +170,35 @@ export const processToolbar = (vditor: IVditor, actionBtn: Element, prefix: stri
|
|
|
116
170
|
// 移除
|
|
117
171
|
if (actionBtn.classList.contains("vditor-menu--current")) {
|
|
118
172
|
if (commandName === "quote") {
|
|
119
|
-
const quoteElement = hasClosestByMatchTag(
|
|
173
|
+
const quoteElement = hasClosestByMatchTag(
|
|
174
|
+
typeElement,
|
|
175
|
+
"BLOCKQUOTE"
|
|
176
|
+
);
|
|
120
177
|
if (quoteElement) {
|
|
121
178
|
range.insertNode(document.createElement("wbr"));
|
|
122
|
-
quoteElement.outerHTML =
|
|
123
|
-
|
|
179
|
+
quoteElement.outerHTML =
|
|
180
|
+
quoteElement.innerHTML.trim() === ""
|
|
181
|
+
? `<p data-block="0">${quoteElement.innerHTML}</p>`
|
|
182
|
+
: quoteElement.innerHTML;
|
|
124
183
|
}
|
|
125
184
|
} else if (commandName === "link") {
|
|
126
|
-
const aElement = hasClosestByAttribute(
|
|
185
|
+
const aElement = hasClosestByAttribute(
|
|
186
|
+
range.startContainer,
|
|
187
|
+
"data-type",
|
|
188
|
+
"a"
|
|
189
|
+
) as HTMLElement;
|
|
127
190
|
if (aElement) {
|
|
128
|
-
const aTextElement = hasClosestByClassName(
|
|
191
|
+
const aTextElement = hasClosestByClassName(
|
|
192
|
+
range.startContainer,
|
|
193
|
+
"vditor-ir__link"
|
|
194
|
+
);
|
|
129
195
|
if (aTextElement) {
|
|
130
196
|
range.insertNode(document.createElement("wbr"));
|
|
131
197
|
aElement.outerHTML = aTextElement.innerHTML;
|
|
132
198
|
} else {
|
|
133
|
-
aElement.outerHTML =
|
|
199
|
+
aElement.outerHTML =
|
|
200
|
+
aElement.querySelector(".vditor-ir__link").innerHTML +
|
|
201
|
+
"<wbr>";
|
|
134
202
|
}
|
|
135
203
|
}
|
|
136
204
|
} else if (commandName === "italic") {
|
|
@@ -141,7 +209,11 @@ export const processToolbar = (vditor: IVditor, actionBtn: Element, prefix: stri
|
|
|
141
209
|
removeInline(range, vditor, "s");
|
|
142
210
|
} else if (commandName === "inline-code") {
|
|
143
211
|
removeInline(range, vditor, "code");
|
|
144
|
-
} else if (
|
|
212
|
+
} else if (
|
|
213
|
+
commandName === "check" ||
|
|
214
|
+
commandName === "list" ||
|
|
215
|
+
commandName === "ordered-list"
|
|
216
|
+
) {
|
|
145
217
|
listToggle(vditor, range, commandName);
|
|
146
218
|
useHighlight = false;
|
|
147
219
|
actionBtn.classList.remove("vditor-menu--current");
|
|
@@ -155,7 +227,8 @@ export const processToolbar = (vditor: IVditor, actionBtn: Element, prefix: stri
|
|
|
155
227
|
const blockElement = hasClosestBlock(range.startContainer);
|
|
156
228
|
if (commandName === "line") {
|
|
157
229
|
if (blockElement) {
|
|
158
|
-
const hrHTML =
|
|
230
|
+
const hrHTML =
|
|
231
|
+
'<hr data-block="0"><p data-block="0"><wbr>\n</p>';
|
|
159
232
|
if (blockElement.innerHTML.trim() === "") {
|
|
160
233
|
blockElement.outerHTML = hrHTML;
|
|
161
234
|
} else {
|
|
@@ -179,8 +252,14 @@ export const processToolbar = (vditor: IVditor, actionBtn: Element, prefix: stri
|
|
|
179
252
|
document.execCommand("insertHTML", false, html);
|
|
180
253
|
useHighlight = false;
|
|
181
254
|
actionBtn.classList.add("vditor-menu--current");
|
|
182
|
-
} else if (
|
|
183
|
-
|
|
255
|
+
} else if (
|
|
256
|
+
commandName === "italic" ||
|
|
257
|
+
commandName === "bold" ||
|
|
258
|
+
commandName === "strike" ||
|
|
259
|
+
commandName === "inline-code" ||
|
|
260
|
+
commandName === "code" ||
|
|
261
|
+
commandName === "table"
|
|
262
|
+
) {
|
|
184
263
|
let html;
|
|
185
264
|
if (range.toString() === "") {
|
|
186
265
|
html = `${prefix}<wbr>${suffix}`;
|
|
@@ -204,13 +283,23 @@ export const processToolbar = (vditor: IVditor, actionBtn: Element, prefix: stri
|
|
|
204
283
|
input(vditor, range);
|
|
205
284
|
|
|
206
285
|
if (commandName === "table") {
|
|
207
|
-
range.selectNodeContents(
|
|
286
|
+
range.selectNodeContents(
|
|
287
|
+
getSelection().getRangeAt(0).startContainer.parentElement
|
|
288
|
+
);
|
|
208
289
|
setSelectionFocus(range);
|
|
209
290
|
}
|
|
210
|
-
} else if (
|
|
291
|
+
} else if (
|
|
292
|
+
commandName === "check" ||
|
|
293
|
+
commandName === "list" ||
|
|
294
|
+
commandName === "ordered-list"
|
|
295
|
+
) {
|
|
211
296
|
listToggle(vditor, range, commandName, false);
|
|
212
297
|
useHighlight = false;
|
|
213
|
-
removeCurrentToolbar(vditor.toolbar.elements, [
|
|
298
|
+
removeCurrentToolbar(vditor.toolbar.elements, [
|
|
299
|
+
"check",
|
|
300
|
+
"list",
|
|
301
|
+
"ordered-list",
|
|
302
|
+
]);
|
|
214
303
|
actionBtn.classList.add("vditor-menu--current");
|
|
215
304
|
}
|
|
216
305
|
}
|
package/src/ts/sv/inputEvent.ts
CHANGED
|
@@ -1,27 +1,48 @@
|
|
|
1
|
-
import {scrollCenter} from "../util/editorCommonEvent";
|
|
2
|
-
import {hasClosestByAttribute} from "../util/hasClosest";
|
|
3
|
-
import {getSelectPosition, setRangeByWbr} from "../util/selection";
|
|
4
|
-
import {
|
|
5
|
-
|
|
1
|
+
import { scrollCenter } from "../util/editorCommonEvent";
|
|
2
|
+
import { hasClosestByAttribute } from "../util/hasClosest";
|
|
3
|
+
import { getSelectPosition, setRangeByWbr } from "../util/selection";
|
|
4
|
+
import {
|
|
5
|
+
getSideByType,
|
|
6
|
+
processAfterRender,
|
|
7
|
+
processSpinVditorSVDOM,
|
|
8
|
+
} from "./process";
|
|
9
|
+
import { combineFootnote } from "./combineFootnote";
|
|
6
10
|
|
|
7
11
|
export const inputEvent = (vditor: IVditor, event?: InputEvent) => {
|
|
8
12
|
const range = getSelection().getRangeAt(0).cloneRange();
|
|
9
13
|
let startContainer = range.startContainer;
|
|
10
|
-
if (
|
|
14
|
+
if (
|
|
15
|
+
range.startContainer.nodeType !== 3 &&
|
|
16
|
+
(range.startContainer as HTMLElement).tagName === "DIV"
|
|
17
|
+
) {
|
|
11
18
|
startContainer = range.startContainer.childNodes[range.startOffset - 1];
|
|
12
19
|
}
|
|
13
20
|
let blockElement = hasClosestByAttribute(startContainer, "data-block", "0");
|
|
14
21
|
// 不调用 lute 解析
|
|
15
|
-
if (
|
|
22
|
+
if (
|
|
23
|
+
blockElement &&
|
|
24
|
+
event &&
|
|
25
|
+
(event.inputType === "deleteContentBackward" || event.data === " ")
|
|
26
|
+
) {
|
|
16
27
|
// 开始可以输入空格
|
|
17
|
-
const startOffset = getSelectPosition(
|
|
28
|
+
const startOffset = getSelectPosition(
|
|
29
|
+
blockElement,
|
|
30
|
+
vditor.sv.element,
|
|
31
|
+
range
|
|
32
|
+
).start;
|
|
18
33
|
let startSpace = true;
|
|
19
|
-
for (
|
|
34
|
+
for (
|
|
35
|
+
let i = startOffset - 1;
|
|
20
36
|
// 软换行后有空格
|
|
21
|
-
|
|
22
|
-
|
|
37
|
+
i >
|
|
38
|
+
blockElement.textContent.substr(0, startOffset).lastIndexOf("\n");
|
|
39
|
+
i--
|
|
40
|
+
) {
|
|
41
|
+
if (
|
|
42
|
+
blockElement.textContent.charAt(i) !== " " &&
|
|
23
43
|
// 多个 tab 前删除不形成代码块 https://github.com/Vanessa219/vditor/issues/162 1
|
|
24
|
-
blockElement.textContent.charAt(i) !== "\t"
|
|
44
|
+
blockElement.textContent.charAt(i) !== "\t"
|
|
45
|
+
) {
|
|
25
46
|
startSpace = false;
|
|
26
47
|
break;
|
|
27
48
|
}
|
|
@@ -37,63 +58,120 @@ export const inputEvent = (vditor: IVditor, event?: InputEvent) => {
|
|
|
37
58
|
if (event.inputType === "deleteContentBackward") {
|
|
38
59
|
// https://github.com/Vanessa219/vditor/issues/584 代码块 marker 删除
|
|
39
60
|
const codeBlockMarkerElement =
|
|
40
|
-
hasClosestByAttribute(
|
|
41
|
-
|
|
61
|
+
hasClosestByAttribute(
|
|
62
|
+
startContainer,
|
|
63
|
+
"data-type",
|
|
64
|
+
"code-block-open-marker"
|
|
65
|
+
) ||
|
|
66
|
+
hasClosestByAttribute(
|
|
67
|
+
startContainer,
|
|
68
|
+
"data-type",
|
|
69
|
+
"code-block-close-marker"
|
|
70
|
+
);
|
|
42
71
|
if (codeBlockMarkerElement) {
|
|
43
|
-
if (
|
|
44
|
-
|
|
72
|
+
if (
|
|
73
|
+
codeBlockMarkerElement.getAttribute("data-type") ===
|
|
74
|
+
"code-block-close-marker"
|
|
75
|
+
) {
|
|
76
|
+
const openMarkerElement = getSideByType(
|
|
77
|
+
startContainer,
|
|
78
|
+
"code-block-open-marker"
|
|
79
|
+
);
|
|
45
80
|
if (openMarkerElement) {
|
|
46
|
-
openMarkerElement.textContent =
|
|
81
|
+
openMarkerElement.textContent =
|
|
82
|
+
codeBlockMarkerElement.textContent;
|
|
47
83
|
processAfterRender(vditor);
|
|
48
84
|
return;
|
|
49
85
|
}
|
|
50
86
|
}
|
|
51
|
-
if (
|
|
52
|
-
|
|
87
|
+
if (
|
|
88
|
+
codeBlockMarkerElement.getAttribute("data-type") ===
|
|
89
|
+
"code-block-open-marker"
|
|
90
|
+
) {
|
|
91
|
+
const openMarkerElement = getSideByType(
|
|
92
|
+
startContainer,
|
|
93
|
+
"code-block-close-marker",
|
|
94
|
+
false
|
|
95
|
+
);
|
|
53
96
|
if (openMarkerElement) {
|
|
54
|
-
openMarkerElement.textContent =
|
|
97
|
+
openMarkerElement.textContent =
|
|
98
|
+
codeBlockMarkerElement.textContent;
|
|
55
99
|
processAfterRender(vditor);
|
|
56
100
|
return;
|
|
57
101
|
}
|
|
58
102
|
}
|
|
59
103
|
}
|
|
60
104
|
// https://github.com/Vanessa219/vditor/issues/877 数学公式输入删除生成节点
|
|
61
|
-
const mathBlockMarkerElement =
|
|
62
|
-
|
|
105
|
+
const mathBlockMarkerElement = hasClosestByAttribute(
|
|
106
|
+
startContainer,
|
|
107
|
+
"data-type",
|
|
108
|
+
"math-block-open-marker"
|
|
109
|
+
);
|
|
63
110
|
if (mathBlockMarkerElement) {
|
|
64
|
-
const mathBlockCloseElement =
|
|
65
|
-
|
|
111
|
+
const mathBlockCloseElement =
|
|
112
|
+
mathBlockMarkerElement.nextElementSibling
|
|
113
|
+
.nextElementSibling;
|
|
114
|
+
if (
|
|
115
|
+
mathBlockCloseElement &&
|
|
116
|
+
mathBlockCloseElement.getAttribute("data-type") ===
|
|
117
|
+
"math-block-close-marker"
|
|
118
|
+
) {
|
|
66
119
|
mathBlockCloseElement.remove();
|
|
67
120
|
processAfterRender(vditor);
|
|
68
121
|
}
|
|
69
122
|
return;
|
|
70
123
|
}
|
|
71
124
|
|
|
72
|
-
blockElement
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
125
|
+
blockElement
|
|
126
|
+
.querySelectorAll('[data-type="code-block-open-marker"]')
|
|
127
|
+
.forEach((item: HTMLElement) => {
|
|
128
|
+
if (item.textContent.length === 1) {
|
|
129
|
+
item.remove();
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
blockElement
|
|
133
|
+
.querySelectorAll('[data-type="code-block-close-marker"]')
|
|
134
|
+
.forEach((item: HTMLElement) => {
|
|
135
|
+
if (item.textContent.length === 1) {
|
|
136
|
+
item.remove();
|
|
137
|
+
}
|
|
138
|
+
});
|
|
82
139
|
|
|
83
140
|
// 标题删除
|
|
84
|
-
const headingElement = hasClosestByAttribute(
|
|
85
|
-
|
|
141
|
+
const headingElement = hasClosestByAttribute(
|
|
142
|
+
startContainer,
|
|
143
|
+
"data-type",
|
|
144
|
+
"heading-marker"
|
|
145
|
+
);
|
|
146
|
+
if (
|
|
147
|
+
headingElement &&
|
|
148
|
+
headingElement.textContent.indexOf("#") === -1
|
|
149
|
+
) {
|
|
86
150
|
processAfterRender(vditor);
|
|
87
151
|
return;
|
|
88
152
|
}
|
|
89
153
|
}
|
|
90
154
|
// 删除或空格不解析,否则会 format 回去
|
|
91
|
-
if (
|
|
92
|
-
(
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
155
|
+
if (
|
|
156
|
+
(event.data === " " ||
|
|
157
|
+
event.inputType === "deleteContentBackward") &&
|
|
158
|
+
(hasClosestByAttribute(startContainer, "data-type", "padding") || // 场景:b 前进行删除 [> 1. a\n> b]
|
|
159
|
+
hasClosestByAttribute(
|
|
160
|
+
startContainer,
|
|
161
|
+
"data-type",
|
|
162
|
+
"li-marker"
|
|
163
|
+
) || // 场景:删除最后一个字符 [* 1\n* ]
|
|
164
|
+
hasClosestByAttribute(
|
|
165
|
+
startContainer,
|
|
166
|
+
"data-type",
|
|
167
|
+
"task-marker"
|
|
168
|
+
) || // 场景:删除最后一个字符 [* [ ] ]
|
|
169
|
+
hasClosestByAttribute(
|
|
170
|
+
startContainer,
|
|
171
|
+
"data-type",
|
|
172
|
+
"blockquote-marker"
|
|
173
|
+
)) // 场景:删除最后一个字符 [> ]
|
|
174
|
+
) {
|
|
97
175
|
processAfterRender(vditor);
|
|
98
176
|
return;
|
|
99
177
|
}
|
|
@@ -106,7 +184,10 @@ export const inputEvent = (vditor: IVditor, event?: InputEvent) => {
|
|
|
106
184
|
if (!blockElement) {
|
|
107
185
|
blockElement = vditor.sv.element;
|
|
108
186
|
}
|
|
109
|
-
if (
|
|
187
|
+
if (
|
|
188
|
+
blockElement.firstElementChild?.getAttribute("data-type") ===
|
|
189
|
+
"link-ref-defs-block"
|
|
190
|
+
) {
|
|
110
191
|
// 修改链接引用
|
|
111
192
|
blockElement = vditor.sv.element;
|
|
112
193
|
}
|
|
@@ -120,10 +201,12 @@ export const inputEvent = (vditor: IVditor, event?: InputEvent) => {
|
|
|
120
201
|
range.insertNode(document.createTextNode(Lute.Caret));
|
|
121
202
|
}
|
|
122
203
|
// 清除浏览器自带的样式
|
|
123
|
-
blockElement.querySelectorAll("[style]").forEach((item) => {
|
|
204
|
+
blockElement.querySelectorAll("[style]").forEach((item) => {
|
|
205
|
+
// 不可前置,否则会影响 newline 的样式
|
|
124
206
|
item.removeAttribute("style");
|
|
125
207
|
});
|
|
126
|
-
blockElement.querySelectorAll("font").forEach((item) => {
|
|
208
|
+
blockElement.querySelectorAll("font").forEach((item) => {
|
|
209
|
+
// 不可前置,否则会影响光标的位置
|
|
127
210
|
item.outerHTML = item.innerHTML;
|
|
128
211
|
});
|
|
129
212
|
let html = blockElement.textContent;
|
|
@@ -136,28 +219,45 @@ export const inputEvent = (vditor: IVditor, event?: InputEvent) => {
|
|
|
136
219
|
html = blockElement.previousElementSibling.textContent + html;
|
|
137
220
|
blockElement.previousElementSibling.remove();
|
|
138
221
|
}
|
|
139
|
-
if (
|
|
222
|
+
if (
|
|
223
|
+
blockElement.previousElementSibling &&
|
|
224
|
+
html.indexOf("---\n") === 0
|
|
225
|
+
) {
|
|
140
226
|
// 确认 yaml-front 是否为首行
|
|
141
227
|
html = blockElement.previousElementSibling.textContent + html;
|
|
142
228
|
blockElement.previousElementSibling.remove();
|
|
143
229
|
}
|
|
144
230
|
// 添加链接引用
|
|
145
|
-
let footnotes = ""
|
|
231
|
+
let footnotes = "";
|
|
146
232
|
|
|
147
|
-
vditor.sv.element
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
233
|
+
vditor.sv.element
|
|
234
|
+
.querySelectorAll("[data-type='link-ref-defs-block']")
|
|
235
|
+
.forEach((item, index) => {
|
|
236
|
+
if (
|
|
237
|
+
item &&
|
|
238
|
+
!(blockElement as HTMLElement).isEqualNode(
|
|
239
|
+
item.parentElement
|
|
240
|
+
)
|
|
241
|
+
) {
|
|
242
|
+
footnotes += item.parentElement.textContent + "\n";
|
|
243
|
+
item.parentElement.remove();
|
|
244
|
+
}
|
|
245
|
+
});
|
|
153
246
|
|
|
154
247
|
// 添加脚注到文章头,便于lute处理
|
|
155
|
-
vditor.sv.element
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
248
|
+
vditor.sv.element
|
|
249
|
+
.querySelectorAll("[data-type='footnotes-link']")
|
|
250
|
+
.forEach((item, index) => {
|
|
251
|
+
if (
|
|
252
|
+
item &&
|
|
253
|
+
!(blockElement as HTMLElement).isEqualNode(
|
|
254
|
+
item.parentElement
|
|
255
|
+
)
|
|
256
|
+
) {
|
|
257
|
+
footnotes += item.parentElement.textContent + "\n";
|
|
258
|
+
item.parentElement.remove();
|
|
259
|
+
}
|
|
260
|
+
});
|
|
161
261
|
html = footnotes + html;
|
|
162
262
|
}
|
|
163
263
|
html = processSpinVditorSVDOM(html, vditor);
|
|
@@ -167,14 +267,19 @@ export const inputEvent = (vditor: IVditor, event?: InputEvent) => {
|
|
|
167
267
|
blockElement.outerHTML = html;
|
|
168
268
|
}
|
|
169
269
|
|
|
170
|
-
vditor.sv.element
|
|
171
|
-
|
|
172
|
-
|
|
270
|
+
vditor.sv.element
|
|
271
|
+
.querySelectorAll("[data-type='link-ref-defs-block']")
|
|
272
|
+
.forEach((item) => {
|
|
273
|
+
vditor.sv.element.insertAdjacentElement(
|
|
274
|
+
"beforeend",
|
|
275
|
+
item.parentElement
|
|
276
|
+
);
|
|
277
|
+
});
|
|
173
278
|
|
|
174
279
|
// 合并脚注
|
|
175
280
|
combineFootnote(vditor.sv.element, (root: HTMLElement) => {
|
|
176
|
-
vditor.sv.element.insertAdjacentElement("beforeend", root)
|
|
177
|
-
})
|
|
281
|
+
vditor.sv.element.insertAdjacentElement("beforeend", root);
|
|
282
|
+
});
|
|
178
283
|
|
|
179
284
|
setRangeByWbr(vditor.sv.element, range);
|
|
180
285
|
|