Browse Source

:sparkles: paste

Van 6 years ago
parent
commit
019fc182cd

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

@@ -30,6 +30,7 @@
 
     &__preview {
       display: none;
+      white-space: initial;
     }
   }
 }

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

@@ -15,7 +15,7 @@ export const chartRender = (element: (HTMLElement | Document) = document,
                 if (e.getAttribute("data-processed") === "true") {
                     return;
                 }
-                const option = JSON.parse(e.innerHTML.trim());
+                const option = JSON.parse(e.innerText.trim());
                 echarts.init(e).setOption(option);
                 e.setAttribute("data-processed", "true");
             } catch (error) {

+ 3 - 3
src/ts/toolbar/MenuItem.ts

@@ -56,9 +56,9 @@ export class MenuItem {
                         const quoteElement = hasClosestByMatchTag(range.startContainer.nodeType === 3 ?
                             range.startContainer.parentNode as HTMLElement :
                             range.startContainer as HTMLElement, "BLOCKQUOTE");
-                        const tempELement = document.createElement("div");
-                        tempELement.innerHTML = quoteElement.innerHTML;
-                        quoteElement.parentNode.replaceChild(tempELement, quoteElement);
+                        const tempElement = document.createElement("div");
+                        tempElement.innerHTML = quoteElement.innerHTML;
+                        quoteElement.parentNode.replaceChild(tempElement, quoteElement);
                     } else if (commandName === "inline-code") {
                         if (!range.collapsed) {
                             document.execCommand("removeFormat", false, "");

+ 71 - 62
src/ts/wysiwyg/highlightToolbar.ts

@@ -119,9 +119,9 @@ export const highlightToolbar = (vditor: IVditor) => {
         const insertBefore = genInsertBefore(range, blockquoteElement, vditor);
         const insertAfter = genInsertAfter(range, blockquoteElement, vditor);
         const close = genClose(vditor.wysiwyg.popover, blockquoteElement, vditor);
+        vditor.wysiwyg.popover.insertAdjacentElement("beforeend", close);
         vditor.wysiwyg.popover.insertAdjacentElement("beforeend", insertBefore);
         vditor.wysiwyg.popover.insertAdjacentElement("beforeend", insertAfter);
-        vditor.wysiwyg.popover.insertAdjacentElement("beforeend", close);
         setPopoverPosition(vditor, blockquoteElement);
     } else {
         blockquoteElement = undefined;
@@ -205,10 +205,10 @@ export const highlightToolbar = (vditor: IVditor) => {
         };
 
         const close = genClose(vditor.wysiwyg.popover, tableElement, vditor);
+        vditor.wysiwyg.popover.insertAdjacentElement("beforeend", close);
         vditor.wysiwyg.popover.insertAdjacentElement("beforeend", input);
         vditor.wysiwyg.popover.insertAdjacentHTML("beforeend", " x ");
         vditor.wysiwyg.popover.insertAdjacentElement("beforeend", input2);
-        vditor.wysiwyg.popover.insertAdjacentElement("beforeend", close);
         setPopoverPosition(vditor, tableElement);
     }
 
@@ -320,66 +320,9 @@ export const highlightToolbar = (vditor: IVditor) => {
     }
 
     const blockElement = hasClosestByClassName(typeElement, "vditor-wysiwyg__block");
-    // block popover: math-inline, math-block, html-block, html-inline, code-block
     if (blockElement) {
-        const blockType = blockElement.getAttribute("data-type");
-        vditor.wysiwyg.popover.innerHTML = "";
-
-        const language = document.createElement("input");
-        if (blockType.indexOf("block") > -1) {
-            const insertBefore = genInsertBefore(range, blockElement, vditor);
-            const insertAfter = genInsertAfter(range, blockElement, vditor);
-            const close = genClose(vditor.wysiwyg.popover, blockElement, vditor);
-            vditor.wysiwyg.popover.insertAdjacentElement("beforeend", insertBefore);
-            vditor.wysiwyg.popover.insertAdjacentElement("beforeend", insertAfter);
-            vditor.wysiwyg.popover.insertAdjacentElement("beforeend", close);
-
-            if (blockType === "code-block") {
-                const codeElement = blockElement.firstElementChild.firstElementChild;
-
-                const updateLanguage = () => {
-                    codeElement.className = `language-${language.value}`;
-                };
-                language.className = "vditor-input";
-                language.setAttribute("placeholder", "language");
-                language.value = codeElement.className.indexOf("language-") > -1 ?
-                    codeElement.className.split("-")[1].split(" ")[0] : "";
-                language.onblur = updateLanguage;
-                language.onkeypress = (event) => {
-                    if (event.key === "Enter") {
-                        updateLanguage();
-                    }
-                };
-                vditor.wysiwyg.popover.insertAdjacentElement("beforeend", language);
-            }
-        }
-
-        const previewObj = genPreview(() => {
-            if (blockType === "code-block") {
-                previewObj.previewPanel.innerHTML =
-                    `<pre>${blockElement.firstElementChild.innerHTML}</pre>`;
-                if (language.value === "abc") {
-                    abcRender(previewObj.previewPanel, vditor.options.cdn);
-                } else if (language.value === "mermaid") {
-                    mermaidRender(previewObj.previewPanel, ".vditor-wysiwyg__preview .language-mermaid",
-                        vditor.options.cdn);
-                } else if (language.value === "echarts") {
-                    chartRender(previewObj.previewPanel, vditor.options.cdn);
-                } else {
-                    highlightRender(vditor.options.preview.hljs, previewObj.previewPanel, vditor.options.cdn);
-                    codeRender(previewObj.previewPanel, vditor.options.lang);
-                }
-            } else if (blockType.indexOf("html") > -1) {
-                previewObj.previewPanel.innerHTML = blockElement.firstElementChild.innerHTML;
-            } else if (blockType.indexOf("math") > -1) {
-                const tagName = blockType === "math-block" ? "div" : "span";
-                previewObj.previewPanel.innerHTML =
-                    `<${tagName} class="vditor-math">${blockElement.firstChild.textContent}</${tagName}>`;
-                mathRenderByLute(previewObj.previewPanel, vditor.options.cdn);
-            }
-        }, blockElement, blockType.indexOf("block") > -1 ? "div" : "span");
-        vditor.wysiwyg.popover.insertAdjacentElement("beforeend", previewObj.preview);
-        setPopoverPosition(vditor, blockElement);
+        // block popover: math-inline, math-block, html-block, html-inline, code-block
+        genBlockPopover(blockElement, vditor, range);
     }
 
     if (!blockquoteElement && !imgElement && !topListElement && !tableElement && !blockElement
@@ -388,6 +331,68 @@ export const highlightToolbar = (vditor: IVditor) => {
     }
 };
 
+const genBlockPopover = (blockElement: HTMLElement, vditor: IVditor, range: Range) => {
+    const blockType = blockElement.getAttribute("data-type");
+    vditor.wysiwyg.popover.innerHTML = "";
+
+    const language = document.createElement("input");
+    if (blockType.indexOf("block") > -1) {
+        const insertBefore = genInsertBefore(range, blockElement, vditor);
+        const insertAfter = genInsertAfter(range, blockElement, vditor);
+        const close = genClose(vditor.wysiwyg.popover, blockElement, vditor);
+        vditor.wysiwyg.popover.insertAdjacentElement("beforeend", close);
+        vditor.wysiwyg.popover.insertAdjacentElement("beforeend", insertBefore);
+        vditor.wysiwyg.popover.insertAdjacentElement("beforeend", insertAfter);
+
+        if (blockType === "code-block") {
+            const codeElement = blockElement.firstElementChild.firstElementChild;
+
+            const updateLanguage = () => {
+                codeElement.className = `language-${language.value}`;
+            };
+            language.className = "vditor-input";
+            language.setAttribute("placeholder", "language");
+            language.value = codeElement.className.indexOf("language-") > -1 ?
+                codeElement.className.split("-")[1].split(" ")[0] : "";
+            language.onblur = updateLanguage;
+            language.onkeypress = (event) => {
+                if (event.key === "Enter") {
+                    updateLanguage();
+                }
+            };
+            vditor.wysiwyg.popover.insertAdjacentElement("beforeend", language);
+        }
+    }
+
+    const previewObj = genPreview(() => {
+        if (blockType === "code-block") {
+            previewObj.previewPanel.innerHTML =
+                `<pre>${blockElement.firstElementChild.innerHTML}</pre>`;
+            if (language.value === "abc") {
+                abcRender(previewObj.previewPanel, vditor.options.cdn);
+            } else if (language.value === "mermaid") {
+                mermaidRender(previewObj.previewPanel, ".vditor-wysiwyg__preview .language-mermaid",
+                    vditor.options.cdn);
+            } else if (language.value === "echarts") {
+                chartRender(previewObj.previewPanel, vditor.options.cdn);
+            } else {
+                highlightRender(vditor.options.preview.hljs, previewObj.previewPanel, vditor.options.cdn);
+                codeRender(previewObj.previewPanel, vditor.options.lang);
+            }
+        } else if (blockType.indexOf("html") > -1) {
+            previewObj.previewPanel.innerHTML =
+                decodeURIComponent(blockElement.querySelector("code").getAttribute("data-code"));
+        } else if (blockType.indexOf("math") > -1) {
+            const tagName = blockType === "math-block" ? "div" : "span";
+            previewObj.previewPanel.innerHTML =
+                `<${tagName} class="vditor-math">${blockElement.firstChild.textContent}</${tagName}>`;
+            mathRenderByLute(previewObj.previewPanel, vditor.options.cdn);
+        }
+    }, blockElement, blockType.indexOf("block") > -1 ? "div" : "span", vditor, range);
+    vditor.wysiwyg.popover.insertAdjacentElement("beforeend", previewObj.preview);
+    setPopoverPosition(vditor, blockElement);
+};
+
 const setPopoverPosition = (vditor: IVditor, element: HTMLElement) => {
     vditor.wysiwyg.popover.style.top = (element.offsetTop - 27) + "px";
     vditor.wysiwyg.popover.style.left = element.offsetLeft + "px";
@@ -440,13 +445,17 @@ const genClose = (popover: HTMLElement, element: HTMLElement, vditor: IVditor) =
     return close;
 };
 
-const genPreview = (clickEvent: () => void, element: HTMLElement, tagName: string) => {
+const genPreview = (clickEvent: () => void, element: HTMLElement, tagName: string, vditor: IVditor, range: Range) => {
     let previewPanel: HTMLElement = element.querySelector(".vditor-wysiwyg__preview");
     if (!previewPanel) {
         element.insertAdjacentHTML("beforeend", `<${tagName} class="vditor-wysiwyg__preview"></${tagName}>`);
         previewPanel = element.querySelector(".vditor-wysiwyg__preview");
         previewPanel.setAttribute("contenteditable", "false");
         previewPanel.setAttribute("data-render", "false");
+        previewPanel.addEventListener("click", (event) => {
+            genBlockPopover(element, vditor, range);
+            event.stopPropagation();
+        });
     }
     const preview = document.createElement("span");
     preview.innerHTML = previewSVG;

+ 13 - 2
src/ts/wysiwyg/index.ts

@@ -63,9 +63,12 @@ class WYSIWYG {
             if (doc.body) {
                 textHTML = doc.body.innerHTML;
             }
+            // process code
             const code = processPasteCode(textHTML, textPlain, "wysiwyg");
             if (code) {
                 const codeNode = document.createElement("div");
+                codeNode.className = "vditor-wysiwyg__block";
+                codeNode.setAttribute("data-type", "code-block");
                 codeNode.innerHTML = "<pre><code></code></pre>";
                 codeNode.querySelector("code").innerText = code;
                 const range = getSelection().getRangeAt(0);
@@ -81,11 +84,19 @@ class WYSIWYG {
             } else if (event.clipboardData.files.length > 0 && vditor.options.upload.url) {
                 uploadFiles(vditor, event.clipboardData.files);
             } else if (textPlain.trim() !== "" && event.clipboardData.files.length === 0) {
-                const textNode = document.createTextNode(textPlain);
+
+                const pasteElement = document.createElement("template");
+                pasteElement.innerHTML = vditor.lute.Md2VditorDOM(textPlain);
+
                 const range = getSelection().getRangeAt(0);
-                range.insertNode(textNode);
+                range.insertNode(pasteElement.content.cloneNode(true));
                 range.collapse(false);
+
+                this.element.insertAdjacentElement("beforeend", this.popover);
+                processPreCode(this.element);
             }
+
+            afterRenderEvent(vditor);
         });
 
         this.element.addEventListener("input", (event: IHTMLInputEvent) => {

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

@@ -6,7 +6,7 @@ export const processPreCode = (editor: HTMLElement) => {
         if (codeElement.innerHTML === "<wbr>") {
             isFocus = true;
         }
-        codeElement.innerText = decodeURIComponent(codeElement.getAttribute("data-code")
+        codeElement.textContent = decodeURIComponent(codeElement.getAttribute("data-code")
             || "\n");
 
         if (isFocus) {