@8btc/mditor 0.0.3 → 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 +16 -8
- package/dist/index.js +405 -98
- 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 +26 -4
- package/dist/types/index.d.ts +13 -1
- package/package.json +1 -1
- package/src/assets/less/_line-number.less +4 -4
- package/src/index.ts +17 -0
- package/src/ts/ir/input.ts +180 -66
- package/src/ts/ir/process.ts +4 -2
- package/src/ts/sv/inputEvent.ts +169 -64
- package/src/ts/sv/process.ts +4 -2
- package/src/ts/util/attachLineNumbers.ts +32 -6
- package/src/ts/wysiwyg/afterRenderEvent.ts +7 -2
- 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/wysiwyg/input.ts
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getTopList,
|
|
3
|
-
hasClosestBlock,
|
|
3
|
+
hasClosestBlock,
|
|
4
|
+
hasClosestByAttribute,
|
|
5
|
+
hasTopClosestByTag,
|
|
4
6
|
} from "../util/hasClosest";
|
|
5
|
-
import {hasClosestByTag} from "../util/hasClosestByHeadings";
|
|
6
|
-
import {log} from "../util/log";
|
|
7
|
-
import {processCodeRender} from "../util/processCode";
|
|
8
|
-
import {setRangeByWbr} from "../util/selection";
|
|
9
|
-
import {renderToc} from "../util/toc";
|
|
10
|
-
import {afterRenderEvent} from "./afterRenderEvent";
|
|
11
|
-
import {previoueIsEmptyA} from "./inlineTag";
|
|
7
|
+
import { hasClosestByTag } from "../util/hasClosestByHeadings";
|
|
8
|
+
import { log } from "../util/log";
|
|
9
|
+
import { processCodeRender } from "../util/processCode";
|
|
10
|
+
import { setRangeByWbr } from "../util/selection";
|
|
11
|
+
import { renderToc } from "../util/toc";
|
|
12
|
+
import { afterRenderEvent } from "./afterRenderEvent";
|
|
13
|
+
import { previoueIsEmptyA } from "./inlineTag";
|
|
12
14
|
|
|
13
15
|
export const input = (vditor: IVditor, range: Range, event?: InputEvent) => {
|
|
14
16
|
let blockElement = hasClosestBlock(range.startContainer);
|
|
@@ -18,18 +20,20 @@ export const input = (vditor: IVditor, range: Range, event?: InputEvent) => {
|
|
|
18
20
|
blockElement = vditor.wysiwyg.element;
|
|
19
21
|
}
|
|
20
22
|
|
|
21
|
-
if (
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
23
|
+
if (
|
|
24
|
+
(event &&
|
|
25
|
+
event.inputType !== "formatItalic" &&
|
|
26
|
+
event.inputType !== "deleteByDrag" &&
|
|
27
|
+
event.inputType !== "insertFromDrop" &&
|
|
28
|
+
event.inputType !== "formatBold" &&
|
|
29
|
+
event.inputType !== "formatRemove" &&
|
|
30
|
+
event.inputType !== "formatStrikeThrough" &&
|
|
31
|
+
event.inputType !== "insertUnorderedList" &&
|
|
32
|
+
event.inputType !== "insertOrderedList" &&
|
|
33
|
+
event.inputType !== "formatOutdent" &&
|
|
34
|
+
event.inputType !== "formatIndent" &&
|
|
35
|
+
event.inputType !== "") || // document.execCommand('unlink', false)
|
|
36
|
+
!event
|
|
33
37
|
) {
|
|
34
38
|
const previousAEmptyElement = previoueIsEmptyA(range.startContainer);
|
|
35
39
|
if (previousAEmptyElement) {
|
|
@@ -51,17 +55,25 @@ export const input = (vditor: IVditor, range: Range, event?: InputEvent) => {
|
|
|
51
55
|
// 移除空评论
|
|
52
56
|
blockElement.querySelectorAll(".vditor-comment").forEach((item) => {
|
|
53
57
|
if (item.textContent.trim() === "") {
|
|
54
|
-
item.classList.remove(
|
|
58
|
+
item.classList.remove(
|
|
59
|
+
"vditor-comment",
|
|
60
|
+
"vditor-comment--focus"
|
|
61
|
+
);
|
|
55
62
|
item.removeAttribute("data-cmtids");
|
|
56
63
|
}
|
|
57
64
|
});
|
|
58
65
|
// 在有评论的行首换行后,该行的前一段会带有评论标识
|
|
59
|
-
blockElement.previousElementSibling
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
item.
|
|
63
|
-
|
|
64
|
-
|
|
66
|
+
blockElement.previousElementSibling
|
|
67
|
+
?.querySelectorAll(".vditor-comment")
|
|
68
|
+
.forEach((item) => {
|
|
69
|
+
if (item.textContent.trim() === "") {
|
|
70
|
+
item.classList.remove(
|
|
71
|
+
"vditor-comment",
|
|
72
|
+
"vditor-comment--focus"
|
|
73
|
+
);
|
|
74
|
+
item.removeAttribute("data-cmtids");
|
|
75
|
+
}
|
|
76
|
+
});
|
|
65
77
|
|
|
66
78
|
let html = "";
|
|
67
79
|
if (blockElement.getAttribute("data-type") === "link-ref-defs-block") {
|
|
@@ -69,17 +81,27 @@ export const input = (vditor: IVditor, range: Range, event?: InputEvent) => {
|
|
|
69
81
|
blockElement = vditor.wysiwyg.element;
|
|
70
82
|
}
|
|
71
83
|
|
|
72
|
-
const isWYSIWYGElement = blockElement.isEqualNode(
|
|
73
|
-
|
|
84
|
+
const isWYSIWYGElement = blockElement.isEqualNode(
|
|
85
|
+
vditor.wysiwyg.element
|
|
86
|
+
);
|
|
87
|
+
const footnoteElement = hasClosestByAttribute(
|
|
88
|
+
blockElement,
|
|
89
|
+
"data-type",
|
|
90
|
+
"footnotes-block"
|
|
91
|
+
);
|
|
74
92
|
|
|
75
93
|
if (!isWYSIWYGElement) {
|
|
76
94
|
// 列表需要到最顶层
|
|
77
95
|
const topListElement = getTopList(range.startContainer);
|
|
78
96
|
if (topListElement && !footnoteElement) {
|
|
79
|
-
const blockquoteElement = hasClosestByTag(
|
|
97
|
+
const blockquoteElement = hasClosestByTag(
|
|
98
|
+
range.startContainer,
|
|
99
|
+
"BLOCKQUOTE"
|
|
100
|
+
);
|
|
80
101
|
if (blockquoteElement) {
|
|
81
102
|
// li 中有 blockquote 就只渲染 blockquote
|
|
82
|
-
blockElement =
|
|
103
|
+
blockElement =
|
|
104
|
+
hasClosestBlock(range.startContainer) || blockElement;
|
|
83
105
|
} else {
|
|
84
106
|
blockElement = topListElement;
|
|
85
107
|
}
|
|
@@ -92,50 +114,81 @@ export const input = (vditor: IVditor, range: Range, event?: InputEvent) => {
|
|
|
92
114
|
|
|
93
115
|
html = blockElement.outerHTML;
|
|
94
116
|
|
|
95
|
-
if (
|
|
117
|
+
if (
|
|
118
|
+
blockElement.tagName === "UL" ||
|
|
119
|
+
blockElement.tagName === "OL"
|
|
120
|
+
) {
|
|
96
121
|
// 如果为列表的话,需要把上下的列表都重绘
|
|
97
122
|
const listPrevElement = blockElement.previousElementSibling;
|
|
98
123
|
const listNextElement = blockElement.nextElementSibling;
|
|
99
|
-
if (
|
|
124
|
+
if (
|
|
125
|
+
listPrevElement &&
|
|
126
|
+
(listPrevElement.tagName === "UL" ||
|
|
127
|
+
listPrevElement.tagName === "OL")
|
|
128
|
+
) {
|
|
100
129
|
html = listPrevElement.outerHTML + html;
|
|
101
130
|
listPrevElement.remove();
|
|
102
131
|
}
|
|
103
|
-
if (
|
|
132
|
+
if (
|
|
133
|
+
listNextElement &&
|
|
134
|
+
(listNextElement.tagName === "UL" ||
|
|
135
|
+
listNextElement.tagName === "OL")
|
|
136
|
+
) {
|
|
104
137
|
html = html + listNextElement.outerHTML;
|
|
105
138
|
listNextElement.remove();
|
|
106
139
|
}
|
|
107
140
|
// firefox 列表回车不会产生新的 list item https://github.com/Vanessa219/vditor/issues/194
|
|
108
|
-
html = html.replace(
|
|
141
|
+
html = html.replace(
|
|
142
|
+
"<div><wbr><br></div>",
|
|
143
|
+
"<li><p><wbr><br></p></li>"
|
|
144
|
+
);
|
|
109
145
|
}
|
|
110
146
|
|
|
111
147
|
if (!blockElement.innerText.startsWith("```")) {
|
|
112
148
|
// 添加链接引用
|
|
113
|
-
vditor.wysiwyg.element
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
149
|
+
vditor.wysiwyg.element
|
|
150
|
+
.querySelectorAll("[data-type='link-ref-defs-block']")
|
|
151
|
+
.forEach((item) => {
|
|
152
|
+
if (
|
|
153
|
+
item &&
|
|
154
|
+
!(blockElement as HTMLElement).isEqualNode(item)
|
|
155
|
+
) {
|
|
156
|
+
html += item.outerHTML;
|
|
157
|
+
item.remove();
|
|
158
|
+
}
|
|
159
|
+
});
|
|
119
160
|
|
|
120
161
|
// 添加脚注
|
|
121
|
-
vditor.wysiwyg.element
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
162
|
+
vditor.wysiwyg.element
|
|
163
|
+
.querySelectorAll("[data-type='footnotes-block']")
|
|
164
|
+
.forEach((item) => {
|
|
165
|
+
if (
|
|
166
|
+
item &&
|
|
167
|
+
!(blockElement as HTMLElement).isEqualNode(item)
|
|
168
|
+
) {
|
|
169
|
+
html += item.outerHTML;
|
|
170
|
+
item.remove();
|
|
171
|
+
}
|
|
172
|
+
});
|
|
127
173
|
}
|
|
128
174
|
} else {
|
|
129
175
|
html = blockElement.innerHTML;
|
|
130
176
|
}
|
|
131
177
|
|
|
132
178
|
// 合并多个 em, strong,s。以防止多个相同元素在一起时不满足 commonmark 规范,出现标记符
|
|
133
|
-
html = html
|
|
179
|
+
html = html
|
|
180
|
+
.replace(/<\/(strong|b)><strong data-marker="\W{2}">/g, "")
|
|
134
181
|
.replace(/<\/(em|i)><em data-marker="\W{1}">/g, "")
|
|
135
182
|
.replace(/<\/(s|strike)><s data-marker="~{1,2}">/g, "");
|
|
136
183
|
|
|
137
|
-
if (
|
|
138
|
-
html
|
|
184
|
+
if (
|
|
185
|
+
html === '<p data-block="0">```<wbr></p>' &&
|
|
186
|
+
vditor.hint.recentLanguage
|
|
187
|
+
) {
|
|
188
|
+
html = '<p data-block="0">```<wbr></p>'.replace(
|
|
189
|
+
"```",
|
|
190
|
+
"```" + vditor.hint.recentLanguage
|
|
191
|
+
);
|
|
139
192
|
}
|
|
140
193
|
|
|
141
194
|
log("SpinVditorDOM", html, "argument", vditor.options.debugger);
|
|
@@ -149,58 +202,89 @@ export const input = (vditor: IVditor, range: Range, event?: InputEvent) => {
|
|
|
149
202
|
|
|
150
203
|
if (footnoteElement) {
|
|
151
204
|
// 更新正文中的 tip
|
|
152
|
-
const footnoteItemElement = hasTopClosestByTag(
|
|
205
|
+
const footnoteItemElement = hasTopClosestByTag(
|
|
206
|
+
vditor.wysiwyg.element.querySelector("wbr"),
|
|
207
|
+
"LI"
|
|
208
|
+
);
|
|
153
209
|
if (footnoteItemElement) {
|
|
154
|
-
const footnoteRefElement =
|
|
210
|
+
const footnoteRefElement =
|
|
211
|
+
vditor.wysiwyg.element.querySelector(
|
|
212
|
+
`sup[data-type="footnotes-ref"][data-footnotes-label="${footnoteItemElement.getAttribute("data-marker")}"]`
|
|
213
|
+
);
|
|
155
214
|
if (footnoteRefElement) {
|
|
156
|
-
footnoteRefElement.setAttribute(
|
|
157
|
-
|
|
215
|
+
footnoteRefElement.setAttribute(
|
|
216
|
+
"aria-label",
|
|
217
|
+
footnoteItemElement.textContent.trim().substr(0, 24)
|
|
218
|
+
);
|
|
158
219
|
}
|
|
159
220
|
}
|
|
160
221
|
}
|
|
161
222
|
}
|
|
162
223
|
|
|
163
224
|
let firstLinkRefDefElement: Element;
|
|
164
|
-
const allLinkRefDefsElement = vditor.wysiwyg.element.querySelectorAll(
|
|
225
|
+
const allLinkRefDefsElement = vditor.wysiwyg.element.querySelectorAll(
|
|
226
|
+
"[data-type='link-ref-defs-block']"
|
|
227
|
+
);
|
|
165
228
|
allLinkRefDefsElement.forEach((item, index) => {
|
|
166
229
|
if (index === 0) {
|
|
167
230
|
firstLinkRefDefElement = item;
|
|
168
231
|
} else {
|
|
169
|
-
firstLinkRefDefElement.insertAdjacentHTML(
|
|
232
|
+
firstLinkRefDefElement.insertAdjacentHTML(
|
|
233
|
+
"beforeend",
|
|
234
|
+
item.innerHTML
|
|
235
|
+
);
|
|
170
236
|
item.remove();
|
|
171
237
|
}
|
|
172
238
|
});
|
|
173
239
|
if (allLinkRefDefsElement.length > 0) {
|
|
174
|
-
vditor.wysiwyg.element.insertAdjacentElement(
|
|
240
|
+
vditor.wysiwyg.element.insertAdjacentElement(
|
|
241
|
+
"beforeend",
|
|
242
|
+
allLinkRefDefsElement[0]
|
|
243
|
+
);
|
|
175
244
|
}
|
|
176
245
|
|
|
177
246
|
// 脚注合并后添加的末尾
|
|
178
247
|
let firstFootnoteElement: Element;
|
|
179
|
-
const allFootnoteElement = vditor.wysiwyg.element.querySelectorAll(
|
|
248
|
+
const allFootnoteElement = vditor.wysiwyg.element.querySelectorAll(
|
|
249
|
+
"[data-type='footnotes-block']"
|
|
250
|
+
);
|
|
180
251
|
allFootnoteElement.forEach((item, index) => {
|
|
181
252
|
if (index === 0) {
|
|
182
253
|
firstFootnoteElement = item;
|
|
183
254
|
} else {
|
|
184
|
-
firstFootnoteElement.insertAdjacentHTML(
|
|
255
|
+
firstFootnoteElement.insertAdjacentHTML(
|
|
256
|
+
"beforeend",
|
|
257
|
+
item.innerHTML
|
|
258
|
+
);
|
|
185
259
|
item.remove();
|
|
186
260
|
}
|
|
187
261
|
});
|
|
188
262
|
if (allFootnoteElement.length > 0) {
|
|
189
|
-
vditor.wysiwyg.element.insertAdjacentElement(
|
|
263
|
+
vditor.wysiwyg.element.insertAdjacentElement(
|
|
264
|
+
"beforeend",
|
|
265
|
+
allFootnoteElement[0]
|
|
266
|
+
);
|
|
190
267
|
}
|
|
191
268
|
|
|
192
269
|
// 设置光标
|
|
193
270
|
setRangeByWbr(vditor.wysiwyg.element, range);
|
|
194
271
|
|
|
195
|
-
vditor.wysiwyg.element
|
|
272
|
+
vditor.wysiwyg.element
|
|
273
|
+
.querySelectorAll(".vditor-wysiwyg__preview[data-render='2']")
|
|
196
274
|
.forEach((item: HTMLElement) => {
|
|
197
275
|
processCodeRender(item, vditor);
|
|
198
276
|
});
|
|
199
277
|
|
|
200
|
-
if (
|
|
201
|
-
|
|
278
|
+
if (
|
|
279
|
+
event &&
|
|
280
|
+
(event.inputType === "deleteContentBackward" ||
|
|
281
|
+
event.inputType === "deleteContentForward") &&
|
|
282
|
+
vditor.options.comment.enable
|
|
283
|
+
) {
|
|
202
284
|
vditor.wysiwyg.triggerRemoveComment(vditor);
|
|
203
|
-
vditor.options.comment.adjustTop(
|
|
285
|
+
vditor.options.comment.adjustTop(
|
|
286
|
+
vditor.wysiwyg.getComments(vditor, true)
|
|
287
|
+
);
|
|
204
288
|
}
|
|
205
289
|
}
|
|
206
290
|
renderToc(vditor);
|
|
@@ -1,18 +1,33 @@
|
|
|
1
|
-
import {processCodeRender} from "../util/processCode";
|
|
2
|
-
import {afterRenderEvent} from "./afterRenderEvent";
|
|
1
|
+
import { processCodeRender } from "../util/processCode";
|
|
2
|
+
import { afterRenderEvent } from "./afterRenderEvent";
|
|
3
|
+
import { attachLineNumbersToBlocks } from "../util/attachLineNumbers";
|
|
3
4
|
|
|
4
|
-
export const renderDomByMd = (
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
export const renderDomByMd = (
|
|
6
|
+
vditor: IVditor,
|
|
7
|
+
md: string,
|
|
8
|
+
options = {
|
|
9
|
+
enableAddUndoStack: true,
|
|
10
|
+
enableHint: false,
|
|
11
|
+
enableInput: true,
|
|
12
|
+
}
|
|
13
|
+
) => {
|
|
9
14
|
const editorElement = vditor.wysiwyg.element;
|
|
10
15
|
editorElement.innerHTML = vditor.lute.Md2VditorDOM(md);
|
|
11
16
|
|
|
12
|
-
editorElement
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
17
|
+
editorElement
|
|
18
|
+
.querySelectorAll(".vditor-wysiwyg__preview[data-render='2']")
|
|
19
|
+
.forEach((item: HTMLElement) => {
|
|
20
|
+
processCodeRender(item, vditor);
|
|
21
|
+
item.previousElementSibling.setAttribute("style", "display:none");
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
if (vditor.options.lineNumber) {
|
|
25
|
+
try {
|
|
26
|
+
attachLineNumbersToBlocks(editorElement, md);
|
|
27
|
+
} catch {
|
|
28
|
+
void 0;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
16
31
|
|
|
17
32
|
afterRenderEvent(vditor, options);
|
|
18
33
|
};
|