vditor 3.10.4 → 3.10.6

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.
Files changed (70) hide show
  1. package/README.md +2 -0
  2. package/dist/index.css +27 -1
  3. package/dist/index.d.ts +3 -0
  4. package/dist/index.js +15755 -0
  5. package/dist/index.min.js +1 -1
  6. package/dist/js/echarts/echarts.min.js +24 -2
  7. package/dist/js/icons/material.js +2 -2
  8. package/dist/method.d.ts +2 -3
  9. package/dist/method.js +2589 -0
  10. package/dist/method.min.js +1 -1
  11. package/dist/ts/export/index.d.ts +0 -1
  12. package/dist/ts/ir/expandMarker.d.ts +0 -1
  13. package/dist/ts/ir/highlightToolbarIR.d.ts +0 -1
  14. package/dist/ts/ir/input.d.ts +0 -1
  15. package/dist/ts/ir/process.d.ts +0 -1
  16. package/dist/ts/ir/processKeydown.d.ts +0 -1
  17. package/dist/ts/markdown/codeRender.d.ts +0 -1
  18. package/dist/ts/markdown/getHTML.d.ts +0 -1
  19. package/dist/ts/markdown/getMarkdown.d.ts +0 -1
  20. package/dist/ts/markdown/highlightRender.d.ts +0 -1
  21. package/dist/ts/markdown/mathRender.d.ts +0 -1
  22. package/dist/ts/markdown/outlineRender.d.ts +0 -1
  23. package/dist/ts/markdown/previewRender.d.ts +0 -1
  24. package/dist/ts/markdown/setLute.d.ts +0 -1
  25. package/dist/ts/markdown/speechRender.d.ts +0 -1
  26. package/dist/ts/preview/image.d.ts +0 -1
  27. package/dist/ts/sv/inputEvent.d.ts +0 -1
  28. package/dist/ts/sv/process.d.ts +0 -1
  29. package/dist/ts/sv/processKeydown.d.ts +0 -1
  30. package/dist/ts/toolbar/index.d.ts +1 -0
  31. package/dist/ts/toolbar/setToolbar.d.ts +0 -1
  32. package/dist/ts/ui/initUI.d.ts +0 -6
  33. package/dist/ts/ui/setPreviewMode.d.ts +0 -1
  34. package/dist/ts/ui/setTheme.d.ts +0 -1
  35. package/dist/ts/upload/getElement.d.ts +0 -1
  36. package/dist/ts/upload/index.d.ts +0 -1
  37. package/dist/ts/upload/setHeaders.d.ts +0 -1
  38. package/dist/ts/util/editorCommonEvent.d.ts +0 -1
  39. package/dist/ts/util/fixBrowserBehavior.d.ts +0 -1
  40. package/dist/ts/util/function.d.ts +1 -0
  41. package/dist/ts/util/highlightToolbar.d.ts +0 -1
  42. package/dist/ts/util/processCode.d.ts +0 -1
  43. package/dist/ts/util/selection.d.ts +0 -1
  44. package/dist/ts/util/toc.d.ts +0 -1
  45. package/dist/ts/wysiwyg/afterRenderEvent.d.ts +0 -1
  46. package/dist/ts/wysiwyg/highlightToolbarWYSIWYG.d.ts +0 -1
  47. package/dist/ts/wysiwyg/inlineTag.d.ts +0 -1
  48. package/dist/ts/wysiwyg/input.d.ts +0 -1
  49. package/dist/ts/wysiwyg/processKeydown.d.ts +0 -1
  50. package/dist/ts/wysiwyg/renderDomByMd.d.ts +0 -1
  51. package/dist/ts/wysiwyg/setHeading.d.ts +0 -1
  52. package/dist/ts/wysiwyg/showCode.d.ts +0 -1
  53. package/dist/ts/wysiwyg/toolbarEvent.d.ts +0 -1
  54. package/dist/types/index.d.ts +4 -0
  55. package/package.json +6 -6
  56. package/src/index.ts +27 -3
  57. package/src/ts/devtools/index.ts +1 -1
  58. package/src/ts/ir/input.ts +6 -0
  59. package/src/ts/ir/processKeydown.ts +2 -2
  60. package/src/ts/markdown/chartRender.ts +4 -3
  61. package/src/ts/markdown/mindmapRender.ts +1 -1
  62. package/src/ts/sv/processKeydown.ts +8 -2
  63. package/src/ts/toolbar/Upload.ts +1 -1
  64. package/src/ts/toolbar/index.ts +17 -0
  65. package/src/ts/ui/initUI.ts +0 -6
  66. package/src/ts/util/addScript.ts +3 -3
  67. package/src/ts/util/fixBrowserBehavior.ts +5 -1
  68. package/src/ts/util/function.ts +4 -0
  69. package/src/ts/wysiwyg/index.ts +5 -0
  70. package/src/ts/wysiwyg/input.ts +1 -1
