@8btc/mditor 0.0.3 → 0.0.5

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.
@@ -1,14 +1,16 @@
1
1
  import {
2
2
  getTopList,
3
- hasClosestBlock, hasClosestByAttribute, hasTopClosestByTag,
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 (event && event.inputType !== "formatItalic"
22
- && event.inputType !== "deleteByDrag"
23
- && event.inputType !== "insertFromDrop"
24
- && event.inputType !== "formatBold"
25
- && event.inputType !== "formatRemove"
26
- && event.inputType !== "formatStrikeThrough"
27
- && event.inputType !== "insertUnorderedList"
28
- && event.inputType !== "insertOrderedList"
29
- && event.inputType !== "formatOutdent"
30
- && event.inputType !== "formatIndent"
31
- && event.inputType !== "" // document.execCommand('unlink', false)
32
- || !event
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("vditor-comment", "vditor-comment--focus");
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?.querySelectorAll(".vditor-comment").forEach((item) => {
60
- if (item.textContent.trim() === "") {
61
- item.classList.remove("vditor-comment", "vditor-comment--focus");
62
- item.removeAttribute("data-cmtids");
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(vditor.wysiwyg.element);
73
- const footnoteElement = hasClosestByAttribute(blockElement, "data-type", "footnotes-block");
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(range.startContainer, "BLOCKQUOTE");
97
+ const blockquoteElement = hasClosestByTag(
98
+ range.startContainer,
99
+ "BLOCKQUOTE"
100
+ );
80
101
  if (blockquoteElement) {
81
102
  // li 中有 blockquote 就只渲染 blockquote
82
- blockElement = hasClosestBlock(range.startContainer) || 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 (blockElement.tagName === "UL" || blockElement.tagName === "OL") {
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 (listPrevElement && (listPrevElement.tagName === "UL" || listPrevElement.tagName === "OL")) {
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 (listNextElement && (listNextElement.tagName === "UL" || listNextElement.tagName === "OL")) {
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("<div><wbr><br></div>", "<li><p><wbr><br></p></li>");
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.querySelectorAll("[data-type='link-ref-defs-block']").forEach((item) => {
114
- if (item && !(blockElement as HTMLElement).isEqualNode(item)) {
115
- html += item.outerHTML;
116
- item.remove();
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.querySelectorAll("[data-type='footnotes-block']").forEach((item) => {
122
- if (item && !(blockElement as HTMLElement).isEqualNode(item)) {
123
- html += item.outerHTML;
124
- item.remove();
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.replace(/<\/(strong|b)><strong data-marker="\W{2}">/g, "")
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 (html === '<p data-block="0">```<wbr></p>' && vditor.hint.recentLanguage) {
138
- html = '<p data-block="0">```<wbr></p>'.replace("```", "```" + vditor.hint.recentLanguage);
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(vditor.wysiwyg.element.querySelector("wbr"), "LI");
205
+ const footnoteItemElement = hasTopClosestByTag(
206
+ vditor.wysiwyg.element.querySelector("wbr"),
207
+ "LI"
208
+ );
153
209
  if (footnoteItemElement) {
154
- const footnoteRefElement = vditor.wysiwyg.element.querySelector(`sup[data-type="footnotes-ref"][data-footnotes-label="${footnoteItemElement.getAttribute("data-marker")}"]`);
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("aria-label",
157
- footnoteItemElement.textContent.trim().substr(0, 24));
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("[data-type='link-ref-defs-block']");
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("beforeend", item.innerHTML);
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("beforeend", allLinkRefDefsElement[0]);
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("[data-type='footnotes-block']");
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("beforeend", item.innerHTML);
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("beforeend", allFootnoteElement[0]);
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.querySelectorAll(".vditor-wysiwyg__preview[data-render='2']")
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 (event && (event.inputType === "deleteContentBackward" || event.inputType === "deleteContentForward") &&
201
- vditor.options.comment.enable) {
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(vditor.wysiwyg.getComments(vditor, true));
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 = (vditor: IVditor, md: string, options = {
5
- enableAddUndoStack: true,
6
- enableHint: false,
7
- enableInput: true,
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.querySelectorAll(".vditor-wysiwyg__preview[data-render='2']").forEach((item: HTMLElement) => {
13
- processCodeRender(item, vditor);
14
- item.previousElementSibling.setAttribute("style", "display:none");
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
  };