Liyuan Li 5 years ago
parent
commit
cd2f6ece64

+ 4 - 2
CHANGELOG.md

@@ -64,10 +64,12 @@
 * [open issues](https://github.com/Vanessa219/vditor/issues)
 * [346](https://github.com/Vanessa219/vditor/issues/346) 内容主题推荐(长期有效) `改进功能`
 
-### v3.2.0 / 2020-05-0x
+### v3.2.3 / 2020-05-0x
 
-### v3.2.1 / 2020-05-07
 
+### v3.2.2 / 2020-05-08
+
+* [4](https://github.com/Vanessa219/vditor/issues/4) 添加支持思维导图的功能 `引入特性`
 * [376](https://github.com/Vanessa219/vditor/issues/376) 为 markdown 添加 sanitize 设置 `引入特性`
 * [375](https://github.com/Vanessa219/vditor/pull/375) upload 配置项添加额外请求参数 `引入特性`
 * [372](https://github.com/Vanessa219/vditor/issues/372) 配置lineNumber为true后,代码复制按钮不出现 `修复缺陷`

+ 1 - 1
package-lock.json

@@ -1,6 +1,6 @@
 {
   "name": "vditor",
-  "version": "3.2.1",
+  "version": "3.2.2",
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "vditor",
-  "version": "3.2.1",
+  "version": "3.2.2",
   "description": "♏ 一款浏览器端的 Markdown 编辑器。",
   "author": "Vanessa <[email protected]> (http://vanessa.b3log.org)",
   "homepage": "https://hacpai.com/tag/vditor",

+ 3 - 1
src/assets/scss/_ir.scss

@@ -91,8 +91,10 @@
           .language-mermaid,
           .language-math,
           .language-graphviz,
-          .language-echarts {
+          .language-echarts,
+          .language-mindmap {
             background-color: var(--code-background-color) !important;
+            height: auto;
           }
         }
       }

+ 4 - 2
src/assets/scss/_reset.scss

@@ -195,7 +195,8 @@
       &.language-mermaid,
       &.language-math,
       &.language-graphviz,
-      &.language-echarts {
+      &.language-echarts,
+      &.language-mindmap {
         background-color: rgba(27, 31, 35, .02);
       }
     }
@@ -255,7 +256,8 @@
       margin-bottom: 0;
     }
 
-    .language-echarts {
+    .language-echarts,
+    .language-mindmap {
       overflow: hidden;
       height: 420px;
     }

+ 1 - 0
src/assets/scss/_wysiwyg.scss

@@ -56,6 +56,7 @@
       margin-bottom: -1em;
 
       code {
+        height: auto;
         background-color: var(--code-background-color) !important;
       }
     }

+ 5 - 1
src/css/content-theme/dark.css

@@ -66,7 +66,11 @@
     background-color: rgba(66, 133, 244, .36)
 }
 
-.vditor-reset code:not(.hljs):not(.highlight-chroma).language-echarts, .vditor-reset code:not(.hljs):not(.highlight-chroma).language-graphviz, .vditor-reset code:not(.hljs):not(.highlight-chroma).language-math, .vditor-reset code:not(.hljs):not(.highlight-chroma).language-mermaid {
+.vditor-reset code:not(.hljs):not(.highlight-chroma).language-echarts,
+.vditor-reset code:not(.hljs):not(.highlight-chroma).language-mindmap,
+.vditor-reset code:not(.hljs):not(.highlight-chroma).language-graphviz,
+.vditor-reset code:not(.hljs):not(.highlight-chroma).language-math,
+.vditor-reset code:not(.hljs):not(.highlight-chroma).language-mermaid {
     background-color: rgba(120, 146, 190, .55)
 }
 

+ 5 - 1
src/css/content-theme/wechat.css

@@ -82,7 +82,11 @@
     border-radius: 2px;
 }
 
-.vditor-reset code:not(.hljs):not(.highlight-chroma).language-echarts, .vditor-reset code:not(.hljs):not(.highlight-chroma).language-graphviz, .vditor-reset code:not(.hljs):not(.highlight-chroma).language-math, .vditor-reset code:not(.hljs):not(.highlight-chroma).language-mermaid {
+.vditor-reset code:not(.hljs):not(.highlight-chroma).language-echarts,
+.vditor-reset code:not(.hljs):not(.highlight-chroma).language-mindmap,
+.vditor-reset code:not(.hljs):not(.highlight-chroma).language-graphviz,
+.vditor-reset code:not(.hljs):not(.highlight-chroma).language-math,
+.vditor-reset code:not(.hljs):not(.highlight-chroma).language-mermaid {
     background-color: rgba(0, 0, 0, 0.03);
     font-size: 14px;
     border: 1px solid #f0f0f0;

File diff suppressed because it is too large
+ 0 - 0
src/js/lute/lute.min.js


+ 3 - 0
src/method.ts

@@ -7,6 +7,7 @@ import {lazyLoadImageRender} from "./ts/markdown/lazyLoadImageRender";
 import {mathRender} from "./ts/markdown/mathRender";
 import {mediaRender} from "./ts/markdown/mediaRender";
 import {mermaidRender} from "./ts/markdown/mermaidRender";
+import {mindmapRender} from "./ts/markdown/mindmapRender";
 import {outlineRender} from "./ts/markdown/outlineRender";
 import {md2html, previewRender} from "./ts/markdown/previewRender";
 import {speechRender} from "./ts/markdown/speechRender";
@@ -28,6 +29,8 @@ class Vditor {
     public static chartRender = chartRender;
     /** 五线谱渲染 */
     public static abcRender = abcRender;
+    /** 脑图渲染 */
+    public static mindmapRender = mindmapRender;
     /** 大纲渲染 */
     public static outlineRender = outlineRender;
     /** 为[特定链接](https://github.com/Vanessa219/vditor/issues/7)分别渲染为视频、音频、嵌入的 iframe */

+ 4 - 1
src/ts/constants.ts

@@ -15,9 +15,10 @@ export abstract class Constants {
         "native", "paraiso-dark", "paraiso-light", "pastie", "perldoc", "pygments", "rainbow_dash", "rrt",
         "solarized-dark", "solarized-dark256", "solarized-light", "swapoff", "tango", "trac", "vim", "vs", "xcode"];
     public static readonly CODE_LANGUAGES: string[] = [
-        "abc",
         "mermaid",
         "echarts",
+        "mindmap",
+        "abc",
         "graphviz",
         "apache",
         "bash",
@@ -32,6 +33,7 @@ export abstract class Constants {
         "json",
         "java",
         "javascript",
+        "js",
         "makefile",
         "markdown",
         "nginx",
@@ -55,6 +57,7 @@ export abstract class Constants {
         "rust",
         "scss",
         "typescript",
+        "ts",
         "yaml",
     ];
 }

+ 1 - 0
src/ts/export/index.ts

@@ -70,6 +70,7 @@ export const exportHTML = (vditor: IVditor) => {
     Vditor.mermaidRender(previewElement, ".language-mermaid", '${vditor.options.cdn}');
     Vditor.graphvizRender(previewElement, '${vditor.options.cdn}');
     Vditor.chartRender(previewElement, '${vditor.options.cdn}');
+    Vditor.mindmapRender(previewElement, '${vditor.options.cdn}');
     Vditor.abcRender(previewElement, '${vditor.options.cdn}');
     Vditor.mediaRender(previewElement);
 </script></body></html>`;

+ 1 - 1
src/ts/markdown/chartRender.ts

@@ -19,7 +19,7 @@ export const chartRender = (element: (HTMLElement | Document) = document,
                     echarts.init(e).setOption(option);
                     e.setAttribute("data-processed", "true");
                 } catch (error) {
-                    e.className = "hljs";
+                    e.className = "vditor-reset--error";
                     e.innerHTML = `echarts render error: <br>${error}`;
                 }
             });

+ 3 - 2
src/ts/markdown/codeRender.ts

@@ -4,8 +4,9 @@ import {code160to32} from "../util/code160to32";
 
 export const codeRender = (element: HTMLElement, lang: (keyof II18nLang) = "zh_CN") => {
     element.querySelectorAll("pre > code").forEach((e: HTMLElement, index: number) => {
-        if (e.classList.contains("language-mermaid") || e.classList.contains("language-echarts")
-            || e.classList.contains("language-abc") || e.classList.contains("language-graphviz")) {
+        if (e.classList.contains("language-mermaid") || e.classList.contains("language-echarts") ||
+            e.classList.contains("language-mindmap")  || e.classList.contains("language-abc") ||
+            e.classList.contains("language-graphviz")) {
             return;
         }
 

+ 1 - 0
src/ts/markdown/highlightRender.ts

@@ -37,6 +37,7 @@ export const highlightRender = (hljsOption?: IHljs, element: HTMLElement | Docum
             }
 
             if (block.classList.contains("language-mermaid") || block.classList.contains("language-echarts")
+                || block.classList.contains("language-mindmap")
                 || block.classList.contains("language-abc") || block.classList.contains("language-graphviz")) {
                 return;
             }

+ 61 - 0
src/ts/markdown/mindmapRender.ts

@@ -0,0 +1,61 @@
+import {VDITOR_VERSION} from "../constants";
+import {addScript} from "../util/addScript";
+
+declare const echarts: {
+    init(element: HTMLElement): IEChart;
+};
+
+export const mindmapRender = (element: (HTMLElement | Document) = document,
+                              cdn = `https://cdn.jsdelivr.net/npm/vditor@${VDITOR_VERSION}`) => {
+    const mindmapElements = element.querySelectorAll(".language-mindmap");
+    if (mindmapElements.length > 0) {
+        addScript(`${cdn}/dist/js/echarts/echarts.min.js`, "vditorEchartsScript").then(() => {
+            mindmapElements.forEach((e: HTMLDivElement) => {
+                try {
+                    if (e.getAttribute("data-processed") === "true") {
+                        return;
+                    }
+                    const option = {
+                        series: [
+                            {
+                                data: [JSON.parse(Lute.RenderMindmap(e.innerText))],
+                                edgeForkPosition: "100%",
+                                edgeShape: "polyline",
+                                expandAndCollapse: true,
+                                label: {
+                                    backgroundColor: "#f6f8fa",
+                                    borderColor: "#d1d5da",
+                                    borderRadius: 5,
+                                    borderWidth: 0.5,
+                                    color: "#4285f4",
+                                    padding:  [3, 4, 5, 6],
+                                    position: [6, -20],
+                                },
+                                leaves: {
+                                    label: {
+                                        color: "#586069",
+                                    },
+                                },
+                                lineStyle: {
+                                    color: "#d1d5da",
+                                    width: 1,
+                                },
+                                symbolSize: 5,
+                                type: "tree",
+                            },
+                        ],
+                        tooltip: {
+                            trigger: "item",
+                            triggerOn: "mousemove",
+                        },
+                    };
+                    echarts.init(e).setOption(option);
+                    e.setAttribute("data-processed", "true");
+                } catch (error) {
+                    e.className = "vditor-reset--error";
+                    e.innerHTML = `mindmap render error: <br>${error}`;
+                }
+            });
+        });
+    }
+};

+ 2 - 0
src/ts/markdown/previewRender.ts

@@ -11,6 +11,7 @@ import {lazyLoadImageRender} from "./lazyLoadImageRender";
 import {mathRender} from "./mathRender";
 import {mediaRender} from "./mediaRender";
 import {mermaidRender} from "./mermaidRender";
+import {mindmapRender} from "./mindmapRender";
 import {setLute} from "./setLute";
 import {speechRender} from "./speechRender";
 
@@ -114,6 +115,7 @@ export const previewRender = async (previewElement: HTMLDivElement, markdown: st
     mermaidRender(previewElement, ".language-mermaid", mergedOptions.cdn);
     graphvizRender(previewElement, mergedOptions.cdn);
     chartRender(previewElement, mergedOptions.cdn);
+    mindmapRender(previewElement, mergedOptions.cdn);
     abcRender(previewElement, mergedOptions.cdn);
     mediaRender(previewElement);
     if (mergedOptions.speech.enable) {

+ 2 - 0
src/ts/preview/index.ts

@@ -9,6 +9,7 @@ import {highlightRender} from "../markdown/highlightRender";
 import {mathRender} from "../markdown/mathRender";
 import {mediaRender} from "../markdown/mediaRender";
 import {mermaidRender} from "../markdown/mermaidRender";
+import {mindmapRender} from "../markdown/mindmapRender";
 import {getEventName} from "../util/compatibility";
 import {hasClosestByTag} from "../util/hasClosestByHEadings";
 import {setSelectionFocus} from "../util/selection";
@@ -180,6 +181,7 @@ export class Preview {
         mermaidRender(vditor.preview.element.lastElementChild as HTMLElement, ".language-mermaid", vditor.options.cdn);
         graphvizRender(vditor.preview.element.lastElementChild as HTMLElement, vditor.options.cdn);
         chartRender(vditor.preview.element.lastElementChild as HTMLElement, vditor.options.cdn);
+        mindmapRender(vditor.preview.element.lastElementChild as HTMLElement, vditor.options.cdn);
         abcRender(vditor.preview.element.lastElementChild as HTMLElement, vditor.options.cdn);
         mediaRender(vditor.preview.element.lastElementChild as HTMLElement);
     }

+ 8 - 8
src/ts/util/fixBrowserBehavior.ts

@@ -1,4 +1,5 @@
 import {Constants} from "../constants";
+import {highlightToolbar as highlightToolbarIR} from "../ir/highlightToolbar";
 import {processAfterRender} from "../ir/process";
 import {outlineRender} from "../markdown/outlineRender";
 import {uploadFiles} from "../upload";
@@ -19,7 +20,6 @@ import {getLastNode} from "./hasClosest";
 import {hasClosestByHeadings} from "./hasClosestByHEadings";
 import {matchHotKey} from "./hotKey";
 import {getEditorRange, getSelectPosition, insertHTML, setRangeByWbr, setSelectionByPosition} from "./selection";
-import {highlightToolbar as highlightToolbarIR} from "../ir/highlightToolbar";
 
 // https://github.com/Vanessa219/vditor/issues/361
 export const fixCJKPosition = (range: Range, key: string) => {
@@ -47,7 +47,7 @@ export const insertEmptyBlock = (vditor: IVditor, position: InsertPosition) => {
         }
         execAfterRender(vditor);
     }
-}
+};
 
 export const isFirstCell = (cellElement: HTMLElement) => {
     const tableElement = hasClosestByMatchTag(cellElement, "TABLE") as HTMLTableElement;
@@ -612,7 +612,7 @@ export const fixTable = (vditor: IVditor, event: KeyboardEvent, range: Range) =>
             event.preventDefault();
             if (cellElement.tagName === "TH") {
                 if (tableElement.previousElementSibling) {
-                    range.selectNodeContents(tableElement.previousElementSibling)
+                    range.selectNodeContents(tableElement.previousElementSibling);
                     range.collapse(false);
                 } else {
                     insertEmptyBlock(vditor, "beforebegin");
@@ -628,9 +628,9 @@ export const fixTable = (vditor: IVditor, event: KeyboardEvent, range: Range) =>
                 }
             }
 
-            let previousElement = trElement.previousElementSibling as HTMLTableRowElement
+            let previousElement = trElement.previousElementSibling as HTMLTableRowElement;
             if (!previousElement) {
-                previousElement = trElement.parentElement.previousElementSibling.firstChild as HTMLTableRowElement
+                previousElement = trElement.parentElement.previousElementSibling.firstChild as HTMLTableRowElement;
             }
             range.selectNodeContents(previousElement.cells[m]);
             range.collapse(false);
@@ -642,7 +642,7 @@ export const fixTable = (vditor: IVditor, event: KeyboardEvent, range: Range) =>
             const trElement = cellElement.parentElement as HTMLTableRowElement;
             if (!trElement.nextElementSibling && cellElement.tagName === "TD") {
                 if (tableElement.nextElementSibling) {
-                    range.selectNodeContents(tableElement.nextElementSibling)
+                    range.selectNodeContents(tableElement.nextElementSibling);
                     range.collapse(true);
                 } else {
                     insertEmptyBlock(vditor, "afterend");
@@ -657,9 +657,9 @@ export const fixTable = (vditor: IVditor, event: KeyboardEvent, range: Range) =>
                 }
             }
 
-            let nextElement = trElement.nextElementSibling as HTMLTableRowElement
+            let nextElement = trElement.nextElementSibling as HTMLTableRowElement;
             if (!nextElement) {
-                nextElement = trElement.parentElement.nextElementSibling.firstChild as HTMLTableRowElement
+                nextElement = trElement.parentElement.nextElementSibling.firstChild as HTMLTableRowElement;
             }
             range.selectNodeContents(nextElement.cells[m]);
             range.collapse(true);

+ 3 - 0
src/ts/util/processCode.ts

@@ -5,6 +5,7 @@ import {graphvizRender} from "../markdown/graphvizRender";
 import {highlightRender} from "../markdown/highlightRender";
 import {mathRender} from "../markdown/mathRender";
 import {mermaidRender} from "../markdown/mermaidRender";
+import {mindmapRender} from "../markdown/mindmapRender";
 
 export const processPasteCode = (html: string, text: string, type = "sv") => {
     const tempElement = document.createElement("div");
@@ -63,6 +64,8 @@ export const processCodeRender = (previewPanel: HTMLElement, vditor: IVditor) =>
         mermaidRender(previewPanel, `.vditor-${vditor.currentMode}__preview .language-mermaid`, vditor.options.cdn);
     } else if (language === "echarts") {
         chartRender(previewPanel, vditor.options.cdn);
+    }  else if (language === "mindmap") {
+        mindmapRender(previewPanel, vditor.options.cdn);
     } else if (language === "graphviz") {
         graphvizRender(previewPanel, vditor.options.cdn);
     } else if (language === "math") {

+ 2 - 0
types/index.d.ts

@@ -152,6 +152,8 @@ interface ILute {
 
     FormatMd(markdown: string): string;
 
+    RenderMindmap(text: string): string;
+
     // debugger md
     RenderEChartsJSON(text: string): string;
 

Some files were not shown because too many files changed in this diff