package/src/index.ts CHANGED
@@ -14,7 +14,7 @@ import {Preview} from "./ts/preview/index";
14
14
  import {Resize} from "./ts/resize/index";
15
15
  import {Editor} from "./ts/sv/index";
16
16
  import {inputEvent} from "./ts/sv/inputEvent";
17
- import {processAfterRender as processSVAfterRender} from "./ts/sv/process";
17
+ import {processAfterRender as processSVAfterRender, processPaste} from "./ts/sv/process";
18
18
  import {Tip} from "./ts/tip/index";
19
19
  import {Toolbar} from "./ts/toolbar/index";
20
20
  import {disableToolbar, hidePanel} from "./ts/toolbar/setToolbar";
@@ -30,11 +30,13 @@ import {addScript, addScriptSync} from "./ts/util/addScript";
30
30
  import {getSelectText} from "./ts/util/getSelectText";
31
31
  import {Options} from "./ts/util/Options";
32
32
  import {processCodeRender} from "./ts/util/processCode";
33
- import {getCursorPosition, getEditorRange} from "./ts/util/selection";
33
+ import {getCursorPosition, getEditorRange, insertHTML} from "./ts/util/selection";
34
34
  import {afterRenderEvent} from "./ts/wysiwyg/afterRenderEvent";
35
35
  import {WYSIWYG} from "./ts/wysiwyg/index";
36
36
  import {input} from "./ts/wysiwyg/input";
37
37
  import {renderDomByMd} from "./ts/wysiwyg/renderDomByMd";
38
+ import {execAfterRender} from "./ts/util/fixBrowserBehavior";
39
+ import {accessLocalStorage} from "./ts/util/compatibility";
38
40
 
