vditor 3.8.5 → 3.8.9

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 (60) hide show
  1. package/README.md +48 -45
  2. package/dist/index.css +2 -2
  3. package/dist/index.d.ts +4 -1
  4. package/dist/index.min.js +722 -858
  5. package/dist/js/i18n/en_US.js +85 -0
  6. package/dist/js/i18n/ja_JP.js +85 -0
  7. package/dist/js/i18n/ko_KR.js +85 -0
  8. package/dist/js/i18n/ru_RU.js +85 -0
  9. package/dist/js/i18n/zh_CN.js +85 -0
  10. package/dist/js/i18n/zh_TW.js +85 -0
  11. package/dist/js/lute/lute.min.js +31 -28
  12. package/dist/method.d.ts +4 -1
  13. package/dist/method.min.js +157 -543
  14. package/dist/ts/markdown/adapterRender.d.ts +33 -0
  15. package/dist/ts/markdown/codeRender.d.ts +1 -2
  16. package/dist/ts/ui/initUI.d.ts +1 -0
  17. package/dist/ts/wysiwyg/index.d.ts +2 -0
  18. package/dist/types/index.d.ts +773 -0
  19. package/package.json +4 -4
  20. package/src/assets/.DS_Store +0 -0
  21. package/src/assets/scss/_content.scss +4 -0
  22. package/src/assets/scss/_reset.scss +11 -0
  23. package/src/index.ts +156 -97
  24. package/src/method.ts +6 -2
  25. package/src/ts/.DS_Store +0 -0
  26. package/src/ts/export/index.ts +7 -5
  27. package/src/ts/hint/index.ts +20 -11
  28. package/src/ts/markdown/abcRender.ts +3 -2
  29. package/src/ts/markdown/adapterRender.ts +33 -0
  30. package/src/ts/markdown/chartRender.ts +3 -2
  31. package/src/ts/markdown/codeRender.ts +5 -6
  32. package/src/ts/markdown/flowchartRender.ts +3 -2
  33. package/src/ts/markdown/graphvizRender.ts +13 -11
  34. package/src/ts/markdown/mathRender.ts +5 -4
  35. package/src/ts/markdown/mermaidRender.ts +4 -2
  36. package/src/ts/markdown/mindmapRender.ts +3 -2
  37. package/src/ts/markdown/plantumlRender.ts +3 -2
  38. package/src/ts/markdown/previewRender.ts +26 -4
  39. package/src/ts/preview/image.ts +2 -4
  40. package/src/ts/preview/index.ts +2 -5
  41. package/src/ts/toolbar/EditMode.ts +3 -4
  42. package/src/ts/toolbar/Headings.ts +6 -6
  43. package/src/ts/toolbar/Info.ts +1 -1
  44. package/src/ts/toolbar/MenuItem.ts +1 -3
  45. package/src/ts/toolbar/Record.ts +3 -4
  46. package/src/ts/ui/initUI.ts +19 -5
  47. package/src/ts/upload/index.ts +11 -11
  48. package/src/ts/util/Options.ts +255 -196
  49. package/src/ts/util/editorCommonEvent.ts +2 -2
  50. package/src/ts/util/fixBrowserBehavior.ts +10 -6
  51. package/src/ts/util/processCode.ts +1 -1
  52. package/src/ts/wysiwyg/highlightToolbarWYSIWYG.ts +298 -138
  53. package/src/ts/wysiwyg/index.ts +9 -4
  54. package/CHANGELOG.md +0 -1053
  55. package/dist/images/.DS_Store +0 -0
  56. package/dist/js/.DS_Store +0 -0
  57. package/dist/js/lute/.DS_Store +0 -0
  58. package/dist/js/mathjax/.DS_Store +0 -0
  59. package/dist/ts/i18n/index.d.ts +0 -2
  60. package/src/ts/i18n/index.ts +0 -476
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vditor",
3
- "version": "3.8.5",
3
+ "version": "3.8.9",
4
4
  "description": "♏ 易于使用的 Markdown 编辑器,为适配不同的应用场景而生",
5
5
  "author": "Vanessa <v@b3log.org> (http://vanessa.b3log.org)",
6
6
  "homepage": "https://b3log.org/vditor",
@@ -34,10 +34,10 @@
34
34
  "identity-obj-proxy": "^3.0.0",
35
35
  "jest": "^26.6.3",
36
36
  "mini-css-extract-plugin": "^0.8.2",
37
- "node-sass": "^4.14.1",
37
+ "node-sass": "^7.0.0",
38
38
  "postcss-loader": "^5.2.0",
39
39
  "puppeteer": "^1.20.0",
40
- "sass-loader": "^10.2.0",
40
+ "sass-loader": "^12.4.0",
41
41
  "style-loader": "^1.3.0",
