Browse Source

:art: #325 markdown

Liyuan Li 5 years ago
parent
commit
e0f7bea737
7 changed files with 77 additions and 12 deletions
  1. 1 0
      CHANGELOG.md
  2. 1 0
      demo/index.js
  3. 14 0
      src/ts/export/markdown.ts
  4. 3 0
      src/ts/i18n/index.ts
  5. 36 0
      src/ts/toolbar/Export.ts
  6. 16 12
      src/ts/toolbar/index.ts
  7. 6 0
      src/ts/util/Options.ts

+ 1 - 0
CHANGELOG.md

@@ -59,6 +59,7 @@
 
 ### v3.1.19 / 2020-04-2x
 
+* [325](https://github.com/Vanessa219/vditor/issues/325) 导出功能 `引入特性`
 * [324](https://github.com/Vanessa219/vditor/issues/324) 支持多款主题预览 `引入特性`
 * [341](https://github.com/Vanessa219/vditor/issues/341) Can not delete the image at IR mode `修复缺陷`
 

+ 1 - 0
demo/index.js

@@ -34,6 +34,7 @@ if (window.innerWidth < 768) {
     "edit-mode",
     "content-theme",
     "code-theme",
+    "export",
     {
       name: "more",
       toolbar: [

+ 14 - 0
src/ts/export/markdown.ts

@@ -0,0 +1,14 @@
+export const download = (content: string, filename: string) => {
+    const aElement = document.createElement("a");
+    aElement.download = filename;
+    aElement.style.display = "none";
+    aElement.href = URL.createObjectURL(new Blob([content]));
+
+    document.body.appendChild(aElement);
+    aElement.click();
+    aElement.remove();
+};
+
+export const exportMarkdown = (content: string) => {
+    download(content, content.substr(0, 10) + ".md");
+};

+ 3 - 0
src/ts/i18n/index.ts

@@ -19,6 +19,7 @@ export const i18n: II18n = {
         "edit": "Edit",
         "edit-mode": "Toggle Edit Mode",
         "emoji": "Emoji",
+        "export": "Export",
         "fileTypeError": "file type is error",
         "footnoteRef": "Footnote Ref",
         "format": "Format",
@@ -86,6 +87,7 @@ export const i18n: II18n = {
         "edit": "수정",
         "edit-mode": "편집 모드 전환",
         "emoji": "이모지",
+        "export": "내보내기",
         "fileTypeError": "지원하지않습니다.",
         "footnoteRef": "각주 참조",
         "format": "형식",
@@ -153,6 +155,7 @@ export const i18n: II18n = {
         "edit": "编辑",
         "edit-mode": "切换编辑模式",
         "emoji": "表情",
+        "export": "导出",
         "fileTypeError": "文件类型不允许上传",
         "footnoteRef": "脚注标识",
         "format": "格式化",

+ 36 - 0
src/ts/toolbar/Export.ts

@@ -0,0 +1,36 @@
+import {exportMarkdown} from "../export/markdown";
+import {getEventName} from "../util/compatibility";
+import {getMarkdown} from "../util/getMarkdown";
+import {MenuItem} from "./MenuItem";
+import {hidePanel, toggleSubMenu} from "./setToolbar";
+
+export class Export extends MenuItem {
+    public element: HTMLElement;
+
+    constructor(vditor: IVditor, menuItem: IMenuItem) {
+        super(vditor, menuItem);
+
+        const actionBtn = this.element.children[0] as HTMLElement;
+
+        const panelElement = document.createElement("div");
+        panelElement.className = `vditor-hint${menuItem.level === 2 ? "" : " vditor-panel--arrow"}`;
+        panelElement.innerHTML = `<button data-type="markdown">Markdown</button>`;
+        panelElement.addEventListener(getEventName(), (event: MouseEvent & { target: HTMLElement }) => {
+            const btnElement = event.target;
+            if (btnElement.tagName === "BUTTON") {
+                switch (btnElement.getAttribute("data-type")) {
+                    case "markdown":
+                        exportMarkdown(getMarkdown(vditor));
+                        break;
+                    default:
+                        break;
+                }
+                hidePanel(vditor, ["subToolbar"]);
+                event.preventDefault();
+                event.stopPropagation();
+            }
+        });
+        this.element.appendChild(panelElement);
+        toggleSubMenu(vditor, panelElement, actionBtn, menuItem.level);
+    }
+}

+ 16 - 12
src/ts/toolbar/index.ts

@@ -9,6 +9,7 @@ import {Devtools} from "./Devtools";
 import {Divider} from "./Divider";
 import {EditMode} from "./EditMode";
 import {Emoji} from "./Emoji";
+import {Export} from "./Export";
 import {Format} from "./Format";
 import {Fullscreen} from "./Fullscreen";
 import {Headings} from "./Headings";
@@ -72,18 +73,6 @@ export class Toolbar {
     private genItem(vditor: IVditor, menuItem: IMenuItem, index: number) {
         let menuItemObj;
         switch (menuItem.name) {
-            case "emoji":
-                menuItemObj = new Emoji(vditor, menuItem);
-                break;
-            case "headings":
-                menuItemObj = new Headings(vditor, menuItem);
-                break;
-            case "|":
-                menuItemObj = new Divider();
-                break;
-            case "br":
-                menuItemObj = new Br();
-                break;
             case "bold":
             case "italic":
             case "more":
@@ -99,6 +88,18 @@ export class Toolbar {
             case "table":
                 menuItemObj = new MenuItem(vditor, menuItem);
                 break;
+            case "emoji":
+                menuItemObj = new Emoji(vditor, menuItem);
+                break;
+            case "headings":
+                menuItemObj = new Headings(vditor, menuItem);
+                break;
+            case "|":
+                menuItemObj = new Divider();
+                break;
+            case "br":
+                menuItemObj = new Br();
+                break;
             case "undo":
                 menuItemObj = new Undo(vditor, menuItem);
                 break;
@@ -156,6 +157,9 @@ export class Toolbar {
             case "content-theme":
                 menuItemObj = new ContentTheme(vditor, menuItem);
                 break;
+            case "export":
+                menuItemObj = new Export(vditor, menuItem);
+                break;
             default:
                 menuItemObj = new Custom(vditor, menuItem);
                 break;

+ 6 - 0
src/ts/util/Options.ts

@@ -9,6 +9,7 @@ import codeThemeSVG from "../../assets/icons/code-theme.svg";
 import codeSVG from "../../assets/icons/code.svg";
 import editSVG from "../../assets/icons/edit.svg";
 import emojiSVG from "../../assets/icons/emoji.svg";
+import exportSVG from "../../assets/icons/export.svg";
 import fullscreenSVG from "../../assets/icons/fullscreen.svg";
 import headingsSVG from "../../assets/icons/headings.svg";
 import helpSVG from "../../assets/icons/help.svg";
@@ -142,6 +143,7 @@ export class Options {
                     "content-theme",
                     "code-theme",
                     "devtools",
+                    "export",
                     "info",
                     "help",
                 ],
@@ -163,6 +165,10 @@ export class Options {
     };
 
     private toolbarItem = [{
+        icon: exportSVG,
+        name: "export",
+        tipPosition: "ne",
+    }, {
         hotkey: "⌘-E",
         icon: emojiSVG,
         name: "emoji",