39
41
  class Vditor extends VditorMethod {
40
42
  public readonly version: string;
@@ -102,6 +104,10 @@ class Vditor extends VditorMethod {
102
104
  tip.show(error, 0)
103
105
  }
104
106
 
107
+ public updateToolbarConfig(options: IToolbarConfig) {
108
+ this.vditor.toolbar.updateConfig(this.vditor, options);
109
+ }
110
+
105
111
  /** 设置主题 */
106
112
  public setTheme(
107
113
  theme: "dark" | "classic",
@@ -204,7 +210,9 @@ class Vditor extends VditorMethod {
204
210
 
205
211
  /** 清除缓存 */
206
212
  public clearCache() {
207
- localStorage.removeItem(this.vditor.options.cache.id);
213
+ if (this.vditor.options.cache.enable && accessLocalStorage()) {
214
+ localStorage.removeItem(this.vditor.options.cache.id);
215
+ }
208
216
  }
209
217
 
210
218
  /** 禁用缓存 */
@@ -264,6 +272,8 @@ class Vditor extends VditorMethod {
264
272
  public insertValue(value: string, render = true) {
265
273
  const range = getEditorRange(this.vditor);
266
274
  range.collapse(true);
275
+ // https://github.com/Vanessa219/vditor/issues/716
276
+ // https://github.com/Vanessa219/vditor/issues/917
267
277
  const tmpElement = document.createElement("template");
268
278
  tmpElement.innerHTML = value;
269
279
  range.insertNode(tmpElement.content.cloneNode(true));
@@ -286,6 +296,20 @@ class Vditor extends VditorMethod {
286
296
  }
287
297
  }
288
298
 
299
+ /** 在焦点处插入 Markdown */
300
+ public insertMD(md: string) {
301
+ // https://github.com/Vanessa219/vditor/issues/1640
302
+ if (this.vditor.currentMode === "ir") {
303
+ insertHTML(this.vditor.lute.Md2VditorIRDOM(md), this.vditor);
304
+ } else if (this.vditor.currentMode === "wysiwyg") {
305
+ insertHTML(this.vditor.lute.Md2VditorDOM(md), this.vditor);
306
+ } else {
307
+ processPaste(this.vditor, md);
308
+ }
309
+ this.vditor.outline.render(this.vditor);
310
+ execAfterRender(this.vditor);
311
+ }
312
+
289
313
  /** 设置编辑器内容 */
290
314
  public setValue(markdown: string, clearStack = false) {
291
315
  if (this.vditor.currentMode === "sv") {
@@ -20,7 +20,7 @@ export class DevTools {
20
20
  return;
21
21
  }
22
22
 
23
- addScript(`${vditor.options.cdn}/dist/js/echarts/echarts.min.js`, "vditorEchartsScript").then(() => {
23
+ addScript(`${vditor.options.cdn}/dist/js/echarts/echarts.min.js?v=5.5.1`, "vditorEchartsScript").then(() => {
24
24
  if (!this.ASTChart) {
25
25
  this.ASTChart = echarts.init(vditor.devtools.element.lastElementChild as HTMLDivElement);
26
26
  }
@@ -57,6 +57,12 @@ export const input = (vditor: IVditor, range: Range, ignoreSpace = false, event?
57
57
  }
58
58
  return;
59
59
  }
60
+
61
+ // https://github.com/Vanessa219/vditor/issues/729
62
+ if (endSpace && /^#{1,6} $/.test(blockElement.textContent)) {
63
+ endSpace = false;
64
+ }
65
+
60
66
  if (endSpace) {
61
67
  const markerElement = hasClosestByClassName(range.startContainer, "vditor-ir__marker");
62
68
  if (markerElement) {
@@ -92,7 +92,7 @@ export const processKeydown = (vditor: IVditor, event: KeyboardEvent) => {
92
92
  }
93
93
  // 数学公式上无元素,按上或左将添加新块
94
94
  if ((codeRenderElement.getAttribute("data-type") === "math-block"
95
- || codeRenderElement.getAttribute("data-type") === "html-block") &&
95
+ || codeRenderElement.getAttribute("data-type") === "html-block") &&
96
96
  insertBeforeBlock(vditor, event, range, codeRenderElement, preRenderElement.parentElement)) {
97
97
  return true;
98
98
  }
@@ -208,7 +208,7 @@ export const processKeydown = (vditor: IVditor, event: KeyboardEvent) => {
208
208
  // 光标位于标题前,marker 后
209
209
  if (headingElement) {
210
210
  const headingLength = headingElement.firstElementChild.textContent.length;
211
- if (getSelectPosition(headingElement, vditor.ir.element).start === headingLength) {
211
+ if (getSelectPosition(headingElement, vditor.ir.element).start === headingLength && headingLength !== 0) {
212
212
  range.setStart(headingElement.firstElementChild.firstChild, headingLength - 1);
213
213
  range.collapse(true);
214
214
  setSelectionFocus(range);
@@ -1,6 +1,7 @@
1
1
  import {Constants} from "../constants";
2
2
  import {addScript} from "../util/addScript";
3
3
  import {chartRenderAdapter} from "./adapterRender";
4
+ import {looseJsonParse} from "../util/function";
4
5
 
5
6
  declare const echarts: {
6
7
  init(element: HTMLElement, theme?: string): IEChart;
@@ -9,8 +10,8 @@ declare const echarts: {
9
10
  export const chartRender = (element: (HTMLElement | Document) = document, cdn = Constants.CDN, theme: string) => {
10
11
  const echartsElements = chartRenderAdapter.getElements(element);
11
12
  if (echartsElements.length > 0) {
12
- addScript(`${cdn}/dist/js/echarts/echarts.min.js`, "vditorEchartsScript").then(() => {
13
- echartsElements.forEach((e: HTMLDivElement) => {
13
+ addScript(`${cdn}/dist/js/echarts/echarts.min.js?v=5.5.1`, "vditorEchartsScript").then(() => {
14
+ echartsElements.forEach(async (e: HTMLDivElement) => {
14
15
  if (e.parentElement.classList.contains("vditor-wysiwyg__pre") ||
15
16
  e.parentElement.classList.contains("vditor-ir__marker--pre")) {
16
17
  return;
@@ -24,7 +25,7 @@ export const chartRender = (element: (HTMLElement | Document) = document, cdn =
24
25
  if (e.getAttribute("data-processed") === "true") {
25
26
  return;
26
27
  }
27
- const option = JSON.parse(text);
28
+ const option = await looseJsonParse(text);
28
29
  echarts.init(e, theme === "dark" ? "dark" : undefined).setOption(option);
29
30
  e.setAttribute("data-processed", "true");
30
31
  } catch (error) {
@@ -9,7 +9,7 @@ declare const echarts: {
9
9
  export const mindmapRender = (element: (HTMLElement | Document) = document, cdn = Constants.CDN, theme: string) => {
10
10
  const mindmapElements = mindmapRenderAdapter.getElements(element);
11
11
  if (mindmapElements.length > 0) {
12
- addScript(`${cdn}/dist/js/echarts/echarts.min.js`, "vditorEchartsScript").then(() => {
12
+ addScript(`${cdn}/dist/js/echarts/echarts.min.js?v=5.5.1`, "vditorEchartsScript").then(() => {
13
13
  mindmapElements.forEach((e: HTMLDivElement) => {
14
14
  if (e.parentElement.classList.contains("vditor-wysiwyg__pre") ||
15
15
  e.parentElement.classList.contains("vditor-ir__marker--pre")) {
@@ -95,8 +95,14 @@ export const processKeydown = (vditor: IVditor, event: KeyboardEvent) => {
95
95
  }
96
96
  // 第一个 marker 后 tab 进行缩进
97
97
  if (event.key === "Tab") {
98
- listFirstMarkerElement.insertAdjacentHTML("beforebegin",
99
- `<span data-type="padding">${listFirstMarkerElement.textContent.replace(/\S/g, " ")}</span>`);
98
+ if (event.shiftKey) {
99
+ if (listFirstMarkerElement.previousElementSibling.getAttribute("data-type") === "padding") {
100
+ listFirstMarkerElement.previousElementSibling.remove();
101
+ }
102
+ } else {
103
+ listFirstMarkerElement.insertAdjacentHTML("beforebegin",
104
+ `<span data-type="padding">${listFirstMarkerElement.textContent.replace(/\S/g, " ")}</span>`);
105
+ }
100
106
  if (/^\d/.test(listFirstMarkerElement.textContent)) {
101
107
  listFirstMarkerElement.textContent = listFirstMarkerElement.textContent.replace(/^\d{1,}/, "1");
102
108
  range.selectNodeContents(listLastMarkerElement.firstChild);
@@ -1,5 +1,5 @@
1
1
  import {Constants} from "../constants";
2
- import {uploadFiles} from "../upload";
2
+ import {uploadFiles} from "../upload/index";
3
3
  import {getEventName} from "../util/compatibility";
4
4
  import {MenuItem} from "./MenuItem";
5
5
 
@@ -69,6 +69,23 @@ export class Toolbar {
69
69
  }
70
70
  }
71
71
 
72
+ public updateConfig(vditor: IVditor, options: IToolbarConfig) {
73
+ vditor.options.toolbarConfig = Object.assign({
74
+ hide: false,
75
+ pin: false,
76
+ }, options);
77
+ if (vditor.options.toolbarConfig.hide) {
78
+ this.element.classList.add("vditor-toolbar--hide");
79
+ } else {
80
+ this.element.classList.remove("vditor-toolbar--hide");
81
+ }
82
+ if (vditor.options.toolbarConfig.pin) {
83
+ this.element.classList.add("vditor-toolbar--pin");
84
+ } else {
85
+ this.element.classList.remove("vditor-toolbar--pin");
86
+ }
87
+ }
88
+
72
89
  private genItem(vditor: IVditor, menuItem: IMenuItem, index: number) {
73
90
  let menuItemObj;
74
91
  switch (menuItem.name) {
@@ -5,12 +5,6 @@ import {accessLocalStorage} from "../util/compatibility";
5
5
  import {setContentTheme} from "./setContentTheme";
6
6
  import {setTheme} from "./setTheme";
7
7
 
8
- declare global {
9
- interface Window {
10
- visualViewport: HTMLElement;
11
- }
12
- }
13
-
14
8
  export const initUI = (vditor: IVditor) => {
15
9
  vditor.element.innerHTML = "";
16
10
  vditor.element.classList.add("vditor");
@@ -18,7 +18,7 @@ export const addScript = (path: string, id: string) => {
18
18
  return new Promise((resolve, reject) => {
19
19
  if (document.getElementById(id)) {
20
20
  // 脚本加载后再次调用直接返回
21
- resolve();
21
+ resolve(true);
22
22
  return false;
23
23
  }
24
24
  const scriptElement = document.createElement("script");
@@ -33,11 +33,11 @@ export const addScript = (path: string, id: string) => {
33
33
  if (document.getElementById(id)) {
34
34
  // 循环调用需清除 DOM 中的 script 标签
35
35
  scriptElement.remove();
36
- resolve();
36
+ resolve(true);
37
37
  return false;
38
38
  }
39
39
  scriptElement.id = id;
40
- resolve();
40
+ resolve(true);
41
41
  };
42
42
  });
43
43
  };
@@ -1290,6 +1290,10 @@ export const paste = async (vditor: IVditor, event: (ClipboardEvent | DragEvent)
1290
1290
  return ["", Lute.WalkContinue];
1291
1291
  }
1292
1292
 
1293
+ if (vditor.options.upload.renderLinkDest) {
1294
+ return vditor.options.upload.renderLinkDest(vditor, node, entering);
1295
+ }
1296
+
1293
1297
  const src = node.TokensStr();
1294
1298
  if (node.__internal_object__.Parent.Type === 34 && src && src.indexOf("file://") === -1 &&
1295
1299
  vditor.options.upload.linkToImgUrl) {
@@ -1448,7 +1452,7 @@ export const paste = async (vditor: IVditor, event: (ClipboardEvent | DragEvent)
1448
1452
  }
1449
1453
  } else if (textPlain.trim() !== "" && files.length === 0) {
1450
1454
  const range = getEditorRange(vditor);
1451
- if (range.toString() !== "" && vditor.lute.IsValidLinkDest(textPlain)) {
1455
+ if (range.toString() !== "" && vditor.lute.IsValidLinkDest(textPlain)) {
1452
1456
  textPlain = `[${range.toString()}](${textPlain})`;
1453
1457
  }
1454
1458
  if (vditor.currentMode === "ir") {
@@ -9,3 +9,7 @@ export const getSearch = (key: string, link = window.location.search) => {
9
9
  const urlSearchParams = new URLSearchParams(params.substring(0, hashIndex >= 0 ? hashIndex : undefined));
10
10
  return urlSearchParams.get(key);
11
11
  };
12
+
13
+ export const looseJsonParse = (text: string) => {
14
+ return Function(`"use strict";return (${text})`)();
15
+ };
@@ -380,6 +380,11 @@ class WYSIWYG {
380
380
  }
381
381
  }
382
382
 
383
+ // https://github.com/Vanessa219/vditor/issues/729
384
+ if (endSpace && /^#{1,6} $/.test(blockElement.textContent)) {
385
+ endSpace = false;
386
+ }
387
+
383
388
  const headingElement = hasClosestByHeadings(getSelection().getRangeAt(0).startContainer);
384
389
  if (headingElement && headingElement.textContent === "") {
385
390
  // heading 为空删除 https://github.com/Vanessa219/vditor/issues/150
@@ -2,7 +2,7 @@ import {
2
2
  getTopList,
3
3
  hasClosestBlock, hasClosestByAttribute, hasTopClosestByTag,
4
4
  } from "../util/hasClosest";
5
- import { hasClosestByTag} from "../util/hasClosestByHeadings";
5
+ import {hasClosestByTag} from "../util/hasClosestByHeadings";
6
6
  import {log} from "../util/log";
7
7
  import {processCodeRender} from "../util/processCode";
8
8
  import {setRangeByWbr} from "../util/selection";