42
42
  "terser-webpack-plugin": "^5.1.2",
43
43
  "ts-jest": "^26.5.6",
@@ -47,7 +47,7 @@
47
47
  "webpack": "^5.37.0",
48
48
  "webpack-bundle-analyzer": "^3.9.0",
49
49
  "webpack-cli": "^4.7.0",
50
- "webpack-dev-server": "^3.11.2"
50
+ "webpack-dev-server": "^4.1.0"
51
51
  },
52
52
  "license": "MIT",
53
53
  "repository": "git://github.com/Vanessa219/vditor.git",
Binary file
@@ -91,6 +91,10 @@
91
91
  padding: 10px;
92
92
  margin: 0 auto;
93
93
  }
94
+
95
+ img:not(.emoji) {
96
+ cursor: pointer;
97
+ }
94
98
  }
95
99
 
96
100
  &-devtools {
@@ -155,6 +155,9 @@
155
155
  margin-bottom: 16px;
156
156
  overflow: auto;
157
157
  border-spacing: 0;
158
+ display: block;
159
+ word-break: keep-all;
160
+ width: 100%;
158
161
 
159
162
  tr {
160
163
  background-color: #fafbfc;
@@ -166,6 +169,14 @@
166
169
  padding: 6px 13px;
167
170
  border: 1px solid #dfe2e5;
168
171
  word-break: normal;
172
+ white-space: nowrap;
173
+
174
+ &:first-child::after {
175
+ content: "";
176
+ display: inline-block;
177
+ vertical-align: top;
178
+ min-height: 24px;
179
+ }
169
180
  }
170
181
 
171
182
  th {
package/src/index.ts CHANGED
@@ -3,42 +3,40 @@ import VditorMethod from "./method";
3
3
  import {Constants, VDITOR_VERSION} from "./ts/constants";
4
4
  import {DevTools} from "./ts/devtools/index";
5
5
  import {Hint} from "./ts/hint/index";
6
- import {i18n} from "./ts/i18n/index";
7
6
  import {IR} from "./ts/ir/index";
8
7
  import {input as irInput} from "./ts/ir/input";
9
8
  import {processAfterRender} from "./ts/ir/process";
10
9
  import {getHTML} from "./ts/markdown/getHTML";
11
10
  import {getMarkdown} from "./ts/markdown/getMarkdown";
12
11
  import {setLute} from "./ts/markdown/setLute";
13
- import {Outline} from "./ts/outline";
12
+ import {Outline} from "./ts/outline/index";
14
13
  import {Preview} from "./ts/preview/index";
15
14
  import {Resize} from "./ts/resize/index";
16
15
  import {Editor} from "./ts/sv/index";
17
16
  import {inputEvent} from "./ts/sv/inputEvent";
18
17
  import {processAfterRender as processSVAfterRender} from "./ts/sv/process";
19
- import {Tip} from "./ts/tip";
18
+ import {Tip} from "./ts/tip/index";
20
19
  import {Toolbar} from "./ts/toolbar/index";
21
20
  import {disableToolbar, hidePanel} from "./ts/toolbar/setToolbar";
22
21
  import {enableToolbar} from "./ts/toolbar/setToolbar";
23
- import {initUI} from "./ts/ui/initUI";
22
+ import {initUI, UIUnbindListener} from "./ts/ui/initUI";
24
23
  import {setCodeTheme} from "./ts/ui/setCodeTheme";
25
24
  import {setContentTheme} from "./ts/ui/setContentTheme";
26
25
  import {setPreviewMode} from "./ts/ui/setPreviewMode";
27
26
  import {setTheme} from "./ts/ui/setTheme";
28
- import {Undo} from "./ts/undo";
27
+ import {Undo} from "./ts/undo/index";
29
28
  import {Upload} from "./ts/upload/index";
30
29
  import {addScript, addScriptSync} from "./ts/util/addScript";
31
30
  import {getSelectText} from "./ts/util/getSelectText";
32
31
  import {Options} from "./ts/util/Options";
33
32
  import {processCodeRender} from "./ts/util/processCode";
34
33
  import {getCursorPosition, getEditorRange} from "./ts/util/selection";
35
- import {WYSIWYG} from "./ts/wysiwyg";
36
34
  import {afterRenderEvent} from "./ts/wysiwyg/afterRenderEvent";
35
+ import {WYSIWYG} from "./ts/wysiwyg/index";
37
36
  import {input} from "./ts/wysiwyg/input";
38
37
  import {renderDomByMd} from "./ts/wysiwyg/renderDomByMd";
39
38
 
40
39
  class Vditor extends VditorMethod {
41
-
42
40
  public readonly version: string;
43
41
  public vditor: IVditor;
44
42
 
@@ -68,76 +66,37 @@ class Vditor extends VditorMethod {
68
66
  const getOptions = new Options(options);
69
67
  const mergedOptions = getOptions.merge();
70
68
 
71
- if (!["en_US", "ja_JP", "ko_KR", "ru_RU", "zh_CN", "zh_TW"].includes(mergedOptions.lang)) {
72
- throw new Error("options.lang error, see https://ld246.com/article/1549638745630#options");
73
- }
74
-
75
- this.vditor = {
76
- currentMode: mergedOptions.mode,
77
- element: id,
78
- hint: new Hint(mergedOptions.hint.extend),
79
- lute: undefined,
80
- options: mergedOptions,
81
- originalInnerHTML: id.innerHTML,
82
- outline: new Outline(i18n[mergedOptions.lang].outline),
83
- tip: new Tip(),
84
- };
85
-
86
- this.vditor.sv = new Editor(this.vditor);
87
- this.vditor.undo = new Undo();
88
- this.vditor.wysiwyg = new WYSIWYG(this.vditor);
89
- this.vditor.ir = new IR(this.vditor);
90
- this.vditor.toolbar = new Toolbar(this.vditor);
91
-
92
- if (mergedOptions.resize.enable) {
93
- this.vditor.resize = new Resize(this.vditor);
94
- }
95
-
96
- if (this.vditor.toolbar.elements.devtools) {
97
- this.vditor.devtools = new DevTools();
98
- }
99
-
100
- if (mergedOptions.upload.url || mergedOptions.upload.handler) {
101
- this.vditor.upload = new Upload();
102
- }
103
-
104
- addScript(options._lutePath || `${mergedOptions.cdn}/dist/js/lute/lute.min.js`, "vditorLuteScript")
105
- .then(() => {
106
- this.vditor.lute = setLute({
107
- autoSpace: this.vditor.options.preview.markdown.autoSpace,
108
- codeBlockPreview: this.vditor.options.preview.markdown.codeBlockPreview,
109
- emojiSite: this.vditor.options.hint.emojiPath,
110
- emojis: this.vditor.options.hint.emoji,
111
- fixTermTypo: this.vditor.options.preview.markdown.fixTermTypo,
112
- footnotes: this.vditor.options.preview.markdown.footnotes,
113
- headingAnchor: false,
114
- inlineMathDigit: this.vditor.options.preview.math.inlineDigit,
115
- linkBase: this.vditor.options.preview.markdown.linkBase,
116
- linkPrefix: this.vditor.options.preview.markdown.linkPrefix,
117
- listStyle: this.vditor.options.preview.markdown.listStyle,
118
- mark: this.vditor.options.preview.markdown.mark,
119
- mathBlockPreview: this.vditor.options.preview.markdown.mathBlockPreview,
120
- paragraphBeginningSpace: this.vditor.options.preview.markdown.paragraphBeginningSpace,
121
- sanitize: this.vditor.options.preview.markdown.sanitize,
122
- 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
+ }
123
82
  });
124
-
125
- this.vditor.preview = new Preview(this.vditor);
126
-
127
- initUI(this.vditor);
128
-
129
- if (mergedOptions.after) {
130
- mergedOptions.after();
131
- }
132
- if (mergedOptions.icon) {
133
- // 防止初始化 2 个编辑器时加载 2 次
134
- addScriptSync(`${mergedOptions.cdn}/dist/js/icons/${mergedOptions.icon}.js`, "vditorIconScript");
135
- }
136
- });
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
+ }
137
91
  }
138
92
 
139
93
  /** 设置主题 */
140
- 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
+ ) {
141
100
  this.vditor.options.theme = theme;
142
101
  setTheme(this.vditor);
143
102
  if (contentTheme) {
@@ -185,15 +144,22 @@ class Vditor extends VditorMethod {
185
144
  /** 禁用编辑器 */
186
145
  public disabled() {
187
146
  hidePanel(this.vditor, ["subToolbar", "hint", "popover"]);
188
- disableToolbar(this.vditor.toolbar.elements, Constants.EDIT_TOOLBARS.concat(["undo", "redo", "fullscreen",
189
- "edit-mode"]));
190
- 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
+ );
191
155
  }
192
156
 
193
157
  /** 解除编辑器禁用 */
194
158
  public enable() {
195
- enableToolbar(this.vditor.toolbar.elements, Constants.EDIT_TOOLBARS.concat(["undo", "redo", "fullscreen",
196
- "edit-mode"]));
159
+ enableToolbar(
160
+ this.vditor.toolbar.elements,
161
+ Constants.EDIT_TOOLBARS.concat(["undo", "redo", "fullscreen", "edit-mode"]),
162
+ );
197
163
  this.vditor.undo.resetIcon(this.vditor);
198
164
  this.vditor[this.vditor.currentMode].element.setAttribute("contenteditable", "true");
199
165
  }
@@ -237,8 +203,9 @@ class Vditor extends VditorMethod {
237
203
  /** 启用缓存 */
238
204
  public enableCache() {
239
205
  if (!this.vditor.options.cache.id) {
240
- throw new Error("need options.cache.id, see https://ld246.com/article/1549638745630#options");
241
- return;
206
+ throw new Error(
207
+ "need options.cache.id, see https://ld246.com/article/1549638745630#options",
208
+ );
242
209
  }
243
210
  this.vditor.options.cache.enable = true;
244
211
  }
@@ -248,6 +215,11 @@ class Vditor extends VditorMethod {
248
215
  return this.vditor.lute.HTML2Md(value);
249
216
  }
250
217
 
218
+ /** markdown 转 JSON 输出 */
219
+ public exportJSON(value: string) {
220
+ return this.vditor.lute.RenderJSON(value);
221
+ }
222
+
251
223
  /** 获取 HTML */
252
224
  public getHTML() {
253
225
  return getHTML(this.vditor);
@@ -318,8 +290,9 @@ class Vditor extends VditorMethod {
318
290
  });
319
291
  } else {
320
292
  this.vditor.ir.element.innerHTML = this.vditor.lute.Md2VditorIRDOM(markdown);
321
- this.vditor.ir.element.querySelectorAll(".vditor-ir__preview[data-render='2']").forEach(
322
- (item: HTMLElement) => {
293
+ this.vditor.ir.element
294
+ .querySelectorAll(".vditor-ir__preview[data-render='2']")
295
+ .forEach((item: HTMLElement) => {
323
296
  processCodeRender(item, this.vditor);
324
297
  });
325
298
  processAfterRender(this.vditor, {
@@ -356,6 +329,9 @@ class Vditor extends VditorMethod {
356
329
  this.vditor.element.removeAttribute("style");
357
330
  document.getElementById("vditorIconScript").remove();
358
331
  this.clearCache();
332
+
333
+ UIUnbindListener();
334
+ this.vditor.wysiwyg.unbindListener();
359
335
  }
360
336
 
361
337
  /** 获取评论 ID */
@@ -379,13 +355,17 @@ class Vditor extends VditorMethod {
379
355
  }
380
356
  });
381
357
  };
382
- this.vditor.wysiwyg.element.querySelectorAll(".vditor-comment").forEach((item) => {
383
- hlItem(item);
384
- });
385
- if (this.vditor.preview.element.style.display !== "none") {
386
- this.vditor.preview.element.querySelectorAll(".vditor-comment").forEach((item) => {
358
+ this.vditor.wysiwyg.element
359
+ .querySelectorAll(".vditor-comment")
360
+ .forEach((item) => {
387
361
  hlItem(item);
388
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
+ });
389
369
  }
390
370
  }
391
371
 
@@ -401,13 +381,17 @@ class Vditor extends VditorMethod {
401
381
  }
402
382
  });
403
383
  };
404
- this.vditor.wysiwyg.element.querySelectorAll(".vditor-comment").forEach((item) => {
405
- unHlItem(item);
406
- });
407
- if (this.vditor.preview.element.style.display !== "none") {
408
- this.vditor.preview.element.querySelectorAll(".vditor-comment").forEach((item) => {
384
+ this.vditor.wysiwyg.element
385
+ .querySelectorAll(".vditor-comment")
386
+ .forEach((item) => {
409
387
  unHlItem(item);
410
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
+ });
411
395
  }
412
396
  }
413
397
 
@@ -433,13 +417,17 @@ class Vditor extends VditorMethod {
433
417
  }
434
418
  };
435
419
  removeIds.forEach((removeId) => {
436
- this.vditor.wysiwyg.element.querySelectorAll(".vditor-comment").forEach((item) => {
437
- removeItem(item, removeId);
438
- });
439
- if (this.vditor.preview.element.style.display !== "none") {
440
- this.vditor.preview.element.querySelectorAll(".vditor-comment").forEach((item) => {
420
+ this.vditor.wysiwyg.element
421
+ .querySelectorAll(".vditor-comment")
422
+ .forEach((item) => {
441
423
  removeItem(item, removeId);
442
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
+ });
443
431
  }
444
432
  });
445
433
  afterRenderEvent(this.vditor, {
@@ -448,6 +436,77 @@ class Vditor extends VditorMethod {
448
436
  enableInput: false,
449
437
  });
450
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
+ }
451
510
  }
452
511
 
453
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
@@ -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
  }