vditor 3.8.4 → 3.8.8

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 (110) hide show
  1. package/CHANGELOG.md +45 -8
  2. package/README.md +49 -46
  3. package/dist/css/content-theme/ant-design.css +185 -1
  4. package/dist/css/content-theme/dark.css +98 -1
  5. package/dist/css/content-theme/light.css +76 -1
  6. package/dist/css/content-theme/wechat.css +69 -1
  7. package/dist/index.css +10 -8
  8. package/dist/index.d.ts +5 -1
  9. package/dist/index.min.js +15433 -8
  10. package/dist/js/.DS_Store +0 -0
  11. package/dist/js/highlight.js/highlight.pack.js +1617 -2
  12. package/dist/js/highlight.js/styles/abap.css +155 -1
  13. package/dist/js/highlight.js/styles/algol.css +142 -1
  14. package/dist/js/highlight.js/styles/algol_nu.css +90 -1
  15. package/dist/js/highlight.js/styles/ant-design.css +469 -1
  16. package/dist/js/highlight.js/styles/arduino.css +155 -1
  17. package/dist/js/highlight.js/styles/autumn.css +136 -1
  18. package/dist/js/highlight.js/styles/borland.css +146 -1
  19. package/dist/js/highlight.js/styles/bw.css +149 -1
  20. package/dist/js/highlight.js/styles/colorful.css +156 -1
  21. package/dist/js/highlight.js/styles/dracula.css +139 -1
  22. package/dist/js/highlight.js/styles/emacs.css +166 -1
  23. package/dist/js/highlight.js/styles/friendly.css +182 -1
  24. package/dist/js/highlight.js/styles/fruity.css +121 -1
  25. package/dist/js/highlight.js/styles/github.css +173 -1
  26. package/dist/js/highlight.js/styles/igor.css +122 -1
  27. package/dist/js/highlight.js/styles/lovelace.css +145 -1
  28. package/dist/js/highlight.js/styles/manni.css +138 -1
  29. package/dist/js/highlight.js/styles/monokai.css +131 -1
  30. package/dist/js/highlight.js/styles/monokailight.css +179 -1
  31. package/dist/js/highlight.js/styles/murphy.css +144 -1
  32. package/dist/js/highlight.js/styles/native.css +163 -1
  33. package/dist/js/highlight.js/styles/paraiso-dark.css +136 -1
  34. package/dist/js/highlight.js/styles/paraiso-light.css +135 -1
  35. package/dist/js/highlight.js/styles/pastie.css +180 -1
  36. package/dist/js/highlight.js/styles/perldoc.css +140 -1
  37. package/dist/js/highlight.js/styles/pygments.css +158 -1
  38. package/dist/js/highlight.js/styles/rainbow_dash.css +163 -1
  39. package/dist/js/highlight.js/styles/rrt.css +158 -1
  40. package/dist/js/highlight.js/styles/solarized-dark.css +145 -1
  41. package/dist/js/highlight.js/styles/solarized-dark256.css +145 -1
  42. package/dist/js/highlight.js/styles/solarized-light.css +162 -1
  43. package/dist/js/highlight.js/styles/swapoff.css +144 -1
  44. package/dist/js/highlight.js/styles/tango.css +183 -1
  45. package/dist/js/highlight.js/styles/trac.css +166 -1
  46. package/dist/js/highlight.js/styles/vim.css +143 -1
  47. package/dist/js/highlight.js/styles/vs.css +112 -1
  48. package/dist/js/highlight.js/styles/xcode.css +173 -1
  49. package/dist/js/i18n/en_US.js +85 -0
  50. package/dist/js/i18n/ja_JP.js +85 -0
  51. package/dist/js/i18n/ko_KR.js +85 -0
  52. package/dist/js/i18n/ru_RU.js +85 -0
  53. package/dist/js/i18n/zh_CN.js +85 -0
  54. package/dist/js/i18n/zh_TW.js +85 -0
  55. package/dist/js/katex/katex.min.css +1 -1
  56. package/dist/js/lute/lute.min.js +31 -28
  57. package/dist/js/mathjax/.DS_Store +0 -0
  58. package/dist/js/mathjax/input/tex/extensions/{colorv2.js → colorV2.js} +0 -0
  59. package/dist/js/mathjax/input/tex/extensions/{configmacros.js → configMacros.js} +0 -0
  60. package/dist/js/mathjax/input/tex/extensions/{tagformat.js → tagFormat.js} +0 -0
  61. package/dist/js/mathjax/tex-svg-full.js +1 -0
  62. package/dist/method.d.ts +6 -3
  63. package/dist/method.min.js +2334 -8
  64. package/dist/ts/markdown/adapterRender.d.ts +33 -0
  65. package/dist/ts/markdown/codeRender.d.ts +1 -2
  66. package/dist/ts/ui/initUI.d.ts +1 -0
  67. package/dist/ts/wysiwyg/index.d.ts +2 -0
  68. package/dist/types/index.d.ts +105 -8
  69. package/package.json +23 -24
  70. package/src/assets/.DS_Store +0 -0
  71. package/src/assets/scss/_content.scss +4 -0
  72. package/src/assets/scss/_reset.scss +11 -0
  73. package/src/index.ts +159 -99
  74. package/src/method.ts +6 -2
  75. package/src/ts/.DS_Store +0 -0
  76. package/src/ts/constants.ts +8 -4
  77. package/src/ts/export/index.ts +7 -5
  78. package/src/ts/hint/index.ts +20 -11
  79. package/src/ts/markdown/abcRender.ts +3 -2
  80. package/src/ts/markdown/adapterRender.ts +33 -0
  81. package/src/ts/markdown/chartRender.ts +3 -2
  82. package/src/ts/markdown/codeRender.ts +5 -6
  83. package/src/ts/markdown/flowchartRender.ts +3 -2
  84. package/src/ts/markdown/graphvizRender.ts +13 -11
  85. package/src/ts/markdown/highlightRender.ts +3 -3
  86. package/src/ts/markdown/mathRender.ts +6 -5
  87. package/src/ts/markdown/mermaidRender.ts +4 -2
  88. package/src/ts/markdown/mindmapRender.ts +3 -2
  89. package/src/ts/markdown/plantumlRender.ts +3 -2
  90. package/src/ts/markdown/previewRender.ts +26 -4
  91. package/src/ts/preview/image.ts +2 -4
  92. package/src/ts/preview/index.ts +2 -5
  93. package/src/ts/toolbar/EditMode.ts +3 -4
  94. package/src/ts/toolbar/Headings.ts +6 -6
  95. package/src/ts/toolbar/Info.ts +1 -1
  96. package/src/ts/toolbar/MenuItem.ts +1 -3
  97. package/src/ts/toolbar/Record.ts +3 -4
  98. package/src/ts/ui/initUI.ts +19 -5
  99. package/src/ts/undo/index.ts +5 -5
  100. package/src/ts/upload/index.ts +8 -8
  101. package/src/ts/util/Options.ts +255 -196
  102. package/src/ts/util/editorCommonEvent.ts +2 -2
  103. package/src/ts/util/fixBrowserBehavior.ts +10 -6
  104. package/src/ts/util/processCode.ts +1 -1
  105. package/src/ts/wysiwyg/highlightToolbarWYSIWYG.ts +298 -138
  106. package/src/ts/wysiwyg/index.ts +9 -4
  107. package/dist/js/mathjax/input/.DS_Store +0 -0
  108. package/dist/js/mathjax/tex-svg.js +0 -1
  109. package/dist/ts/i18n/index.d.ts +0 -2
  110. package/src/ts/i18n/index.ts +0 -318
