@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.
@@ -1,40 +1,62 @@
1
- import {Constants} from "../constants";
2
- import {isHeadingMD, isHrMD} from "../util/fixBrowserBehavior";
1
+ import { Constants } from "../constants";
2
+ import { isHeadingMD, isHrMD } from "../util/fixBrowserBehavior";
3
3
  import {
4
4
  getTopList,
5
- hasClosestBlock, hasClosestByAttribute,
5
+ hasClosestBlock,
6
+ hasClosestByAttribute,
6
7
  hasClosestByClassName,
7
8
  } from "../util/hasClosest";
8
- import {hasClosestByTag} from "../util/hasClosestByHeadings";
9
- import {log} from "../util/log";
10
- import {processCodeRender} from "../util/processCode";
11
- import {getSelectPosition, setRangeByWbr} from "../util/selection";
12
- import {renderToc} from "../util/toc";
13
- import {processAfterRender} from "./process";
14
- import {getMarkdown} from "../markdown/getMarkdown";
9
+ import { hasClosestByTag } from "../util/hasClosestByHeadings";
10
+ import { log } from "../util/log";
11
+ import { processCodeRender } from "../util/processCode";
12
+ import { getSelectPosition, setRangeByWbr } from "../util/selection";
13
+ import { renderToc } from "../util/toc";
14
+ import { processAfterRender } from "./process";
15
+ import { getMarkdown } from "../markdown/getMarkdown";
15
16
  import { bindMathInteractionsInContainer } from "../markdown/mathContextMenu";
16
17
 
