vditor 3.11.2 → 4.0.0

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 (74) hide show
  1. package/README.md +12 -1
  2. package/dist/css/content-theme/ant-design.css +10 -0
  3. package/dist/css/content-theme/dark.css +10 -0
  4. package/dist/css/content-theme/light.css +13 -0
  5. package/dist/css/content-theme/wechat.css +10 -0
  6. package/dist/index.css +163 -81
  7. package/dist/index.js +3035 -2715
  8. package/dist/index.min.js +1 -1
  9. package/dist/js/i18n/ja_JP.js +2 -2
  10. package/dist/js/i18n/zh_TW.js +8 -8
  11. package/dist/js/lute/lute.min.js +75 -60
  12. package/dist/js/mermaid/mermaid.min.js +2027 -1047
  13. package/dist/js/wavedrom/LICENSE.WaveDrom +21 -0
  14. package/dist/js/wavedrom/wavedrom.min.js +9 -0
  15. package/dist/method.d.ts +2 -0
  16. package/dist/method.js +323 -9
  17. package/dist/method.min.js +1 -1
  18. package/dist/ts/constants.d.ts +4 -0
  19. package/dist/ts/markdown/adapterRender.d.ts +4 -0
  20. package/dist/ts/markdown/imageCaptionRender.d.ts +2 -0
  21. package/dist/ts/markdown/wavedromRender.d.ts +1 -0
  22. package/dist/ts/sv/index.d.ts +1 -5
  23. package/dist/ts/sv/process.d.ts +1 -3
  24. package/dist/ts/upload/getElement.d.ts +1 -1
  25. package/dist/ts/upload/index.d.ts +2 -0
  26. package/dist/ts/util/editorCommonEvent.d.ts +1 -1
  27. package/dist/ts/util/fixBrowserBehavior.d.ts +1 -0
  28. package/dist/types/index.d.ts +22 -5
  29. package/package.json +7 -4
  30. package/src/assets/less/_reset.less +103 -2
  31. package/src/assets/less/_sv.less +2 -98
  32. package/src/assets/less/_wysiwyg.less +30 -0
  33. package/src/assets/less/index.less +20 -0
  34. package/src/index.ts +48 -14
  35. package/src/method.ts +3 -0
  36. package/src/ts/constants.ts +5 -1
  37. package/src/ts/export/index.ts +2 -0
  38. package/src/ts/hint/index.ts +9 -4
  39. package/src/ts/ir/highlightToolbarIR.ts +4 -4
  40. package/src/ts/ir/index.ts +26 -0
  41. package/src/ts/ir/process.ts +24 -1
  42. package/src/ts/markdown/adapterRender.ts +4 -0
  43. package/src/ts/markdown/getHTML.ts +6 -3
  44. package/src/ts/markdown/getMarkdown.ts +3 -3
  45. package/src/ts/markdown/imageCaptionRender.ts +175 -0
  46. package/src/ts/markdown/mermaidRender.ts +1 -1
  47. package/src/ts/markdown/previewRender.ts +7 -1
  48. package/src/ts/markdown/setLute.ts +3 -0
  49. package/src/ts/markdown/wavedromRender.ts +54 -0
  50. package/src/ts/preview/index.ts +5 -0
  51. package/src/ts/sv/index.ts +37 -76
  52. package/src/ts/sv/process.ts +48 -164
  53. package/src/ts/sv/processKeydown.ts +19 -186
  54. package/src/ts/toolbar/EditMode.ts +3 -10
  55. package/src/ts/toolbar/Emoji.ts +8 -1
  56. package/src/ts/toolbar/Record.ts +10 -2
  57. package/src/ts/toolbar/index.ts +3 -0
  58. package/src/ts/ui/initUI.ts +7 -3
  59. package/src/ts/undo/index.ts +32 -17
  60. package/src/ts/upload/index.ts +42 -10
  61. package/src/ts/util/Options.ts +1 -1
  62. package/src/ts/util/editorCommonEvent.ts +18 -9
  63. package/src/ts/util/fixBrowserBehavior.ts +197 -51
  64. package/src/ts/util/processCode.ts +3 -0
  65. package/src/ts/util/selection.ts +11 -3
  66. package/src/ts/wysiwyg/afterRenderEvent.ts +2 -0
  67. package/src/ts/wysiwyg/highlightToolbarWYSIWYG.ts +58 -2
  68. package/src/ts/wysiwyg/input.ts +5 -0
  69. package/src/ts/wysiwyg/processKeydown.ts +47 -0
  70. package/src/ts/wysiwyg/setHeading.ts +110 -6
  71. package/dist/ts/sv/combineFootnote.d.ts +0 -6
  72. package/dist/ts/sv/inputEvent.d.ts +0 -1
  73. package/src/ts/sv/combineFootnote.ts +0 -27
  74. package/src/ts/sv/inputEvent.ts +0 -188