package/src/index.ts CHANGED
@@ -1,43 +1,42 @@
1
+ import "./assets/scss/index.scss";
1
2
  import VditorMethod from "./method";
2
3
  import {Constants, VDITOR_VERSION} from "./ts/constants";
3
- import {DevTools} from "./ts/devtools";
4
+ import {DevTools} from "./ts/devtools/index";
4
5
  import {Hint} from "./ts/hint/index";
5
- import {i18n} from "./ts/i18n";
6
- import {IR} from "./ts/ir";
6
+ import {IR} from "./ts/ir/index";
7
7
  import {input as irInput} from "./ts/ir/input";
8
8
  import {processAfterRender} from "./ts/ir/process";
9
9
  import {getHTML} from "./ts/markdown/getHTML";
10
10
  import {getMarkdown} from "./ts/markdown/getMarkdown";
11
11
  import {setLute} from "./ts/markdown/setLute";
12
- import {Outline} from "./ts/outline";
12
+ import {Outline} from "./ts/outline/index";
13
13
  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
17
  import {processAfterRender as processSVAfterRender} from "./ts/sv/process";
18
- import {Tip} from "./ts/tip";
18
+ import {Tip} from "./ts/tip/index";
19
19
  import {Toolbar} from "./ts/toolbar/index";
20
20
  import {disableToolbar, hidePanel} from "./ts/toolbar/setToolbar";
21
21
  import {enableToolbar} from "./ts/toolbar/setToolbar";
22
- import {initUI} from "./ts/ui/initUI";
22
+ import {initUI, UIUnbindListener} from "./ts/ui/initUI";
23
23
  import {setCodeTheme} from "./ts/ui/setCodeTheme";
24
24
  import {setContentTheme} from "./ts/ui/setContentTheme";
25
25
  import {setPreviewMode} from "./ts/ui/setPreviewMode";
26
26
  import {setTheme} from "./ts/ui/setTheme";
27
- import {Undo} from "./ts/undo";
27
+ import {Undo} from "./ts/undo/index";
28
28
  import {Upload} from "./ts/upload/index";
29
29
  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
33
  import {getCursorPosition, getEditorRange} from "./ts/util/selection";
34
- import {WYSIWYG} from "./ts/wysiwyg";
35
34
  import {afterRenderEvent} from "./ts/wysiwyg/afterRenderEvent";
35
+ import {WYSIWYG} from "./ts/wysiwyg/index";
36
36
  import {input} from "./ts/wysiwyg/input";
37
37
  import {renderDomByMd} from "./ts/wysiwyg/renderDomByMd";
38
38
 