17
- export const input = (vditor: IVditor, range: Range, ignoreSpace = false, event?: InputEvent) => {
18
+ export const input = (
19
+ vditor: IVditor,
20
+ range: Range,
21
+ ignoreSpace = false,
22
+ event?: InputEvent
23
+ ) => {
18
24
  let blockElement = hasClosestBlock(range.startContainer);
19
25
  // 前后可以输入空格
20
- if (blockElement && !ignoreSpace && blockElement.getAttribute("data-type") !== "code-block") {
21
- if ((isHrMD(blockElement.innerHTML) && blockElement.previousElementSibling) ||
22
- isHeadingMD(blockElement.innerHTML)) {
26
+ if (
27
+ blockElement &&
28
+ !ignoreSpace &&
29
+ blockElement.getAttribute("data-type") !== "code-block"
30
+ ) {
31
+ if (
32
+ (isHrMD(blockElement.innerHTML) &&
33
+ blockElement.previousElementSibling) ||
34
+ isHeadingMD(blockElement.innerHTML)
35
+ ) {
23
36
  return;
24
37
  }
25
38
 
26
39
  // 前后空格处理
27
- const startOffset = getSelectPosition(blockElement, vditor.ir.element, range).start;
40
+ const startOffset = getSelectPosition(
41
+ blockElement,
42
+ vditor.ir.element,
43
+ range
44
+ ).start;
28
45
 
29
46
  // 开始可以输入空格
30
47
  let startSpace = true;
31
- for (let i = startOffset - 1;
48
+ for (
49
+ let i = startOffset - 1;
32
50
  // 软换行后有空格
33
- i > blockElement.textContent.substr(0, startOffset).lastIndexOf("\n");
34
- i--) {
35
- if (blockElement.textContent.charAt(i) !== " " &&
51
+ i >
52
+ blockElement.textContent.substr(0, startOffset).lastIndexOf("\n");
53
+ i--
54
+ ) {
55
+ if (
56
+ blockElement.textContent.charAt(i) !== " " &&
36
57
  // 多个 tab 前删除不形成代码块 https://github.com/Vanessa219/vditor/issues/162 1
37
- blockElement.textContent.charAt(i) !== "\t") {
58
+ blockElement.textContent.charAt(i) !== "\t"
59
+ ) {
38
60
  startSpace = false;
39
61
  break;
40
62
  }
@@ -45,8 +67,15 @@ export const input = (vditor: IVditor, range: Range, ignoreSpace = false, event?
45
67
 
46
68
  // 结尾可以输入空格
47
69
  let endSpace = true;
48
- for (let i = startOffset - 1; i < blockElement.textContent.length; i++) {
49
- if (blockElement.textContent.charAt(i) !== " " && blockElement.textContent.charAt(i) !== "\n") {
70
+ for (
71
+ let i = startOffset - 1;
72
+ i < blockElement.textContent.length;
73
+ i++
74
+ ) {
75
+ if (
76
+ blockElement.textContent.charAt(i) !== " " &&
77
+ blockElement.textContent.charAt(i) !== "\n"
78
+ ) {
50
79
  endSpace = false;
51
80
  break;
52
81
  }
@@ -65,12 +94,20 @@ export const input = (vditor: IVditor, range: Range, ignoreSpace = false, event?
65
94
  }
66
95
 
67
96
  if (endSpace) {
68
- const markerElement = hasClosestByClassName(range.startContainer, "vditor-ir__marker");
97
+ const markerElement = hasClosestByClassName(
98
+ range.startContainer,
99
+ "vditor-ir__marker"
100
+ );
69
101
  if (markerElement) {
70
102
  // inline marker space https://github.com/Vanessa219/vditor/issues/239
71
103
  } else {
72
- const previousNode = range.startContainer.previousSibling as HTMLElement;
73
- if (previousNode && previousNode.nodeType !== 3 && previousNode.classList.contains("vditor-ir__node--expand")) {
104
+ const previousNode = range.startContainer
105
+ .previousSibling as HTMLElement;
106
+ if (
107
+ previousNode &&
108
+ previousNode.nodeType !== 3 &&
109
+ previousNode.classList.contains("vditor-ir__node--expand")
110
+ ) {
74
111
  // FireFox https://github.com/Vanessa219/vditor/issues/239
75
112
  previousNode.classList.remove("vditor-ir__node--expand");
76
113
  }
@@ -82,9 +119,11 @@ export const input = (vditor: IVditor, range: Range, ignoreSpace = false, event?
82
119
  }
83
120
  }
84
121
 
85
- vditor.ir.element.querySelectorAll(".vditor-ir__node--expand").forEach((item) => {
86
- item.classList.remove("vditor-ir__node--expand");
87
- });
122
+ vditor.ir.element
123
+ .querySelectorAll(".vditor-ir__node--expand")
124
+ .forEach((item) => {
125
+ item.classList.remove("vditor-ir__node--expand");
126
+ });
88
127
 
89
128
  if (!blockElement) {
90
129
  // 使用顶级块元素,应使用 innerHTML
@@ -93,9 +132,15 @@ export const input = (vditor: IVditor, range: Range, ignoreSpace = false, event?
93
132
 
94
133
  // document.exeComment insertHTML 会插入 wbr
95
134
  if (!blockElement.querySelector("wbr")) {
96
- const previewRenderElement = hasClosestByClassName(range.startContainer, "vditor-ir__preview");
135
+ const previewRenderElement = hasClosestByClassName(
136
+ range.startContainer,
137
+ "vditor-ir__preview"
138
+ );
97
139
  if (previewRenderElement) {
98
- previewRenderElement.previousElementSibling.insertAdjacentHTML("beforeend", "<wbr>");
140
+ previewRenderElement.previousElementSibling.insertAdjacentHTML(
141
+ "beforeend",
142
+ "<wbr>"
143
+ );
99
144
  } else {
100
145
  range.insertNode(document.createElement("wbr"));
101
146
  }
@@ -112,10 +157,17 @@ export const input = (vditor: IVditor, range: Range, ignoreSpace = false, event?
112
157
  }
113
158
 
114
159
  const isIRElement = blockElement.isEqualNode(vditor.ir.element);
115
- const footnoteElement = hasClosestByAttribute(blockElement, "data-type", "footnotes-block");
160
+ const footnoteElement = hasClosestByAttribute(
161
+ blockElement,
162
+ "data-type",
163
+ "footnotes-block"
164
+ );
116
165
  let html = "";
117
166
  if (!isIRElement) {
118
- const blockquoteElement = hasClosestByTag(range.startContainer, "BLOCKQUOTE");
167
+ const blockquoteElement = hasClosestByTag(
168
+ range.startContainer,
169
+ "BLOCKQUOTE"
170
+ );
119
171
  // 列表需要到最顶层
120
172
  const topListElement = getTopList(range.startContainer);
121
173
  if (topListElement) {
@@ -123,7 +175,11 @@ export const input = (vditor: IVditor, range: Range, ignoreSpace = false, event?
123
175
  }
124
176
 
125
177
  // 应到引用层,否则 > --- 会解析为 front-matter;列表中有 blockquote 则解析 blockquote;blockquote 中有列表则解析列表
126
- if (blockquoteElement && (!topListElement || (topListElement && !blockquoteElement.contains(topListElement)))) {
178
+ if (
179
+ blockquoteElement &&
180
+ (!topListElement ||
181
+ (topListElement && !blockquoteElement.contains(topListElement)))
182
+ ) {
127
183
  blockElement = blockquoteElement;
128
184
  }
129
185
 
@@ -138,39 +194,66 @@ export const input = (vditor: IVditor, range: Range, ignoreSpace = false, event?
138
194
  // 如果为列表的话,需要把上下的列表都重绘
139
195
  const listPrevElement = blockElement.previousElementSibling;
140
196
  const listNextElement = blockElement.nextElementSibling;
141
- if (listPrevElement && (listPrevElement.tagName === "UL" || listPrevElement.tagName === "OL")) {
197
+ if (
198
+ listPrevElement &&
199
+ (listPrevElement.tagName === "UL" ||
200
+ listPrevElement.tagName === "OL")
201
+ ) {
142
202
  html = listPrevElement.outerHTML + html;
143
203
  listPrevElement.remove();
144
204
  }
145
- if (listNextElement && (listNextElement.tagName === "UL" || listNextElement.tagName === "OL")) {
205
+ if (
206
+ listNextElement &&
207
+ (listNextElement.tagName === "UL" ||
208
+ listNextElement.tagName === "OL")
209
+ ) {
146
210
  html = html + listNextElement.outerHTML;
147
211
  listNextElement.remove();
148
212
  }
149
213
  // firefox 列表回车不会产生新的 list item https://github.com/Vanessa219/vditor/issues/194
150
- html = html.replace("<div><wbr><br></div>", "<li><p><wbr><br></p></li>");
151
- } else if (blockElement.previousElementSibling &&
152
- blockElement.previousElementSibling.textContent.replace(Constants.ZWSP, "") !== "" &&
153
- event && event.inputType === "insertParagraph") {
214
+ html = html.replace(
215
+ "<div><wbr><br></div>",
216
+ "<li><p><wbr><br></p></li>"
217
+ );
218
+ } else if (
219
+ blockElement.previousElementSibling &&
220
+ blockElement.previousElementSibling.textContent.replace(
221
+ Constants.ZWSP,
222
+ ""
223
+ ) !== "" &&
224
+ event &&
225
+ event.inputType === "insertParagraph"
226
+ ) {
154
227
  // 换行时需要处理上一段落
155
228
  html = blockElement.previousElementSibling.outerHTML + html;
156
229
  blockElement.previousElementSibling.remove();
157
230
  }
158
231
  if (!blockElement.innerText.startsWith("```")) {
159
232
  // 添加链接引用
160
- vditor.ir.element.querySelectorAll("[data-type='link-ref-defs-block']").forEach((item) => {
161
- if (item && !(blockElement as HTMLElement).isEqualNode(item)) {
162
- html += item.outerHTML;
163
- item.remove();
164
- }
165
- });
233
+ vditor.ir.element
234
+ .querySelectorAll("[data-type='link-ref-defs-block']")
235
+ .forEach((item) => {
236
+ if (
237
+ item &&
238
+ !(blockElement as HTMLElement).isEqualNode(item)
239
+ ) {
240
+ html += item.outerHTML;
241
+ item.remove();
242
+ }
243
+ });
166
244
 
167
245
  // 添加脚注
168
- vditor.ir.element.querySelectorAll("[data-type='footnotes-block']").forEach((item) => {
169
- if (item && !(blockElement as HTMLElement).isEqualNode(item)) {
170
- html += item.outerHTML;
171
- item.remove();
172
- }
173
- });
246
+ vditor.ir.element
247
+ .querySelectorAll("[data-type='footnotes-block']")
248
+ .forEach((item) => {
249
+ if (
250
+ item &&
251
+ !(blockElement as HTMLElement).isEqualNode(item)
252
+ ) {
253
+ html += item.outerHTML;
254
+ item.remove();
255
+ }
256
+ });
174
257
  }
175
258
  } else {
176
259
  html = blockElement.innerHTML;
@@ -187,15 +270,28 @@ export const input = (vditor: IVditor, range: Range, ignoreSpace = false, event?
187
270
 
188
271
  // 更新正文中的 tip
189
272
  if (footnoteElement) {
190
- const footnoteItemElement = hasClosestByAttribute(vditor.ir.element.querySelector("wbr"),
191
- "data-type", "footnotes-def");
273
+ const footnoteItemElement = hasClosestByAttribute(
274
+ vditor.ir.element.querySelector("wbr"),
275
+ "data-type",
276
+ "footnotes-def"
277
+ );
192
278
  if (footnoteItemElement) {
193
279
  const footnoteItemText = footnoteItemElement.textContent;
194
- const marker = footnoteItemText.substring(1, footnoteItemText.indexOf("]:"));
195
- const footnoteRefElement = vditor.ir.element.querySelector(`sup[data-type="footnotes-ref"][data-footnotes-label="${marker}"]`);
280
+ const marker = footnoteItemText.substring(
281
+ 1,
282
+ footnoteItemText.indexOf("]:")
283
+ );
284
+ const footnoteRefElement = vditor.ir.element.querySelector(
285
+ `sup[data-type="footnotes-ref"][data-footnotes-label="${marker}"]`
286
+ );
196
287
  if (footnoteRefElement) {
197
- footnoteRefElement.setAttribute("aria-label",
198
- footnoteItemText.substr(marker.length + 3).trim().substr(0, 24));
288
+ footnoteRefElement.setAttribute(
289
+ "aria-label",
290
+ footnoteItemText
291
+ .substr(marker.length + 3)
292
+ .trim()
293
+ .substr(0, 24)
294
+ );
199
295
  }
200
296
  }
201
297
  }
@@ -203,39 +299,57 @@ export const input = (vditor: IVditor, range: Range, ignoreSpace = false, event?
203
299
 
204
300
  // linkref 合并及添加
205
301
  let firstLinkRefDefElement: HTMLElement;
206
- const allLinkRefDefsElement = vditor.ir.element.querySelectorAll("[data-type='link-ref-defs-block']");
302
+ const allLinkRefDefsElement = vditor.ir.element.querySelectorAll(
303
+ "[data-type='link-ref-defs-block']"
304
+ );
207
305
  allLinkRefDefsElement.forEach((item: HTMLElement, index) => {
208
306
  if (index === 0) {
209
307
  firstLinkRefDefElement = item;
210
308
  } else {
211
- firstLinkRefDefElement.insertAdjacentHTML("beforeend", item.innerHTML);
309
+ firstLinkRefDefElement.insertAdjacentHTML(
310
+ "beforeend",
311
+ item.innerHTML
312
+ );
212
313
  item.remove();
213
314
  }
214
315
  });
215
316
  if (allLinkRefDefsElement.length > 0) {
216
- vditor.ir.element.insertAdjacentElement("beforeend", allLinkRefDefsElement[0]);
317
+ vditor.ir.element.insertAdjacentElement(
318
+ "beforeend",
319
+ allLinkRefDefsElement[0]
320
+ );
217
321
  }
218
322
 
219
323
  // 脚注合并后添加的末尾
220
324
  let firstFootnoteElement: HTMLElement;
221
- const allFootnoteElement = vditor.ir.element.querySelectorAll("[data-type='footnotes-block']");
325
+ const allFootnoteElement = vditor.ir.element.querySelectorAll(
326
+ "[data-type='footnotes-block']"
327
+ );
222
328
  allFootnoteElement.forEach((item: HTMLElement, index) => {
223
329
  if (index === 0) {
224
330
  firstFootnoteElement = item;
225
331
  } else {
226
- firstFootnoteElement.insertAdjacentHTML("beforeend", item.innerHTML);
332
+ firstFootnoteElement.insertAdjacentHTML(
333
+ "beforeend",
334
+ item.innerHTML
335
+ );
227
336
  item.remove();
228
337
  }
229
338
  });
230
339
  if (allFootnoteElement.length > 0) {
231
- vditor.ir.element.insertAdjacentElement("beforeend", allFootnoteElement[0]);
340
+ vditor.ir.element.insertAdjacentElement(
341
+ "beforeend",
342
+ allFootnoteElement[0]
343
+ );
232
344
  }
233
345
 
234
346
  setRangeByWbr(vditor.ir.element, range);
235
347
 
236
- vditor.ir.element.querySelectorAll(".vditor-ir__preview[data-render='2']").forEach((item: HTMLElement) => {
237
- processCodeRender(item, vditor);
238
- });
348
+ vditor.ir.element
349
+ .querySelectorAll(".vditor-ir__preview[data-render='2']")
350
+ .forEach((item: HTMLElement) => {
351
+ processCodeRender(item, vditor);
352
+ });
239
353
 
240
354
  renderToc(vditor);
241
355
 
@@ -17,7 +17,7 @@ import {
17
17
  } from "../util/selection";
18
18
  import { highlightToolbarIR } from "./highlightToolbarIR";
19
19
  import { input } from "./input";
20
- import { attachLineNumbersToBlocks } from "../util/attachLineNumbers";
20
+ import { attachLineNumbersToBlocksThrottled } from "../util/attachLineNumbers";
21
21
 
22
22
  export const processHint = (vditor: IVditor) => {
23
23
  vditor.hint.render(vditor);
@@ -105,7 +105,9 @@ export const processAfterRender = (
105
105
  }
106
106
 
107
107
  try {
108
- attachLineNumbersToBlocks(vditor.ir.element, text);
108
+ if (vditor.options.lineNumber) {
109
+ attachLineNumbersToBlocksThrottled(vditor.ir.element, text);
110
+ }
109
111
  } catch {
110
112
  void 0;
111
113
  }