vditor 3.11.1 → 3.11.3

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 (52) hide show
  1. package/README.md +13 -2
  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 +133 -4
  7. package/dist/index.js +715 -57
  8. package/dist/index.min.js +1 -1
  9. package/dist/js/i18n/es_ES.js +86 -0
  10. package/dist/js/i18n/ja_JP.js +2 -2
  11. package/dist/js/i18n/vi_VN.js +86 -0
  12. package/dist/js/i18n/zh_TW.js +8 -8
  13. package/dist/js/icons/ant.js +1 -1
  14. package/dist/js/icons/material.js +1 -1
  15. package/dist/js/lute/lute.min.js +87 -71
  16. package/dist/js/mermaid/mermaid.min.js +2027 -1047
  17. package/dist/js/wavedrom/LICENSE.WaveDrom +21 -0
  18. package/dist/js/wavedrom/wavedrom.min.js +9 -0
  19. package/dist/method.d.ts +2 -0
  20. package/dist/method.js +319 -8
  21. package/dist/method.min.js +1 -1
  22. package/dist/ts/constants.d.ts +4 -0
  23. package/dist/ts/markdown/adapterRender.d.ts +4 -0
  24. package/dist/ts/markdown/imageCaptionRender.d.ts +2 -0
  25. package/dist/ts/markdown/wavedromRender.d.ts +1 -0
  26. package/dist/ts/util/fixBrowserBehavior.d.ts +1 -0
  27. package/dist/types/index.d.ts +47 -3
  28. package/package.json +7 -4
  29. package/src/assets/less/_reset.less +103 -2
  30. package/src/assets/less/index.less +20 -0
  31. package/src/index.ts +4 -1
  32. package/src/method.ts +3 -0
  33. package/src/ts/constants.ts +5 -1
  34. package/src/ts/export/index.ts +2 -0
  35. package/src/ts/ir/index.ts +26 -0
  36. package/src/ts/ir/process.ts +24 -1
  37. package/src/ts/markdown/adapterRender.ts +4 -0
  38. package/src/ts/markdown/getHTML.ts +6 -3
  39. package/src/ts/markdown/imageCaptionRender.ts +175 -0
  40. package/src/ts/markdown/mermaidRender.ts +1 -1
  41. package/src/ts/markdown/previewRender.ts +8 -2
  42. package/src/ts/markdown/setLute.ts +3 -0
  43. package/src/ts/markdown/wavedromRender.ts +54 -0
  44. package/src/ts/preview/index.ts +5 -0
  45. package/src/ts/util/Options.ts +1 -1
  46. package/src/ts/util/fixBrowserBehavior.ts +165 -21
  47. package/src/ts/util/processCode.ts +3 -0
  48. package/src/ts/util/selection.ts +7 -2
  49. package/src/ts/wysiwyg/afterRenderEvent.ts +2 -0
  50. package/src/ts/wysiwyg/highlightToolbarWYSIWYG.ts +23 -4
  51. package/src/ts/wysiwyg/input.ts +5 -0
  52. package/src/ts/wysiwyg/setHeading.ts +110 -6
@@ -1,7 +1,94 @@
1
- import {hasClosestBlock} from "../util/hasClosest";
1
+ import {hasClosestBlock, hasClosestByMatchTag} from "../util/hasClosest";
2
2
  import {getEditorRange, setRangeByWbr} from "../util/selection";
3
3
  import {renderToc} from "../util/toc";
4
4
 