39
39
  class Vditor extends VditorMethod {
40
-
41
40
  public readonly version: string;
42
41
  public vditor: IVditor;
43
42
 
@@ -67,76 +66,37 @@ class Vditor extends VditorMethod {
67
66
  const getOptions = new Options(options);
68
67
  const mergedOptions = getOptions.merge();
69
68
 
70
- if (!["en_US", "ja_JP", "ko_KR", "zh_CN"].includes(mergedOptions.lang)) {
71
- throw new Error("options.lang error, see https://ld246.com/article/1549638745630#options");
72
- }
73
-
74
- this.vditor = {
75
- currentMode: mergedOptions.mode,
76
- element: id,
77
- hint: new Hint(mergedOptions.hint.extend),
78
- lute: undefined,
79
- options: mergedOptions,
80
- originalInnerHTML: id.innerHTML,
81
- outline: new Outline(i18n[mergedOptions.lang].outline),
82
- tip: new Tip(),
83
- };
84
-
85
- this.vditor.sv = new Editor(this.vditor);
86
- this.vditor.undo = new Undo();
87
- this.vditor.wysiwyg = new WYSIWYG(this.vditor);
88
- this.vditor.ir = new IR(this.vditor);
89
- this.vditor.toolbar = new Toolbar(this.vditor);
90
-
91
- if (mergedOptions.resize.enable) {
92
- this.vditor.resize = new Resize(this.vditor);
93
- }
94
-
95
- if (this.vditor.toolbar.elements.devtools) {
96
- this.vditor.devtools = new DevTools();
97
- }
98
-
99
- if (mergedOptions.upload.url || mergedOptions.upload.handler) {
100
- this.vditor.upload = new Upload();
101
- }
102
-
103
- addScript(options._lutePath || `${mergedOptions.cdn}/dist/js/lute/lute.min.js`, "vditorLuteScript")
104
- .then(() => {
105
- this.vditor.lute = setLute({
106
- autoSpace: this.vditor.options.preview.markdown.autoSpace,
107
- codeBlockPreview: this.vditor.options.preview.markdown.codeBlockPreview,
108
- emojiSite: this.vditor.options.hint.emojiPath,
109
- emojis: this.vditor.options.hint.emoji,
110
- fixTermTypo: this.vditor.options.preview.markdown.fixTermTypo,
111
- footnotes: this.vditor.options.preview.markdown.footnotes,
112
- headingAnchor: false,
113
- inlineMathDigit: this.vditor.options.preview.math.inlineDigit,
114
- linkBase: this.vditor.options.preview.markdown.linkBase,
115
- linkPrefix: this.vditor.options.preview.markdown.linkPrefix,
116
- listStyle: this.vditor.options.preview.markdown.listStyle,
117
- mark: this.vditor.options.preview.markdown.mark,
118
- mathBlockPreview: this.vditor.options.preview.markdown.mathBlockPreview,
119
- paragraphBeginningSpace: this.vditor.options.preview.markdown.paragraphBeginningSpace,
120
- sanitize: this.vditor.options.preview.markdown.sanitize,
121
- toc: this.vditor.options.preview.markdown.toc,
69
+ // 支持自定义国际化
70
+ if (!mergedOptions.i18n) {
71
+ if (!["en_US", "ja_JP", "ko_KR", "ru_RU", "zh_CN", "zh_TW"].includes(mergedOptions.lang)) {
72
+ throw new Error(
73
+ "options.lang error, see https://ld246.com/article/1549638745630#options",
74
+ );
75
+ } else {
76
+ const i18nScriptPrefix = "vditorI18nScript";
77
+ const i18nScriptID = i18nScriptPrefix + mergedOptions.lang;
78
+ document.querySelectorAll(`head script[id^="${i18nScriptPrefix}"]`).forEach((el) => {
79
+ if (el.id !== i18nScriptID) {
80
+ document.head.removeChild(el);
81
+ }
122
82
  });
123
-
124
- this.vditor.preview = new Preview(this.vditor);
125
-
126
- initUI(this.vditor);
127
-
128
- if (mergedOptions.after) {
129
- mergedOptions.after();
130
- }
131
- if (mergedOptions.icon) {
132
- // 防止初始化 2 个编辑器时加载 2 次
133
- addScriptSync(`${mergedOptions.cdn}/dist/js/icons/${mergedOptions.icon}.js`, "vditorIconScript");
134
- }
135
- });
83
+ addScript(`${mergedOptions.cdn}/dist/js/i18n/${mergedOptions.lang}.js`, i18nScriptID).then(() => {
84
+ this.init(id as HTMLElement, mergedOptions);
85
+ });
86
+ }
87
+ } else {
88
+ window.VditorI18n = mergedOptions.i18n;
89
+ this.init(id, mergedOptions);
90
+ }
136
91
  }
137
92
 
138
93
  /** 设置主题 */
139
- public setTheme(theme: "dark" | "classic", contentTheme?: string, codeTheme?: string, contentThemePath?: string) {
94
+ public setTheme(
95
+ theme: "dark" | "classic",
96
+ contentTheme?: string,
97
+ codeTheme?: string,
98
+ contentThemePath?: string,
99
+ ) {
140
100
  this.vditor.options.theme = theme;
141
101
  setTheme(this.vditor);
142
102
  if (contentTheme) {
@@ -184,15 +144,22 @@ class Vditor extends VditorMethod {
184
144
  /** 禁用编辑器 */
185
145
  public disabled() {
186
146
  hidePanel(this.vditor, ["subToolbar", "hint", "popover"]);
187
- disableToolbar(this.vditor.toolbar.elements, Constants.EDIT_TOOLBARS.concat(["undo", "redo", "fullscreen",
188
- "edit-mode"]));
189
- this.vditor[this.vditor.currentMode].element.setAttribute("contenteditable", "false");
147
+ disableToolbar(
148
+ this.vditor.toolbar.elements,
149
+ Constants.EDIT_TOOLBARS.concat(["undo", "redo", "fullscreen", "edit-mode"]),
150
+ );
151
+ this.vditor[this.vditor.currentMode].element.setAttribute(
152
+ "contenteditable",
153
+ "false",
154
+ );
190
155
  }
191
156
 
192
157
  /** 解除编辑器禁用 */
193
158
  public enable() {
194
- enableToolbar(this.vditor.toolbar.elements, Constants.EDIT_TOOLBARS.concat(["undo", "redo", "fullscreen",
195
- "edit-mode"]));
159
+ enableToolbar(
160
+ this.vditor.toolbar.elements,
161
+ Constants.EDIT_TOOLBARS.concat(["undo", "redo", "fullscreen", "edit-mode"]),
162
+ );
196
163
  this.vditor.undo.resetIcon(this.vditor);
197
164
  this.vditor[this.vditor.currentMode].element.setAttribute("contenteditable", "true");
198
165
  }
@@ -236,8 +203,9 @@ class Vditor extends VditorMethod {
236
203
  /** 启用缓存 */
237
204
  public enableCache() {
238
205
  if (!this.vditor.options.cache.id) {
239
- throw new Error("need options.cache.id, see https://ld246.com/article/1549638745630#options");
240
- return;
206
+ throw new Error(
207
+ "need options.cache.id, see https://ld246.com/article/1549638745630#options",
208
+ );
241
209
  }
242
210
  this.vditor.options.cache.enable = true;
243
211
  }
@@ -247,6 +215,11 @@ class Vditor extends VditorMethod {
247
215
  return this.vditor.lute.HTML2Md(value);
248
216
  }
249
217
 
218
+ /** markdown 转 JSON 输出 */
219
+ public exportJSON(value: string) {
220
+ return this.vditor.lute.RenderJSON(value);
221
+ }
222
+
250
223
  /** 获取 HTML */
251
224
  public getHTML() {
252
225
  return getHTML(this.vditor);
@@ -317,8 +290,9 @@ class Vditor extends VditorMethod {
317
290
  });
318
291
  } else {
319
292
  this.vditor.ir.element.innerHTML = this.vditor.lute.Md2VditorIRDOM(markdown);
320
- this.vditor.ir.element.querySelectorAll(".vditor-ir__preview[data-render='2']").forEach(
321
- (item: HTMLElement) => {
293
+ this.vditor.ir.element
294
+ .querySelectorAll(".vditor-ir__preview[data-render='2']")
295
+ .forEach((item: HTMLElement) => {
322
296
  processCodeRender(item, this.vditor);
323
297
  });
324
298
  processAfterRender(this.vditor, {
@@ -355,6 +329,9 @@ class Vditor extends VditorMethod {
355
329
  this.vditor.element.removeAttribute("style");
356
330
  document.getElementById("vditorIconScript").remove();
357
331
  this.clearCache();
332
+
333
+ UIUnbindListener();
334
+ this.vditor.wysiwyg.unbindListener();
358
335
  }
359
336
 
360
337
  /** 获取评论 ID */
@@ -378,13 +355,17 @@ class Vditor extends VditorMethod {
378
355
  }
379
356
  });
380
357
  };
381
- this.vditor.wysiwyg.element.querySelectorAll(".vditor-comment").forEach((item) => {
382
- hlItem(item);
383
- });
384
- if (this.vditor.preview.element.style.display !== "none") {
385
- this.vditor.preview.element.querySelectorAll(".vditor-comment").forEach((item) => {
358
+ this.vditor.wysiwyg.element
359
+ .querySelectorAll(".vditor-comment")
360
+ .forEach((item) => {
386
361
  hlItem(item);
387
362
  });
363
+ if (this.vditor.preview.element.style.display !== "none") {
364
+ this.vditor.preview.element
365
+ .querySelectorAll(".vditor-comment")
366
+ .forEach((item) => {
367
+ hlItem(item);
368
+ });
388
369
  }
389
370
  }
390
371
 
@@ -400,13 +381,17 @@ class Vditor extends VditorMethod {
400
381
  }
401
382
  });
402
383
  };
403
- this.vditor.wysiwyg.element.querySelectorAll(".vditor-comment").forEach((item) => {
404
- unHlItem(item);
405
- });
406
- if (this.vditor.preview.element.style.display !== "none") {
407
- this.vditor.preview.element.querySelectorAll(".vditor-comment").forEach((item) => {
384
+ this.vditor.wysiwyg.element
385
+ .querySelectorAll(".vditor-comment")
386
+ .forEach((item) => {
408
387
  unHlItem(item);
409
388
  });
389
+ if (this.vditor.preview.element.style.display !== "none") {
390
+ this.vditor.preview.element
391
+ .querySelectorAll(".vditor-comment")
392
+ .forEach((item) => {
393
+ unHlItem(item);
394
+ });
410
395
  }
411
396
  }
412
397
 
@@ -432,13 +417,17 @@ class Vditor extends VditorMethod {
432
417
  }
433
418
  };
434
419
  removeIds.forEach((removeId) => {
435
- this.vditor.wysiwyg.element.querySelectorAll(".vditor-comment").forEach((item) => {
436
- removeItem(item, removeId);
437
- });
438
- if (this.vditor.preview.element.style.display !== "none") {
439
- this.vditor.preview.element.querySelectorAll(".vditor-comment").forEach((item) => {
420
+ this.vditor.wysiwyg.element
421
+ .querySelectorAll(".vditor-comment")
422
+ .forEach((item) => {
440
423
  removeItem(item, removeId);
441
424
  });
425
+ if (this.vditor.preview.element.style.display !== "none") {
426
+ this.vditor.preview.element
427
+ .querySelectorAll(".vditor-comment")
428
+ .forEach((item) => {
429
+ removeItem(item, removeId);
430
+ });
442
431
  }
443
432
  });
444
433
  afterRenderEvent(this.vditor, {
@@ -447,6 +436,77 @@ class Vditor extends VditorMethod {
447
436
  enableInput: false,
448
437
  });
449
438
  }
439
+
440
+ private init(id: HTMLElement, mergedOptions: IOptions) {
441
+ this.vditor = {
442
+ currentMode: mergedOptions.mode,
443
+ element: id,
444
+ hint: new Hint(mergedOptions.hint.extend),
445
+ lute: undefined,
446
+ options: mergedOptions,
447
+ originalInnerHTML: id.innerHTML,
448
+ outline: new Outline(window.VditorI18n.outline),
449
+ tip: new Tip(),
450
+ };
451
+
452
+ this.vditor.sv = new Editor(this.vditor);
453
+ this.vditor.undo = new Undo();
454
+ this.vditor.wysiwyg = new WYSIWYG(this.vditor);
455
+ this.vditor.ir = new IR(this.vditor);
456
+ this.vditor.toolbar = new Toolbar(this.vditor);
457
+
458
+ if (mergedOptions.resize.enable) {
459
+ this.vditor.resize = new Resize(this.vditor);
460
+ }
461
+
462
+ if (this.vditor.toolbar.elements.devtools) {
463
+ this.vditor.devtools = new DevTools();
464
+ }
465
+
466
+ if (mergedOptions.upload.url || mergedOptions.upload.handler) {
467
+ this.vditor.upload = new Upload();
468
+ }
469
+
470
+ addScript(
471
+ mergedOptions._lutePath ||
472
+ `${mergedOptions.cdn}/dist/js/lute/lute.min.js`,
473
+ "vditorLuteScript",
474
+ ).then(() => {
475
+ this.vditor.lute = setLute({
476
+ autoSpace: this.vditor.options.preview.markdown.autoSpace,
477
+ codeBlockPreview: this.vditor.options.preview.markdown
478
+ .codeBlockPreview,
479
+ emojiSite: this.vditor.options.hint.emojiPath,
480
+ emojis: this.vditor.options.hint.emoji,
481
+ fixTermTypo: this.vditor.options.preview.markdown.fixTermTypo,
482
+ footnotes: this.vditor.options.preview.markdown.footnotes,
483
+ headingAnchor: false,
484
+ inlineMathDigit: this.vditor.options.preview.math.inlineDigit,
485
+ linkBase: this.vditor.options.preview.markdown.linkBase,
486
+ linkPrefix: this.vditor.options.preview.markdown.linkPrefix,
487
+ listStyle: this.vditor.options.preview.markdown.listStyle,
488
+ mark: this.vditor.options.preview.markdown.mark,
489
+ mathBlockPreview: this.vditor.options.preview.markdown
490
+ .mathBlockPreview,
491
+ paragraphBeginningSpace: this.vditor.options.preview.markdown
492
+ .paragraphBeginningSpace,
493
+ sanitize: this.vditor.options.preview.markdown.sanitize,
494
+ toc: this.vditor.options.preview.markdown.toc,
495
+ });
496
+
497
+ this.vditor.preview = new Preview(this.vditor);
498
+
499
+ initUI(this.vditor);
500
+
501
+ if (mergedOptions.after) {
502
+ mergedOptions.after();
503
+ }
504
+ if (mergedOptions.icon) {
505
+ // 防止初始化 2 个编辑器时加载 2 次
506
+ addScriptSync(`${mergedOptions.cdn}/dist/js/icons/${mergedOptions.icon}.js`, "vditorIconScript");
507
+ }
508
+ });
509
+ }
450
510
  }
451
511
 
452
512
  export default Vditor;
package/src/method.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import {abcRender} from "./ts/markdown/abcRender";
2
+ import * as adapterRender from "./ts/markdown/adapterRender";
2
3
  import {chartRender} from "./ts/markdown/chartRender";
3
4
  import {codeRender} from "./ts/markdown/codeRender";
4
5
  import {flowchartRender} from "./ts/markdown/flowchartRender";
@@ -13,11 +14,14 @@ import {outlineRender} from "./ts/markdown/outlineRender";
13
14
  import {plantumlRender} from "./ts/markdown/plantumlRender";
14
15
  import {md2html, previewRender} from "./ts/markdown/previewRender";
15
16
  import {speechRender} from "./ts/markdown/speechRender";
16
- import { previewImage } from "./ts/preview/image";
17
- import { setCodeTheme } from "./ts/ui/setCodeTheme";
17
+ import {previewImage} from "./ts/preview/image";
18
+ import {setCodeTheme} from "./ts/ui/setCodeTheme";
18
19
  import {setContentTheme} from "./ts/ui/setContentTheme";
20
+
19
21
  class Vditor {
20
22
 
23
+ /** 点击图片放大 */
24
+ public static adapterRender = adapterRender;
21
25
  /** 点击图片放大 */
22
26
  public static previewImage = previewImage;
23
27
  /** 为 element 中的代码块添加复制按钮 */
package/src/ts/.DS_Store CHANGED
Binary file
@@ -18,10 +18,14 @@ export abstract class Constants {
18
18
  "rainbow_dash", "rrt", "solarized-dark", "solarized-dark256", "solarized-light", "swapoff", "tango", "trac",
19
19
  "vim", "vs", "xcode", "ant-design"];
20
20
  public static readonly CODE_LANGUAGES: string[] = ["mermaid", "echarts", "mindmap", "plantuml", "abc", "graphviz", "flowchart", "apache",
21
- "bash", "cs", "cpp", "css", "coffeescript", "diff", "xml", "http", "ini", "json", "java", "javascript", "js",
22
- "makefile", "markdown", "nginx", "objectivec", "php", "perl", "properties", "python", "ruby", "sql", "shell",
23
- "dart", "erb", "go", "gradle", "julia", "kotlin", "less", "lua", "matlab", "rust", "scss", "typescript", "ts",
24
- "yaml"];
21
+ "js", "ts", "html",
22
+ // common
23
+ "properties", "apache", "bash", "c", "csharp", "cpp", "css", "coffeescript", "diff", "go", "xml", "http",
24
+ "json", "java", "javascript", "kotlin", "less", "lua", "makefile", "markdown", "nginx", "objectivec", "php",
25
+ "php-template", "perl", "plaintext", "python", "python-repl", "r", "ruby", "rust", "scss", "sql", "shell",
26
+ "swift", "ini", "typescript", "vbnet", "yaml",
27
+ "ada", "clojure", "dart", "erb", "fortran", "gradle", "haskell", "julia", "julia-repl", "lisp", "matlab",
28
+ "pgsql", "powershell", "sql_more", "stata", "cmake", "mathematica"];
25
29
  public static readonly CDN = `https://cdn.jsdelivr.net/npm/vditor@${VDITOR_VERSION}`;
26
30
  public static readonly MARKDOWN_OPTIONS = {
27
31
  autoSpace: false,
@@ -1,4 +1,3 @@
1
- import {i18n} from "../i18n";
2
1
  import {getHTML} from "../markdown/getHTML";
3
2
  import {getMarkdown} from "../markdown/getMarkdown";
4
3
 
@@ -13,7 +12,7 @@ export const download = (vditor: IVditor, content: string, filename: string) =>
13
12
  aElement.click();
14
13
  aElement.remove();
15
14
  } else {
16
- vditor.tip.show(i18n[vditor.options.lang].downloadTip, 0);
15
+ vditor.tip.show(window.VditorI18n.downloadTip, 0);
17
16
  }
18
17
  };
19
18
 
@@ -23,7 +22,7 @@ export const exportMarkdown = (vditor: IVditor) => {
23
22
  };
24
23
 
25
24
  export const exportPDF = (vditor: IVditor) => {
26
- vditor.tip.show(i18n[vditor.options.lang].generate, 3800);
25
+ vditor.tip.show(window.VditorI18n.generate, 3800);
27
26
  const iframe = document.querySelector("iframe");
28
27
  iframe.contentDocument.open();
29
28
  iframe.contentDocument.write(`<link rel="stylesheet" href="${vditor.options.cdn}/dist/index.css"/>
@@ -56,12 +55,13 @@ window.addEventListener("message", (e) => {
56
55
  export const exportHTML = (vditor: IVditor) => {
57
56
  const content = getHTML(vditor);
58
57
  const html = `<html><head><link rel="stylesheet" type="text/css" href="${vditor.options.cdn}/dist/index.css"/>
58
+ <script src="${vditor.options.cdn}/dist/js/i18n/${vditor.options.lang}.js"></script>
59
59
  <script src="${vditor.options.cdn}/dist/method.min.js"></script></head>
60
60
  <body><div class="vditor-reset" id="preview">${content}</div>
61
61
  <script>
62
62
  const previewElement = document.getElementById('preview')
63
63
  Vditor.setContentTheme('${vditor.options.preview.theme.current}', '${vditor.options.preview.theme.path}');
64
- Vditor.codeRender(previewElement, '${vditor.options.lang}');
64
+ Vditor.codeRender(previewElement);
65
65
  Vditor.highlightRender(${JSON.stringify(vditor.options.preview.hljs)}, previewElement, '${vditor.options.cdn}');
66
66
  Vditor.mathRender(previewElement, {
67
67
  cdn: '${vditor.options.cdn}',
@@ -74,6 +74,8 @@ export const exportHTML = (vditor: IVditor) => {
74
74
  Vditor.mindmapRender(previewElement, '${vditor.options.cdn}', '${vditor.options.theme}');
75
75
  Vditor.abcRender(previewElement, '${vditor.options.cdn}');
76
76
  Vditor.mediaRender(previewElement);
77
- </script></body></html>`;
77
+ Vditor.speechRender(previewElement);
78
+ </script>
79
+ <script src="${vditor.options.cdn}/dist/js/icons/${vditor.options.icon}.js"></script></body></html>`;
78
80
  download(vditor, html, content.substr(0, 10) + ".html");
79
81
  };
@@ -59,8 +59,8 @@ export class Hint {
59
59
  vditor.options.hint.extend.forEach((item) => {
60
60
  if (item.key === this.splitChar) {
61
61
  clearTimeout(this.timeId);
62
- this.timeId = window.setTimeout(() => {
63
- this.genHTML(item.hint(key), key, vditor);
62
+ this.timeId = window.setTimeout(async () => {
63
+ this.genHTML(await item.hint(key), key, vditor);
64
64
  }, vditor.options.hint.delay);
65
65
  }
66
66
  });
@@ -148,15 +148,24 @@ ${i === 0 ? "class='vditor-hint--current'" : ""}> ${html}</button>`;
148
148
  return;
149
149
  }
150
150
  }
151
- if (vditor.currentMode === "wysiwyg" && range.startContainer.nodeType !== 3 &&
152
- (range.startContainer as HTMLElement).firstElementChild.classList.contains("vditor-input")) {
153
- const inputElement = (range.startContainer as HTMLElement).firstElementChild as HTMLInputElement;
154
- inputElement.value = value.trimRight();
155
- range.selectNodeContents(inputElement);
156
- range.collapse(false);
157
- inputElement.dispatchEvent(new CustomEvent("input"));
158
- this.recentLanguage = value.trimRight();
159
- return;
151
+ if (vditor.currentMode === "wysiwyg" && range.startContainer.nodeType !== 3 ) {
152
+ const startContainer = range.startContainer as HTMLElement;
153
+ let inputElement: HTMLInputElement;
154
+ if (startContainer.classList.contains("vditor-input")) {
155
+ inputElement = startContainer as HTMLInputElement;
156
+ } else {
157
+ inputElement = startContainer.firstElementChild as HTMLInputElement;
158
+ }
159
+ if (inputElement && inputElement.classList.contains("vditor-input")) {
160
+ inputElement.value = value.trimRight();
161
+ range.selectNodeContents(inputElement);
162
+ range.collapse(false);
163
+ // {detail: 1}用于标识这个自定义事件是在编程语言选择后触发的
164
+ // 用于在鼠标选择语言后,自动聚焦到代码输入框
165
+ inputElement.dispatchEvent(new CustomEvent("input", {detail: 1}));
166
+ this.recentLanguage = value.trimRight();
167
+ return;
168
+ }
160
169
  }
161
170
 
162
171
  range.setStart(range.startContainer, this.lastIndex);
@@ -1,12 +1,13 @@
1
1
  import {Constants} from "../constants";
2
2
  import {addScript} from "../util/addScript";
3
+ import {abcRenderAdapter} from "./adapterRender";
3
4
 
4
5
  declare const ABCJS: {
5
6
  renderAbc(element: HTMLElement, text: string): void;
6
7
  };
7
8
 
8
9
  export const abcRender = (element: (HTMLElement | Document) = document, cdn = Constants.CDN) => {
9
- const abcElements = element.querySelectorAll(".language-abc");
10
+ const abcElements = abcRenderAdapter.getElements(element);
10
11
  if (abcElements.length > 0) {
11
12
  addScript(`${cdn}/dist/js/abcjs/abcjs_basic.min.js`, "vditorAbcjsScript").then(() => {
12
13
  abcElements.forEach((item: HTMLDivElement) => {
@@ -17,7 +18,7 @@ export const abcRender = (element: (HTMLElement | Document) = document, cdn = Co
17
18
  if (item.getAttribute("data-processed") === "true") {
18
19
  return;
19
20
  }
20
- ABCJS.renderAbc(item, item.textContent.trim());
21
+ ABCJS.renderAbc(item, abcRenderAdapter.getCode(item).trim());
21
22
  item.style.overflowX = "auto";
22
23
  item.setAttribute("data-processed", "true");
23
24
  });
@@ -0,0 +1,33 @@
1
+ export const mathRenderAdapter = {
2
+ getCode: (mathElement: Element) => mathElement.textContent,
3
+ getElements: (element: HTMLElement) => element.querySelectorAll(".language-math"),
4
+ };
5
+ export const mermaidRenderAdapter = {
6
+ /** 不仅要返回code,并且需要将 code 设置为 el 的 innerHTML */
7
+ getCode: (el: Element) => el.textContent,
8
+ getElements: (element: HTMLElement) => element.querySelectorAll(".language-mermaid"),
9
+ };
10
+ export const mindmapRenderAdapter = {
11
+ getCode: (el: Element) => el.getAttribute("data-code"),
12
+ getElements: (el: HTMLElement | Document) => el.querySelectorAll(".language-mindmap"),
13
+ };
14
+ export const chartRenderAdapter = {
15
+ getCode: (el: HTMLElement) => el.innerText,
16
+ getElements: (el: HTMLElement | Document) => el.querySelectorAll(".language-echarts"),
17
+ };
18
+ export const abcRenderAdapter = {
19
+ getCode: (el: Element) => el.textContent,
20
+ getElements: (el: HTMLElement | Document) => el.querySelectorAll(".language-abc"),
21
+ };
22
+ export const graphvizRenderAdapter = {
23
+ getCode: (el: Element) => el.textContent,
24
+ getElements: (el: HTMLElement | Document) => el.querySelectorAll(".language-graphviz"),
25
+ };
26
+ export const flowchartRenderAdapter = {
27
+ getCode: (el: Element) => el.textContent,
28
+ getElements: (el: HTMLElement | Document) => el.querySelectorAll(".language-flowchart"),
29
+ };
30
+ export const plantumlRenderAdapter = {
31
+ getCode: (el: Element) => el.textContent,
32
+ getElements: (el: HTMLElement | Document) => el.querySelectorAll(".language-plantuml"),
33
+ };
@@ -1,12 +1,13 @@
1
1
  import {Constants} from "../constants";
2
2
  import {addScript} from "../util/addScript";
3
+ import {chartRenderAdapter} from "./adapterRender";
3
4
 
4
5
  declare const echarts: {
5
6
  init(element: HTMLElement, theme?: string): IEChart;
6
7
  };
7
8
 
8
9
  export const chartRender = (element: (HTMLElement | Document) = document, cdn = Constants.CDN, theme: string) => {
9
- const echartsElements = element.querySelectorAll(".language-echarts");
10
+ const echartsElements = chartRenderAdapter.getElements(element);
10
11
  if (echartsElements.length > 0) {
11
12
  addScript(`${cdn}/dist/js/echarts/echarts.min.js`, "vditorEchartsScript").then(() => {
12
13
  echartsElements.forEach((e: HTMLDivElement) => {
@@ -15,7 +16,7 @@ export const chartRender = (element: (HTMLElement | Document) = document, cdn =
15
16
  return;
16
17
  }
17
18
 
18
- const text = e.innerText.trim();
19
+ const text = chartRenderAdapter.getCode(e).trim();
19
20
  if (!text) {
20
21
  return;
21
22
  }
@@ -1,7 +1,6 @@
1
- import {i18n} from "../i18n/index";
2
1
  import {code160to32} from "../util/code160to32";
3
2
 
4
- export const codeRender = (element: HTMLElement, lang: keyof II18n = "zh_CN") => {
3
+ export const codeRender = (element: HTMLElement) => {
5
4
  element.querySelectorAll("pre > code").forEach((e: HTMLElement, index: number) => {
6
5
  if (e.parentElement.classList.contains("vditor-wysiwyg__pre") ||
7
6
  e.parentElement.classList.contains("vditor-ir__marker--pre")) {
@@ -11,7 +10,7 @@ export const codeRender = (element: HTMLElement, lang: keyof II18n = "zh_CN") =>
11
10
  e.classList.contains("language-echarts") || e.classList.contains("language-mindmap") ||
12
11
  e.classList.contains("language-plantuml") ||
13
12
  e.classList.contains("language-abc") || e.classList.contains("language-graphviz") ||
14
- e.classList.contains("language-math") ) {
13
+ e.classList.contains("language-math")) {
15
14
  return;
16
15
  }
17
16
 
@@ -36,11 +35,11 @@ export const codeRender = (element: HTMLElement, lang: keyof II18n = "zh_CN") =>
36
35
 
37
36
  const divElement = document.createElement("div");
38
37
  divElement.className = "vditor-copy";
39
- divElement.innerHTML = `<span aria-label="${i18n[lang].copy}"
40
- onmouseover="this.setAttribute('aria-label', '${i18n[lang].copy}')"
38
+ divElement.innerHTML = `<span aria-label="${window.VditorI18n.copy}"
39
+ onmouseover="this.setAttribute('aria-label', '${window.VditorI18n.copy}')"
41
40
  class="vditor-tooltipped vditor-tooltipped__w"
42
41
  onclick="this.previousElementSibling.select();document.execCommand('copy');` +
43
- `this.setAttribute('aria-label', '${i18n[lang].copied}')"><svg><use xlink:href="#vditor-icon-copy"></use></svg></span>`;
42
+ `this.setAttribute('aria-label', '${window.VditorI18n.copied}')"><svg><use xlink:href="#vditor-icon-copy"></use></svg></span>`;
44
43
  const textarea = document.createElement("textarea");
45
44
  textarea.value = code160to32(codeText);
46
45
  divElement.insertAdjacentElement("afterbegin", textarea);
@@ -1,12 +1,13 @@
1
1
  import {Constants} from "../constants";
2
2
  import {addScript} from "../util/addScript";
3
+ import {flowchartRenderAdapter} from "./adapterRender";
3
4
 
4
5
  declare const flowchart: {
5
6
  parse(text: string): { drawSVG: (type: HTMLElement) => void };
6
7
  };
7
8
 
8
9
  export const flowchartRender = (element: HTMLElement, cdn = Constants.CDN) => {
9
- const flowchartElements = element.querySelectorAll(".language-flowchart");
10
+ const flowchartElements = flowchartRenderAdapter.getElements(element);
10
11
  if (flowchartElements.length === 0) {
11
12
  return;
12
13
  }
@@ -15,7 +16,7 @@ export const flowchartRender = (element: HTMLElement, cdn = Constants.CDN) => {
15
16
  if (item.getAttribute("data-processed") === "true") {
16
17
  return;
17
18
  }
18
- const flowchartObj = flowchart.parse(item.textContent);
19
+ const flowchartObj = flowchart.parse(flowchartRenderAdapter.getCode(item));
19
20
  item.innerHTML = "";
20
21
  flowchartObj.drawSVG(item);
21
22
  item.setAttribute("data-processed", "true");