@8btc/mditor 0.0.1 → 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/index.css +8 -14
- package/dist/index.js +297 -35
- package/dist/index.min.js +1 -1
- package/dist/method.js +3 -3
- package/dist/method.min.js +1 -1
- package/dist/ts/util/attachLineNumbers.d.ts +6 -0
- package/package.json +1 -1
- package/src/assets/less/_line-number.less +17 -10
- package/src/ts/ir/process.ts +127 -40
- package/src/ts/sv/process.ts +107 -41
- package/src/ts/util/attachLineNumbers.ts +437 -0
- package/src/ts/wysiwyg/afterRenderEvent.ts +17 -7
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 { attachLineNumbersToBlocks } 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,24 @@ export const processAfterRender = (vditor: IVditor, options = {
|
|
|
73
103
|
if (options.enableAddUndoStack) {
|
|
74
104
|
vditor.undo.addToUndoStack(vditor);
|
|
75
105
|
}
|
|
106
|
+
|
|
107
|
+
try {
|
|
108
|
+
attachLineNumbersToBlocks(vditor.ir.element, text);
|
|
109
|
+
} catch {
|
|
110
|
+
void 0;
|
|
111
|
+
}
|
|
76
112
|
}, vditor.options.undoDelay);
|
|
77
113
|
};
|
|
78
114
|
|
|
79
115
|
export const processHeading = (vditor: IVditor, value: string) => {
|
|
80
116
|
const range = getEditorRange(vditor);
|
|
81
|
-
const headingElement =
|
|
117
|
+
const headingElement =
|
|
118
|
+
hasClosestBlock(range.startContainer) ||
|
|
119
|
+
(range.startContainer as HTMLElement);
|
|
82
120
|
if (headingElement) {
|
|
83
|
-
const headingMarkerElement = headingElement.querySelector(
|
|
121
|
+
const headingMarkerElement = headingElement.querySelector(
|
|
122
|
+
".vditor-ir__marker--heading"
|
|
123
|
+
);
|
|
84
124
|
if (headingMarkerElement) {
|
|
85
125
|
headingMarkerElement.innerHTML = value;
|
|
86
126
|
} else {
|
|
@@ -94,18 +134,30 @@ export const processHeading = (vditor: IVditor, value: string) => {
|
|
|
94
134
|
};
|
|
95
135
|
|
|
96
136
|
const removeInline = (range: Range, vditor: IVditor, type: string) => {
|
|
97
|
-
const inlineElement = hasClosestByAttribute(
|
|
137
|
+
const inlineElement = hasClosestByAttribute(
|
|
138
|
+
range.startContainer,
|
|
139
|
+
"data-type",
|
|
140
|
+
type
|
|
141
|
+
) as HTMLElement;
|
|
98
142
|
if (inlineElement) {
|
|
99
143
|
inlineElement.firstElementChild.remove();
|
|
100
144
|
inlineElement.lastElementChild.remove();
|
|
101
145
|
range.insertNode(document.createElement("wbr"));
|
|
102
146
|
const tempElement = document.createElement("div");
|
|
103
|
-
tempElement.innerHTML = vditor.lute.SpinVditorIRDOM(
|
|
104
|
-
|
|
147
|
+
tempElement.innerHTML = vditor.lute.SpinVditorIRDOM(
|
|
148
|
+
inlineElement.outerHTML
|
|
149
|
+
);
|
|
150
|
+
inlineElement.outerHTML =
|
|
151
|
+
tempElement.firstElementChild.innerHTML.trim();
|
|
105
152
|
}
|
|
106
153
|
};
|
|
107
154
|
|
|
108
|
-
export const processToolbar = (
|
|
155
|
+
export const processToolbar = (
|
|
156
|
+
vditor: IVditor,
|
|
157
|
+
actionBtn: Element,
|
|
158
|
+
prefix: string,
|
|
159
|
+
suffix: string
|
|
160
|
+
) => {
|
|
109
161
|
const range = getEditorRange(vditor);
|
|
110
162
|
const commandName = actionBtn.getAttribute("data-type");
|
|
111
163
|
let typeElement = range.startContainer as HTMLElement;
|
|
@@ -116,21 +168,35 @@ export const processToolbar = (vditor: IVditor, actionBtn: Element, prefix: stri
|
|
|
116
168
|
// 移除
|
|
117
169
|
if (actionBtn.classList.contains("vditor-menu--current")) {
|
|
118
170
|
if (commandName === "quote") {
|
|
119
|
-
const quoteElement = hasClosestByMatchTag(
|
|
171
|
+
const quoteElement = hasClosestByMatchTag(
|
|
172
|
+
typeElement,
|
|
173
|
+
"BLOCKQUOTE"
|
|
174
|
+
);
|
|
120
175
|
if (quoteElement) {
|
|
121
176
|
range.insertNode(document.createElement("wbr"));
|
|
122
|
-
quoteElement.outerHTML =
|
|
123
|
-
|
|
177
|
+
quoteElement.outerHTML =
|
|
178
|
+
quoteElement.innerHTML.trim() === ""
|
|
179
|
+
? `<p data-block="0">${quoteElement.innerHTML}</p>`
|
|
180
|
+
: quoteElement.innerHTML;
|
|
124
181
|
}
|
|
125
182
|
} else if (commandName === "link") {
|
|
126
|
-
const aElement = hasClosestByAttribute(
|
|
183
|
+
const aElement = hasClosestByAttribute(
|
|
184
|
+
range.startContainer,
|
|
185
|
+
"data-type",
|
|
186
|
+
"a"
|
|
187
|
+
) as HTMLElement;
|
|
127
188
|
if (aElement) {
|
|
128
|
-
const aTextElement = hasClosestByClassName(
|
|
189
|
+
const aTextElement = hasClosestByClassName(
|
|
190
|
+
range.startContainer,
|
|
191
|
+
"vditor-ir__link"
|
|
192
|
+
);
|
|
129
193
|
if (aTextElement) {
|
|
130
194
|
range.insertNode(document.createElement("wbr"));
|
|
131
195
|
aElement.outerHTML = aTextElement.innerHTML;
|
|
132
196
|
} else {
|
|
133
|
-
aElement.outerHTML =
|
|
197
|
+
aElement.outerHTML =
|
|
198
|
+
aElement.querySelector(".vditor-ir__link").innerHTML +
|
|
199
|
+
"<wbr>";
|
|
134
200
|
}
|
|
135
201
|
}
|
|
136
202
|
} else if (commandName === "italic") {
|
|
@@ -141,7 +207,11 @@ export const processToolbar = (vditor: IVditor, actionBtn: Element, prefix: stri
|
|
|
141
207
|
removeInline(range, vditor, "s");
|
|
142
208
|
} else if (commandName === "inline-code") {
|
|
143
209
|
removeInline(range, vditor, "code");
|
|
144
|
-
} else if (
|
|
210
|
+
} else if (
|
|
211
|
+
commandName === "check" ||
|
|
212
|
+
commandName === "list" ||
|
|
213
|
+
commandName === "ordered-list"
|
|
214
|
+
) {
|
|
145
215
|
listToggle(vditor, range, commandName);
|
|
146
216
|
useHighlight = false;
|
|
147
217
|
actionBtn.classList.remove("vditor-menu--current");
|
|
@@ -155,7 +225,8 @@ export const processToolbar = (vditor: IVditor, actionBtn: Element, prefix: stri
|
|
|
155
225
|
const blockElement = hasClosestBlock(range.startContainer);
|
|
156
226
|
if (commandName === "line") {
|
|
157
227
|
if (blockElement) {
|
|
158
|
-
const hrHTML =
|
|
228
|
+
const hrHTML =
|
|
229
|
+
'<hr data-block="0"><p data-block="0"><wbr>\n</p>';
|
|
159
230
|
if (blockElement.innerHTML.trim() === "") {
|
|
160
231
|
blockElement.outerHTML = hrHTML;
|
|
161
232
|
} else {
|
|
@@ -179,8 +250,14 @@ export const processToolbar = (vditor: IVditor, actionBtn: Element, prefix: stri
|
|
|
179
250
|
document.execCommand("insertHTML", false, html);
|
|
180
251
|
useHighlight = false;
|
|
181
252
|
actionBtn.classList.add("vditor-menu--current");
|
|
182
|
-
} else if (
|
|
183
|
-
|
|
253
|
+
} else if (
|
|
254
|
+
commandName === "italic" ||
|
|
255
|
+
commandName === "bold" ||
|
|
256
|
+
commandName === "strike" ||
|
|
257
|
+
commandName === "inline-code" ||
|
|
258
|
+
commandName === "code" ||
|
|
259
|
+
commandName === "table"
|
|
260
|
+
) {
|
|
184
261
|
let html;
|
|
185
262
|
if (range.toString() === "") {
|
|
186
263
|
html = `${prefix}<wbr>${suffix}`;
|
|
@@ -204,13 +281,23 @@ export const processToolbar = (vditor: IVditor, actionBtn: Element, prefix: stri
|
|
|
204
281
|
input(vditor, range);
|
|
205
282
|
|
|
206
283
|
if (commandName === "table") {
|
|
207
|
-
range.selectNodeContents(
|
|
284
|
+
range.selectNodeContents(
|
|
285
|
+
getSelection().getRangeAt(0).startContainer.parentElement
|
|
286
|
+
);
|
|
208
287
|
setSelectionFocus(range);
|
|
209
288
|
}
|
|
210
|
-
} else if (
|
|
289
|
+
} else if (
|
|
290
|
+
commandName === "check" ||
|
|
291
|
+
commandName === "list" ||
|
|
292
|
+
commandName === "ordered-list"
|
|
293
|
+
) {
|
|
211
294
|
listToggle(vditor, range, commandName, false);
|
|
212
295
|
useHighlight = false;
|
|
213
|
-
removeCurrentToolbar(vditor.toolbar.elements, [
|
|
296
|
+
removeCurrentToolbar(vditor.toolbar.elements, [
|
|
297
|
+
"check",
|
|
298
|
+
"list",
|
|
299
|
+
"ordered-list",
|
|
300
|
+
]);
|
|
214
301
|
actionBtn.classList.add("vditor-menu--current");
|
|
215
302
|
}
|
|
216
303
|
}
|
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 { attachLineNumbersToBlocks } 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,11 @@ 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
|
+
attachLineNumbersToBlocks(vditor.sv.element, text);
|
|
182
|
+
} catch {
|
|
183
|
+
void 0;
|
|
184
|
+
}
|
|
140
185
|
}, vditor.options.undoDelay);
|
|
141
186
|
};
|
|
142
187
|
|
|
@@ -150,7 +195,12 @@ export const processHeading = (vditor: IVditor, value: string) => {
|
|
|
150
195
|
document.execCommand("insertHTML", false, value);
|
|
151
196
|
};
|
|
152
197
|
|
|
153
|
-
export const processToolbar = (
|
|
198
|
+
export const processToolbar = (
|
|
199
|
+
vditor: IVditor,
|
|
200
|
+
actionBtn: Element,
|
|
201
|
+
prefix: string,
|
|
202
|
+
suffix: string
|
|
203
|
+
) => {
|
|
154
204
|
const range = getEditorRange(vditor);
|
|
155
205
|
const commandName = actionBtn.getAttribute("data-type");
|
|
156
206
|
// 添加
|
|
@@ -173,8 +223,15 @@ export const processToolbar = (vditor: IVditor, actionBtn: Element, prefix: stri
|
|
|
173
223
|
}
|
|
174
224
|
document.execCommand("insertHTML", false, html);
|
|
175
225
|
return;
|
|
176
|
-
} else if (
|
|
177
|
-
commandName === "
|
|
226
|
+
} else if (
|
|
227
|
+
commandName === "italic" ||
|
|
228
|
+
commandName === "bold" ||
|
|
229
|
+
commandName === "strike" ||
|
|
230
|
+
commandName === "inline-code" ||
|
|
231
|
+
commandName === "code" ||
|
|
232
|
+
commandName === "table" ||
|
|
233
|
+
commandName === "line"
|
|
234
|
+
) {
|
|
178
235
|
let html;
|
|
179
236
|
// https://github.com/Vanessa219/vditor/issues/563 代码块不需要后面的 ```
|
|
180
237
|
if (range.toString() === "") {
|
|
@@ -182,15 +239,24 @@ export const processToolbar = (vditor: IVditor, actionBtn: Element, prefix: stri
|
|
|
182
239
|
} else {
|
|
183
240
|
html = `${prefix}${range.toString()}${Lute.Caret}${commandName === "code" ? "" : suffix}`;
|
|
184
241
|
}
|
|
185
|
-
if (
|
|
242
|
+
if (
|
|
243
|
+
commandName === "table" ||
|
|
244
|
+
(commandName === "code" &&
|
|
245
|
+
spanElement &&
|
|
246
|
+
spanElement.textContent !== "")
|
|
247
|
+
) {
|
|
186
248
|
html = "\n\n" + html;
|
|
187
249
|
} else if (commandName === "line") {
|
|
188
250
|
html = `\n\n${prefix}\n${Lute.Caret}`;
|
|
189
251
|
}
|
|
190
252
|
document.execCommand("insertHTML", false, html);
|
|
191
253
|
return;
|
|
192
|
-
} else if (
|
|
193
|
-
commandName === "
|
|
254
|
+
} else if (
|
|
255
|
+
commandName === "check" ||
|
|
256
|
+
commandName === "list" ||
|
|
257
|
+
commandName === "ordered-list" ||
|
|
258
|
+
commandName === "quote"
|
|
259
|
+
) {
|
|
194
260
|
if (spanElement) {
|
|
195
261
|
let marker = "* ";
|
|
196
262
|
if (commandName === "check") {
|