Browse Source

:sparkles: #94

Liyuan Li 5 years ago
parent
commit
29ce633214

+ 12 - 4
demo/static.html

@@ -35,7 +35,7 @@
     <meta property="og:image" content="https://cdn.jsdelivr.net/npm/vditor/dist/images/logo.png"/>
     <meta name="twitter:image" content="https://cdn.jsdelivr.net/npm/vditor/dist/images/logo.png"/>
     <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vditor@latest/dist/index.css"/>
-    <script src="https://cdn.jsdelivr.net/npm/vditor@3.0.11/dist/index.min.js"></script>
+    <script src="https://cdn.jsdelivr.net/npm/vditor@3.1.6/dist/index.min.js"></script>
 </head>
 <body>
 <h2><a href="https://hacpai.com/article/1549638745630?r=Vanessa" target="_blank">Doc</a></h2>
@@ -57,16 +57,24 @@
 </ul>
 </div>
 <script>
-  const vditor = new Vditor('vditor', {
+  window.vditor = new Vditor('vditor', {
     debugger: true,
     typewriterMode: true,
     placeholder: 'placeholder',
-    counter: 100,
-    height: 500,
     preview: {
       markdown: {
         toc: true,
       },
+      hljs: {
+        style: 'native',
+      },
+    },
+    toolbarConfig: {
+      pin: true,
+    },
+    counter: {
+      enable: true,
+      type: 'text',
     },
     hint: {
       emojiPath: 'https://cdn.jsdelivr.net/npm/[email protected]/dist/images/emoji',

+ 12 - 2
src/assets/scss/_content.scss

@@ -237,15 +237,25 @@
   &-outline {
     width: 250px;
     border-right: 1px solid var(--border-color);
-    background-color: var(--textarea-background-color);
+    background-color: var(--panel-background-color);
     display: none;
 
+    &__item {
+      padding: 5px 10px;
+      cursor: pointer;
+      &:hover {
+        color: var(--toolbar-icon-hover-color);
+        background-color: var(--toolbar-background-color);
+      }
+    }
+
     & > div {
       position: sticky;
       overflow: auto;
       top: 35px;
-      padding: 10px;
+      padding: 10px 0;
       max-height: 100vh;
+      color: var(--textarea-text-color);
 
       &::-webkit-scrollbar {
         display: none;

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


+ 10 - 6
src/ts/hint/index.ts

@@ -84,7 +84,11 @@ export class Hint {
 
         const editorElement = vditor[vditor.currentMode].element;
         const textareaPosition = getCursorPosition(editorElement);
-        const x = textareaPosition.left;
+        let x = textareaPosition.left;
+        const outlineElement = vditor.element.querySelector(".vditor-outline") as HTMLElement;
+        if (outlineElement) {
+            x = x + outlineElement.offsetWidth;
+        }
         const y = textareaPosition.top;
         let hintsHTML = "";
 
@@ -174,11 +178,11 @@ ${i === 0 ? "class='vditor-hint--current'" : ""}> ${html}</button>`;
             setSelectionFocus(range);
 
             if (vditor.currentMode === "wysiwyg") {
-                 const preElement = hasClosestByClassName(range.startContainer, "vditor-wysiwyg__block");
-                 if (preElement && preElement.lastElementChild.classList.contains("vditor-wysiwyg__preview")) {
-                     preElement.lastElementChild.innerHTML = preElement.firstElementChild.innerHTML;
-                     processCodeRender(preElement.lastElementChild as HTMLElement, vditor);
-                 }
+                const preElement = hasClosestByClassName(range.startContainer, "vditor-wysiwyg__block");
+                if (preElement && preElement.lastElementChild.classList.contains("vditor-wysiwyg__preview")) {
+                    preElement.lastElementChild.innerHTML = preElement.firstElementChild.innerHTML;
+                    processCodeRender(preElement.lastElementChild as HTMLElement, vditor);
+                }
             } else {
                 const preElement = hasClosestByClassName(range.startContainer, "vditor-ir__marker--pre");
                 if (preElement && preElement.nextElementSibling.classList.contains("vditor-ir__preview")) {

+ 28 - 6
src/ts/markdown/outlineRender.ts

@@ -1,18 +1,40 @@
 import {hasClosestByHeadings} from "../util/hasClosestByHEadings";
 
-export const outlineRender = (contentElement: HTMLElement, targetElement: Element) => {
+export const outlineRender = (contentElement: HTMLElement, targetElement: Element, vditor?: IVditor) => {
     let tocHTML = "";
-    const isIR = contentElement.parentElement.classList.contains("vditor-ir");
     Array.from(contentElement.children).forEach((item: HTMLElement) => {
         if (hasClosestByHeadings(item)) {
             const headingNo = parseInt(item.tagName.substring(1), 10);
             const space = new Array((headingNo - 1) * 2).fill("&emsp;").join("");
-            if (isIR) {
-                tocHTML += `${space}<span data-type="toc-h">${item.textContent.substring(headingNo + 1).trim()}</span><br>`;
+            let text = "";
+            if (vditor && vditor.currentMode === "ir") {
+                text = item.textContent.substring(headingNo + 1).trim();
             } else {
-                tocHTML += `${space}<span data-type="toc-h">${item.textContent.trim()}</span><br>`;
+                text = item.textContent.trim();
+            }
+            tocHTML += `<div data-id="${item.id}" class="vditor-outline__item">${space}${text}</div>`;
+        }
+    });
+    targetElement.innerHTML = tocHTML || "<div>Outline</div>";
+
+    targetElement.addEventListener("click", (event: Event & { target: HTMLElement }) => {
+        const itemElement = event.target;
+        if (itemElement.classList.contains("vditor-outline__item")) {
+            if (vditor) {
+                const id = itemElement.getAttribute("data-id");
+                if (vditor.options.height === "auto") {
+                    let windowScrollY = document.getElementById(id).offsetTop + vditor.element.offsetTop
+                    if (!vditor.options.toolbarConfig.pin) {
+                        windowScrollY += vditor.toolbar.element.offsetHeight
+                    }
+                    window.scrollTo(window.scrollX, windowScrollY);
+                } else {
+                    if (vditor.element.offsetTop < window.scrollY) {
+                        window.scrollTo(window.scrollX, vditor.element.offsetTop);
+                    }
+                    contentElement.scrollTop = document.getElementById(id).offsetTop;
+                }
             }
         }
     });
-    targetElement.innerHTML = tocHTML || 'Outline';
 };

+ 5 - 1
src/ts/ui/initUI.ts

@@ -26,7 +26,11 @@ export const initUI = (vditor: IVditor) => {
     if (vditor.toolbar.elements.outline) {
         const outlineElement = document.createElement("div");
         outlineElement.className = "vditor-outline";
-        outlineElement.innerHTML = `<div style='top:${vditor.toolbar.element.clientHeight}px'></div>`;
+        let top = 0
+        if (vditor.options.toolbarConfig.pin) {
+            top = vditor.toolbar.element.clientHeight
+        }
+        outlineElement.innerHTML = `<div style='top:${top}px'></div>`;
         contentElement.appendChild(outlineElement);
     }
 

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

@@ -342,7 +342,7 @@ export const isToC = (text: string) => {
 export const renderOutline = (vditor: IVditor) => {
     const outlineElement = vditor.element.querySelector(".vditor-outline") as HTMLElement;
     if (outlineElement && outlineElement.style.display === "block") {
-        outlineRender(vditor[vditor.currentMode].element, outlineElement.firstElementChild);
+        outlineRender(vditor[vditor.currentMode].element, outlineElement.firstElementChild, vditor);
     }
 };
 

+ 1 - 1
src/ts/wysiwyg/index.ts

@@ -87,7 +87,7 @@ class WYSIWYG {
                 return;
             }
             const top = parseInt(this.popover.getAttribute("data-top"), 10) - vditor.wysiwyg.element.scrollTop;
-            let max = -8
+            let max = -8;
             if (vditor.options.toolbarConfig.pin && vditor.toolbar.element.getBoundingClientRect().top === 0) {
                 max = window.scrollY - vditor.element.offsetTop + max;
             }

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