@@ -70,6 +70,35 @@
70
70
  vertical-align: sub;
71
71
  }
72
72
 
73
+ figure.vditor-image {
74
+ margin: 0 0 16px;
75
+ text-align: center;
76
+
77
+ figcaption {
78
+ font-size: 0.875em;
79
+ margin-top: 4px;
80
+ opacity: 0.65;
81
+ white-space: pre-wrap;
82
+ }
83
+ }
84
+
85
+ span.vditor-image[data-image-caption] {
86
+ display: inline-block;
87
+ max-width: 100%;
88
+ text-align: center;
89
+ vertical-align: top;
90
+
91
+ &::after {
92
+ content: attr(data-image-caption);
93
+ display: block;
94
+ font-size: 0.875em;
95
+ line-height: 1.5;
96
+ margin-top: 4px;
97
+ opacity: 0.65;
98
+ white-space: pre-wrap;
99
+ }
100
+ }
101
+
73
102
  h1,
74
103
  h2,
75
104
  h3,
@@ -235,7 +264,8 @@
235
264
  .language-markmap,
236
265
  .language-abc,
237
266
  .language-flowchart,
238
- .language-graphviz {
267
+ .language-graphviz,
268
+ .language-wavedrom {
239
269
  margin-bottom: 16px;
240
270
  }
241
271
 
@@ -261,7 +291,8 @@
261
291
  .language-mermaid,
262
292
  .language-markmap,
263
293
  .language-flowchart,
264
- .language-graphviz {
294
+ .language-graphviz,
295
+ .language-wavedrom {
265
296
  text-align: center;
266
297
  }
267
298
 
@@ -617,3 +648,73 @@
617
648
  }
618
649
  }
619
650
  }