5
+ const createBlockElement = (element: HTMLElement, tagName: string) => {
6
+ const blockElement = element.ownerDocument.createElement(tagName);
7
+ blockElement.setAttribute("data-block", "0");
8
+ return blockElement;
9
+ };
10
+
11
+ const replaceBlockElement = (element: HTMLElement, tagName: string) => {
12
+ const blockElement = createBlockElement(element, tagName);
13
+ while (element.firstChild) {
14
+ blockElement.appendChild(element.firstChild);
15
+ }
16
+ element.replaceWith(blockElement);
17
+ return blockElement;
18
+ };
19
+
20
+ const isListItemBlock = (node: Node) => {
21
+ if (node.nodeType !== 1) {
22
+ return false;
23
+ }
24
+ const element = node as HTMLElement;
25
+ return element.getAttribute("data-block") === "0" || element.tagName === "INPUT";
26
+ };
27
+
28
+ const getListItemInlineNodes = (itemElement: HTMLElement, wbrElement: HTMLElement) => {
29
+ let anchorNode: Node = wbrElement;
30
+ while (anchorNode.parentNode && !anchorNode.parentNode.isSameNode(itemElement)) {
31
+ anchorNode = anchorNode.parentNode;
32
+ }
33
+ if (!anchorNode.parentNode?.isSameNode(itemElement)) {
34
+ return [];
35
+ }
36
+
37
+ let firstNode = anchorNode;
38
+ let lastNode = anchorNode;
39
+ while (firstNode.previousSibling && !isListItemBlock(firstNode.previousSibling)) {
40
+ firstNode = firstNode.previousSibling;
41
+ }
42
+ while (lastNode.nextSibling && !isListItemBlock(lastNode.nextSibling)) {
43
+ lastNode = lastNode.nextSibling;
44
+ }
45
+
46
+ // 任务列表的复选框和正文之间需要保留分隔空格。
47
+ if (firstNode.previousSibling instanceof HTMLInputElement && firstNode.nodeType === 3) {
48
+ const leadingWhitespace = firstNode.textContent.match(/^\s+/)?.[0];
49
+ if (leadingWhitespace) {
50
+ firstNode.textContent = firstNode.textContent.substring(leadingWhitespace.length);
51
+ itemElement.insertBefore(itemElement.ownerDocument.createTextNode(leadingWhitespace), firstNode);
52
+ }
53
+ }
54
+
55
+ const nodes: Node[] = [];
56
+ let node: Node = firstNode;
57
+ while (node) {
58
+ nodes.push(node);
59
+ if (node.isSameNode(lastNode)) {
60
+ break;
61
+ }
62
+ node = node.nextSibling;
63
+ }
64
+ return nodes;
65
+ };
66
+
67
+ const setListItemHeading = (itemElement: HTMLElement, wbrElement: HTMLElement, tagName: string) => {
68
+ const inlineNodes = getListItemInlineNodes(itemElement, wbrElement);
69
+ if (inlineNodes.length === 0) {
70
+ return false;
71
+ }
72
+
73
+ const headingElement = createBlockElement(itemElement, tagName);
74
+ itemElement.insertBefore(headingElement, inlineNodes[0]);
75
+ inlineNodes.forEach((node) => {
76
+ headingElement.appendChild(node);
77
+ });
78
+ if (headingElement.innerHTML.trim() === "<wbr>") {
79
+ headingElement.appendChild(itemElement.ownerDocument.createElement("br"));
80
+ }
81
+ return true;
82
+ };
83
+
84
+ const unwrapBlockElement = (element: HTMLElement) => {
85
+ const fragment = element.ownerDocument.createDocumentFragment();
86
+ while (element.firstChild) {
87
+ fragment.appendChild(element.firstChild);
88
+ }
89
+ element.replaceWith(fragment);
90
+ };
91
+
5
92
  export const setHeading = (vditor: IVditor, tagName: string) => {
6
93
  const range = getEditorRange(vditor);
7
94
  let blockElement = hasClosestBlock(range.startContainer);
@@ -12,16 +99,27 @@ export const setHeading = (vditor: IVditor, tagName: string) => {
12
99
  blockElement = vditor.wysiwyg.element;
13
100
  }
14
101
  if (blockElement && !blockElement.classList.contains("vditor-wysiwyg__block")) {
15
- range.insertNode(document.createElement("wbr"));
102
+ const wbrElement = document.createElement("wbr");
103
+ range.insertNode(wbrElement);
16
104
  // Firefox 需要 trim https://github.com/Vanessa219/vditor/issues/207
17
105
  if (blockElement.innerHTML.trim() === "<wbr>") {
18
106
  // Firefox 光标对不齐 https://github.com/Vanessa219/vditor/issues/199 1
19
107
  blockElement.innerHTML = "<wbr><br>";
20
108
  }
21
- if (blockElement.tagName === "BLOCKQUOTE" || blockElement.classList.contains("vditor-reset")) {
22
- blockElement.innerHTML = `<${tagName} data-block="0">${blockElement.innerHTML.trim()}</${tagName}>`;
109
+ const itemElement = hasClosestByMatchTag(wbrElement, "LI");
110
+ if (itemElement && blockElement.isSameNode(itemElement.parentElement)) {
111
+ if (!setListItemHeading(itemElement, wbrElement, tagName)) {
112
+ wbrElement.remove();
113
+ return;
114
+ }
115
+ } else if (blockElement.tagName === "BLOCKQUOTE" || blockElement.classList.contains("vditor-reset")) {
116
+ const headingElement = createBlockElement(blockElement, tagName);
117
+ while (blockElement.firstChild) {
118
+ headingElement.appendChild(blockElement.firstChild);
119
+ }
120
+ blockElement.appendChild(headingElement);
23
121
  } else {
24
- blockElement.outerHTML = `<${tagName} data-block="0">${blockElement.innerHTML.trim()}</${tagName}>`;
122
+ replaceBlockElement(blockElement, tagName);
25
123
  }
26
124
  setRangeByWbr(vditor.wysiwyg.element, range);
27
125
  renderToc(vditor);
@@ -36,8 +134,14 @@ export const removeHeading = (vditor: IVditor) => {
36
134
  }
37
135
  if (blockElement) {
38
136
  range.insertNode(document.createElement("wbr"));
39
- blockElement.outerHTML = `<p data-block="0">${blockElement.innerHTML}</p>`;
137
+ if (blockElement.parentElement?.tagName === "LI" &&
138
+ blockElement.parentElement.parentElement?.getAttribute("data-tight") === "true") {
139
+ unwrapBlockElement(blockElement);
140
+ } else {
141
+ replaceBlockElement(blockElement, "p");
142
+ }
40
143
  setRangeByWbr(vditor.wysiwyg.element, range);
144
+ renderToc(vditor);
41
145
  }
42
146
  vditor.wysiwyg.popover.style.display = "none";
43
147
  };