651
+
652
+ .vditor-reset .callout,
653
+ .vditor-wysiwyg blockquote.callout,
654
+ .vditor-ir blockquote.callout {
655
+ --callout-color: var(--callout-note-color, #0969da);
656
+ --callout-background-color: var(--callout-note-background-color, rgba(9, 105, 218, 0.08));
657
+ position: relative;
658
+ margin: 0 0 16px;
659
+ padding: 0.75em 1em;
660
+ color: inherit;
661
+ background-color: var(--callout-background-color);
662
+ border: 0;
663
+ border-left: 0.25em solid var(--callout-color);
664
+
665
+ &[data-subtype="TIP"] {
666
+ --callout-color: var(--callout-tip-color, #1a7f37);
667
+ --callout-background-color: var(--callout-tip-background-color, rgba(26, 127, 55, 0.08));
668
+ }
669
+
670
+ &[data-subtype="IMPORTANT"] {
671
+ --callout-color: var(--callout-important-color, #8250df);
672
+ --callout-background-color: var(--callout-important-background-color, rgba(130, 80, 223, 0.08));
673
+ }
674
+
675
+ &[data-subtype="WARNING"] {
676
+ --callout-color: var(--callout-warning-color, #9a6700);
677
+ --callout-background-color: var(--callout-warning-background-color, rgba(154, 103, 0, 0.08));
678
+ }
679
+
680
+ &[data-subtype="CAUTION"] {
681
+ --callout-color: var(--callout-caution-color, #cf222e);
682
+ --callout-background-color: var(--callout-caution-background-color, rgba(207, 34, 46, 0.08));
683
+ }
684
+
685
+ > .callout-info {
686
+ display: flex;
687
+ align-items: center;
688
+ min-height: 1.5em;
689
+ margin: 0 0 0.5em;
690
+ color: var(--callout-color);
691
+ font-weight: 600;
692
+
693
+ .callout-icon {
694
+ display: inline-flex;
695
+ align-items: center;
696
+ margin-right: 0.35em;
697
+ }
698
+
699
+ .callout-title {
700
+ min-width: 1px;
701
+ }
702
+
703
+ .callout-img,
704
+ > .callout-img {
705
+ width: 1.2em;
706
+ height: 1.2em;
707
+ margin-right: 0.35em;
708
+ object-fit: contain;
709
+ }
710
+ }
711
+
712
+ > .callout-content > :last-child,
713
+ > :last-child {
714
+ margin-bottom: 0;
715
+ }
716
+ }
717
+
718
+ .vditor-wysiwyg__callout-marker {
719
+ display: none;
720
+ }
@@ -20,13 +20,12 @@
20
20
  word-break: break-word;
21
21
  word-wrap: break-word;
22
22
 
23
- &[contenteditable="false"] {
23
+ &:disabled {
24
24
  opacity: 0.3;
25
25
  cursor: not-allowed;
26
26
  }
27
27
 
28
- &:empty::before {
29
- content: attr(placeholder);
28
+ &::placeholder {
30
29
  color: var(--second-color);
31
30
  }
32
31
 
@@ -34,99 +33,4 @@
34
33
  background-color: var(--textarea-background-color);
35
34
  }
36
35
 
37
- &:after {
38
- content: "";
39
- height: var(--editor-bottom);
40
- display: block;
41
- }
42
-
43
- span[data-type="newline"] + span[data-type="text"]:empty {
44
- display: inherit;
45
- }
46
-
47
- .sup {
48
- vertical-align: super;
49
- font-size: smaller;
50
- }
51
-
52
- .strong {
53
- font-weight: bold;
54
- }
55
-
56
- .em {
57
- font-style: italic;
58
- }
59
-
60
- .s {
61
- text-decoration: line-through;
62
- }
63
-
64
- .mark:not(.vditor-sv__marker) {
65
- background-color: yellow;
66
- color: black;
67
- }
68
-
69
- .h1 {
70
- font-size: 1.75em;
71
- line-height: 44px;
72
- }
73
-
74
- .h2 {
75
- font-size: 1.55em;
76
- line-height: 38px;
77
- }
78
-
79
- .h3 {
80
- font-size: 1.38em;
81
- line-height: 27px;
82
- }
83
-
84
- .h4 {
85
- font-size: 1.25em;
86
- line-height: 25px;
87
- }
88
-
89
- .h5 {
90
- font-size: 1.13em;
91
- }
92
-
93
- .h6 {
94
- font-size: 1em;
95
- }
96
-
97
- &__marker {
98
- color: var(--second-color);
99
-
100
- &--heading {
101
- color: var(--ir-heading-color);
102
- }
103
-
104
- &--bi {
105
- color: var(--ir-bi-color);
106
- }
107
-
108
- &--link {
109
- color: var(--ir-link-color);
110
- }
111
-
112
- &--title {
113
- color: var(--ir-title-color);
114
- }
115
-
116
- &--bracket {
117
- color: var(--ir-bracket-color);
118
- }
119
-
120
- &--paren {
121
- color: var(--ir-paren-color);
122
- }
123
-
124
- &--info {
125
- color: var(--ir-heading-color);
126
- }
127
-
128
- &--strong {
129
- font-weight: bold;
130
- }
131
- }
132
36
  }
@@ -177,8 +177,38 @@
177
177
  }
178
178
  }
179
179
 
180
+ .vditor-wysiwyg__mobile-toolbar {
181
+ display: none;
182
+ }
183
+
180
184
  @media screen and (max-width: @max-width) {
181
185
  .vditor-wysiwyg {
186
+ &__mobile-toolbar {
187
+ display: block;
188
+ float: left;
189
+ height: 21px;
190
+ position: relative;
191
+ width: 23px;
192
+ }
193
+
194
+ &__mobile-actions {
195
+ box-sizing: border-box;
196
+ flex-wrap: wrap;
197
+ left: 0;
198
+ padding: 5px;
199
+ top: 26px;
200
+ white-space: normal;
201
+
202
+ &.vditor-panel--left {
203
+ left: auto;
204
+ right: 0;
205
+ }
206
+
207
+ &--open {
208
+ display: flex;
209
+ }
210
+ }
211
+
182
212
  h1:before,
183
213
  h2:before,
184
214
  h3:before,
@@ -37,6 +37,16 @@
37
37
  --count-background-color: rgba(27, 31, 35, 0.05);
38
38
  --heading-border-color: #eaecef;
39
39
  --blockquote-color: #6a737d;
40
+ --callout-note-color: #0969da;
41
+ --callout-note-background-color: rgba(9, 105, 218, 0.08);
42
+ --callout-tip-color: #1a7f37;
43
+ --callout-tip-background-color: rgba(26, 127, 55, 0.08);
44
+ --callout-important-color: #8250df;
45
+ --callout-important-background-color: rgba(130, 80, 223, 0.08);
46
+ --callout-warning-color: #9a6700;
47
+ --callout-warning-background-color: rgba(154, 103, 0, 0.08);
48
+ --callout-caution-color: #cf222e;
49
+ --callout-caution-background-color: rgba(207, 34, 46, 0.08);
40
50
 
41
51
  --ir-heading-color: #660e7a;
42
52
  --ir-title-color: #808080;
@@ -67,6 +77,16 @@
67
77
  --count-background-color: rgba(@blurColor, 0.36);
68
78
  --heading-border-color: var(--textarea-text-color);
69
79
  --blockquote-color: var(--toolbar-icon-color);
80
+ --callout-note-color: #58a6ff;
81
+ --callout-note-background-color: rgba(56, 139, 253, 0.15);
82
+ --callout-tip-color: #3fb950;
83
+ --callout-tip-background-color: rgba(46, 160, 67, 0.15);
84
+ --callout-important-color: #a371f7;
85
+ --callout-important-background-color: rgba(163, 113, 247, 0.15);
86
+ --callout-warning-color: #d29922;
87
+ --callout-warning-background-color: rgba(187, 128, 9, 0.15);
88
+ --callout-caution-color: #f85149;
89
+ --callout-caution-background-color: rgba(248, 81, 73, 0.15);
70
90
 
71
91
  --ir-heading-color: #9876aa;
72
92
  --ir-title-color: #808080;
package/src/index.ts CHANGED
@@ -13,7 +13,6 @@ 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
- import {inputEvent} from "./ts/sv/inputEvent";
17
16
  import {processAfterRender as processSVAfterRender, processPaste} from "./ts/sv/process";
18
17
  import {Tip} from "./ts/tip/index";
19
18
  import {Toolbar} from "./ts/toolbar/index";
@@ -167,10 +166,11 @@ class Vditor extends VditorMethod {
167
166
  this.vditor.toolbar.elements,
168
167
  Constants.EDIT_TOOLBARS.concat(["undo", "redo", "fullscreen", "edit-mode"]),
169
168
  );
170
- this.vditor[this.vditor.currentMode].element.setAttribute(
171
- "contenteditable",
172
- "false",
173
- );
169
+ if (this.vditor.currentMode === "sv") {
170
+ this.vditor.sv.element.disabled = true;
171
+ } else {
172
+ this.vditor[this.vditor.currentMode].element.setAttribute("contenteditable", "false");
173
+ }
174
174
  }
175
175
 
176
176
  /** 解除编辑器禁用 */
@@ -180,7 +180,11 @@ class Vditor extends VditorMethod {
180
180
  Constants.EDIT_TOOLBARS.concat(["undo", "redo", "fullscreen", "edit-mode"]),
181
181
  );
182
182
  this.vditor.undo.resetIcon(this.vditor);
183
- this.vditor[this.vditor.currentMode].element.setAttribute("contenteditable", "true");
183
+ if (this.vditor.currentMode === "sv") {
184
+ this.vditor.sv.element.disabled = false;
185
+ } else {
186
+ this.vditor[this.vditor.currentMode].element.setAttribute("contenteditable", "true");
187
+ }
184
188
  }
185
189
 
186
190
  /** 返回选中的字符串 */
@@ -188,7 +192,10 @@ class Vditor extends VditorMethod {
188
192
  if (this.vditor.currentMode === "wysiwyg") {
189
193
  return getSelectText(this.vditor.wysiwyg.element);
190
194
  } else if (this.vditor.currentMode === "sv") {
191
- return getSelectText(this.vditor.sv.element);
195
+ return this.vditor.sv.element.value.substring(
196
+ this.vditor.sv.element.selectionStart,
197
+ this.vditor.sv.element.selectionEnd,
198
+ );
192
199
  } else if (this.vditor.currentMode === "ir") {
193
200
  return getSelectText(this.vditor.ir.element);
194
201
  }
@@ -201,6 +208,15 @@ class Vditor extends VditorMethod {
201
208
 
202
209
  /** 获取焦点位置 */
203
210
  public getCursorPosition() {
211
+ if (this.vditor.currentMode === "sv") {
212
+ const element = this.vditor.sv.element;
213
+ const lineHeight = parseInt(getComputedStyle(element).lineHeight, 10) || 22;
214
+ const line = element.value.substring(0, element.selectionStart).split("\n").length - 1;
215
+ return {
216
+ left: 0,
217
+ top: line * lineHeight - element.scrollTop,
218
+ };
219
+ }
204
220
  return getCursorPosition(this.vditor[this.vditor.currentMode].element);
205
221
  }
206
222
 
@@ -258,6 +274,14 @@ class Vditor extends VditorMethod {
258
274
 
259
275
  /** 删除选中内容 */
260
276
  public deleteValue() {
277
+ if (this.vditor.currentMode === "sv") {
278
+ if (this.vditor.sv.element.selectionStart === this.vditor.sv.element.selectionEnd) {
279
+ return;
280
+ }
281
+ processPaste(this.vditor, "");
282
+ processSVAfterRender(this.vditor);
283
+ return;
284
+ }
261
285
  if (window.getSelection().isCollapsed) {
262
286
  return;
263
287
  }
@@ -266,11 +290,23 @@ class Vditor extends VditorMethod {
266
290
 
267
291
  /** 更新选中内容 */
268
292
  public updateValue(value: string) {
293
+ if (this.vditor.currentMode === "sv") {
294
+ processPaste(this.vditor, value);
295
+ processSVAfterRender(this.vditor);
296
+ return;
297
+ }
269
298
  document.execCommand("insertHTML", false, value);
270
299
  }
271
300
 
272
301
  /** 在焦点处插入内容,并默认进行 Markdown 渲染 */
273
302
  public insertValue(value: string, render = true) {
303
+ if (this.vditor.currentMode === "sv") {
304
+ processPaste(this.vditor, value);
305
+ if (render) {
306
+ processSVAfterRender(this.vditor);
307
+ }
308
+ return;
309
+ }
274
310
  const range = getEditorRange(this.vditor);
275
311
  range.collapse(true);
276
312
  // https://github.com/Vanessa219/vditor/issues/716
@@ -279,12 +315,7 @@ class Vditor extends VditorMethod {
279
315
  tmpElement.innerHTML = value;
280
316
  range.insertNode(tmpElement.content.cloneNode(true));
281
317
  range.collapse(false);
282
- if (this.vditor.currentMode === "sv") {
283
- this.vditor.sv.preventInput = true;
284
- if (render) {
285
- inputEvent(this.vditor);
286
- }
287
- } else if (this.vditor.currentMode === "wysiwyg") {
318
+ if (this.vditor.currentMode === "wysiwyg") {
288
319
  // 由于 https://github.com/Vanessa219/vditor/issues/1566 不能使用 this.vditor.wysiwyg.preventInput = true;
289
320
  if (render) {
290
321
  input(this.vditor, getSelection().getRangeAt(0));
@@ -314,7 +345,7 @@ class Vditor extends VditorMethod {
314
345
  /** 设置编辑器内容 */
315
346
  public setValue(markdown: string, clearStack = false) {
316
347
  if (this.vditor.currentMode === "sv") {
317
- this.vditor.sv.element.innerHTML = `<div data-block='0'>${this.vditor.lute.SpinVditorSVDOM(markdown)}</div>`;
348
+ this.vditor.sv.element.value = markdown;
318
349
  processSVAfterRender(this.vditor, {
319
350
  enableAddUndoStack: true,
320
351
  enableHint: false,
@@ -525,6 +556,7 @@ class Vditor extends VditorMethod {
525
556
  ).then(() => {
526
557
  this.vditor.lute = setLute({
527
558
  autoSpace: this.vditor.options.preview.markdown.autoSpace,
559
+ callout: this.vditor.options.preview.markdown.callout,
528
560
  gfmAutoLink: this.vditor.options.preview.markdown.gfmAutoLink,
529
561
  codeBlockPreview: this.vditor.options.preview.markdown
530
562
  .codeBlockPreview,
@@ -543,6 +575,8 @@ class Vditor extends VditorMethod {
543
575
  paragraphBeginningSpace: this.vditor.options.preview.markdown
544
576
  .paragraphBeginningSpace,
545
577
  sanitize: this.vditor.options.preview.markdown.sanitize,
578
+ sub: this.vditor.options.preview.markdown.sub,
579
+ sup: this.vditor.options.preview.markdown.sup,
546
580
  toc: this.vditor.options.preview.markdown.toc,
547
581
  });
548
582
 
package/src/method.ts CHANGED
@@ -14,6 +14,7 @@ import {markmapRender} from "./ts/markdown/markmapRender";
14
14
  import {mindmapRender} from "./ts/markdown/mindmapRender";
15
15
  import {outlineRender} from "./ts/markdown/outlineRender";
16
16
  import {plantumlRender} from "./ts/markdown/plantumlRender";
17
+ import {wavedromRender} from "./ts/markdown/wavedromRender";
17
18
  import {md2html, previewRender} from "./ts/markdown/previewRender";
18
19
  import {speechRender} from "./ts/markdown/speechRender";
19
20
  import {previewImage} from "./ts/preview/image";
@@ -30,6 +31,8 @@ class Vditor {
30
31
  public static codeRender = codeRender;
31
32
  /** 对 graphviz 进行渲染 */
32
33
  public static graphvizRender = graphvizRender;
34
+ /** 对数字波形图进行渲染 */
35
+ public static wavedromRender = wavedromRender;
33
36
  /** 为 element 中的代码块进行高亮渲染 */
34
37
  public static highlightRender = highlightRender;
35
38
  /** 对数学公式进行渲染 */
@@ -44,17 +44,19 @@ export abstract class Constants {
44
44
  "stackoverflow-light", "tokyo-night-light", "vs", "xcode", "default"];
45
45
  public static readonly ALIAS_CODE_LANGUAGES: string[] = [
46
46
  // 自定义
47
- "abc", "plantuml", "mermaid", "flowchart", "echarts", "mindmap", "graphviz", "math", "markmap", "smiles",
47
+ "abc", "plantuml", "mermaid", "flowchart", "echarts", "mindmap", "graphviz", "wavedrom", "math", "markmap", "smiles",
48
48
  // 别名
49
49
  "js", "ts", "html", "toml", "c#", "bat"
50
50
  ];
51
51
  public static readonly CDN = `https://unpkg.com/vditor@${VDITOR_VERSION}`;
52
52
  public static readonly MARKDOWN_OPTIONS = {
53
53
  autoSpace: false,
54
+ callout: true,
54
55
  gfmAutoLink: true,
55
56
  codeBlockPreview: true,
56
57
  fixTermTypo: false,
57
58
  footnotes: true,
59
+ imageCaption: false,
58
60
  linkBase: "",
59
61
  linkPrefix: "",
60
62
  listStyle: false,
@@ -62,6 +64,8 @@ export abstract class Constants {
62
64
  mathBlockPreview: true,
63
65
  paragraphBeginningSpace: false,
64
66
  sanitize: true,
67
+ sub: false,
68
+ sup: false,
65
69
  toc: false,
66
70
  };
67
71
  public static readonly HLJS_OPTIONS = {
@@ -36,6 +36,7 @@ window.addEventListener("message", (e) => {
36
36
  Vditor.preview(document.getElementById('preview'), e.data, {
37
37
  cdn: "${vditor.options.cdn}",
38
38
  markdown: {
39
+ callout: ${JSON.stringify(vditor.options.preview.markdown.callout)},
39
40
  theme: ${JSON.stringify(vditor.options.preview.theme)}
40
41
  },
41
42
  hljs: {
@@ -73,6 +74,7 @@ export const exportHTML = (vditor: IVditor) => {
73
74
  Vditor.markmapRender(previewElement, '${vditor.options.cdn}');
74
75
  Vditor.flowchartRender(previewElement, '${vditor.options.cdn}');
75
76
  Vditor.graphvizRender(previewElement, '${vditor.options.cdn}');
77
+ Vditor.wavedromRender(previewElement, '${vditor.options.cdn}');
76
78
  Vditor.chartRender(previewElement, '${vditor.options.cdn}', '${vditor.options.theme}');
77
79
  Vditor.mindmapRender(previewElement, '${vditor.options.cdn}', '${vditor.options.theme}');
78
80
  Vditor.abcRender(previewElement, '${vditor.options.cdn}');
@@ -23,6 +23,10 @@ export class Hint {
23
23
  }
24
24
 
25
25
  public render(vditor: IVditor) {
26
+ if (vditor.currentMode === "sv") {
27
+ this.element.style.display = "none";
28
+ return;
29
+ }
26
30
  if (!window.getSelection().focusNode) {
27
31
  return;
28
32
  }
@@ -128,6 +132,9 @@ ${i === 0 ? "class='vditor-hint--current'" : ""}> ${html}</button>`;
128
132
 
129
133
  public fillEmoji = (element: HTMLElement, vditor: IVditor) => {
130
134
  this.element.style.display = "none";
135
+ if (vditor.currentMode === "sv") {
136
+ return;
137
+ }
131
138
 
132
139
  const value = decodeURIComponent(element.getAttribute("data-value"));
133
140
  const range: Range = window.getSelection().getRangeAt(0);
@@ -172,9 +179,7 @@ ${i === 0 ? "class='vditor-hint--current'" : ""}> ${html}</button>`;
172
179
  range.deleteContents();
173
180
 
174
181
  if (vditor.options.hint.parse) {
175
- if (vditor.currentMode === "sv") {
176
- insertHTML(vditor.lute.SpinVditorSVDOM(value), vditor);
177
- } else if (vditor.currentMode === "wysiwyg") {
182
+ if (vditor.currentMode === "wysiwyg") {
178
183
  insertHTML(vditor.lute.SpinVditorDOM(value), vditor);
179
184
  } else {
180
185
  insertHTML(vditor.lute.SpinVditorIRDOM(value), vditor);
@@ -182,7 +187,7 @@ ${i === 0 ? "class='vditor-hint--current'" : ""}> ${html}</button>`;
182
187
  } else {
183
188
  insertHTML(value, vditor);
184
189
  }
185
- if (this.splitChar === ":" && value.indexOf(":") > -1 && vditor.currentMode !== "sv") {
190
+ if (this.splitChar === ":" && value.indexOf(":") > -1) {
186
191
  range.insertNode(document.createTextNode(" "));
187
192
  }
188
193
  range.collapse(false);
@@ -5,12 +5,12 @@ import {hasClosestByHeadings} from "../util/hasClosestByHeadings";
5
5
  import {getEditorRange, selectIsEditor} from "../util/selection";
6
6
 
7
7
  export const highlightToolbarIR = (vditor: IVditor) => {
8
- clearTimeout(vditor[vditor.currentMode].hlToolbarTimeoutId);
9
- vditor[vditor.currentMode].hlToolbarTimeoutId = window.setTimeout(() => {
10
- if (vditor[vditor.currentMode].element.getAttribute("contenteditable") === "false") {
8
+ clearTimeout(vditor.ir.hlToolbarTimeoutId);
9
+ vditor.ir.hlToolbarTimeoutId = window.setTimeout(() => {
10
+ if (vditor.ir.element.getAttribute("contenteditable") === "false") {
11
11
  return;
12
12
  }
13
- if (!selectIsEditor(vditor[vditor.currentMode].element)) {
13
+ if (!selectIsEditor(vditor.ir.element)) {
14
14
  return;
15
15
  }
16
16
 
@@ -11,6 +11,7 @@ import {
11
11
  } from "../util/editorCommonEvent";
12
12
  import {paste} from "../util/fixBrowserBehavior";
13
13
  import {hasClosestByAttribute, hasClosestByClassName} from "../util/hasClosest";
14
+ import {hasClosestByHeadings} from "../util/hasClosestByHeadings";
14
15
  import {
15
16
  getEditorRange, setRangeByWbr,
16
17
  setSelectionFocus,
@@ -22,6 +23,28 @@ import {input} from "./input";
22
23
  import {processAfterRender, processHint} from "./process";
23
24
  import {hidePanel} from "../toolbar/setToolbar";
24
25
 
26
+ const getHeadingMarker = (headingElement: Element) => {
27
+ return Array.from(headingElement.children).find((item) => item.getAttribute("data-type") === "heading-marker");
28
+ };
29
+
30
+ const restoreHeadingMarker = (sourceHeading: HTMLElement | false, copiedHeading?: HTMLElement) => {
31
+ if (!sourceHeading || !copiedHeading || sourceHeading.tagName !== copiedHeading.tagName ||
32
+ sourceHeading.getAttribute("data-marker") !== copiedHeading.getAttribute("data-marker") ||
33
+ copiedHeading.textContent.trim() === "" || getHeadingMarker(copiedHeading)) {
34
+ return;
35
+ }
36
+
37
+ const markerElement = getHeadingMarker(sourceHeading);
38
+ if (!markerElement) {
39
+ return;
40
+ }
41
+ if (sourceHeading.firstElementChild === markerElement) {
42
+ copiedHeading.insertBefore(markerElement.cloneNode(true), copiedHeading.firstChild);
43
+ } else if (sourceHeading.lastElementChild === markerElement) {
44
+ copiedHeading.appendChild(markerElement.cloneNode(true));
45
+ }
46
+ };
47
+
25
48
  class IR {
26
49
  public range: Range;
27
50
  public element: HTMLPreElement;
@@ -61,6 +84,9 @@ class IR {
61
84
 
62
85
  const tempElement = document.createElement("div");
63
86
  tempElement.appendChild(range.cloneContents());
87
+ const copiedHeadings = tempElement.querySelectorAll<HTMLElement>("h1, h2, h3, h4, h5, h6");
88
+ restoreHeadingMarker(hasClosestByHeadings(range.startContainer), copiedHeadings.item(0));
89
+ restoreHeadingMarker(hasClosestByHeadings(range.endContainer), copiedHeadings.item(copiedHeadings.length - 1));
64
90
 
65
91
  event.clipboardData.setData("text/plain", vditor.lute.VditorIRDOM2Md(tempElement.innerHTML).trim());
66
92
  event.clipboardData.setData("text/html", "");