Liyuan Li 5 years ago
parent
commit
a6b17dc227
5 changed files with 55 additions and 15 deletions
  1. 1 0
      CHANGELOG.md
  2. 2 2
      demo/index.js
  3. 35 5
      src/ts/sv/inputEvent.ts
  4. 14 7
      src/ts/sv/process.ts
  5. 3 1
      src/ts/sv/processKeydown.ts

+ 1 - 0
CHANGELOG.md

@@ -68,6 +68,7 @@
 
 ### v3.3.9 / 2020-07-xx
 
+* [584](https://github.com/Vanessa219/vditor/issues/584) Can not delete Code block `修复缺陷`
 * [588](https://github.com/Vanessa219/vditor/issues/588) 第五版 SV 模式 bug 记录 `修复缺陷`
 
 ### v3.3.8 / 2020-07-17

+ 2 - 2
demo/index.js

@@ -50,8 +50,8 @@ if (window.innerWidth < 768) {
 }
 
 window.vditor = new Vditor('vditor', {
-  _lutePath: `http://192.168.0.107:9090/lute.min.js?${new Date().getTime()}`,
-  // _lutePath: 'src/js/lute/lute.min.js',
+  // _lutePath: `http://192.168.0.107:9090/lute.min.js?${new Date().getTime()}`,
+  _lutePath: 'src/js/lute/lute.min.js',
   toolbar,
   mode: 'sv',
   height: window.innerHeight + 100,

+ 35 - 5
src/ts/sv/inputEvent.ts

@@ -1,7 +1,7 @@
 import {scrollCenter} from "../util/editorCommonEvent";
 import {hasClosestByAttribute} from "../util/hasClosest";
 import {getSelectPosition, setRangeByWbr} from "../util/selection";
-import {processAfterRender, processSpinVditorSVDOM} from "./process";
+import {getSideByType, processAfterRender, processSpinVditorSVDOM} from "./process";
 
 export const inputEvent = (vditor: IVditor, event?: InputEvent) => {
     const range = getSelection().getRangeAt(0).cloneRange();
@@ -32,15 +32,45 @@ export const inputEvent = (vditor: IVditor, event?: InputEvent) => {
             processAfterRender(vditor);
             return;
         }
+        // https://github.com/Vanessa219/vditor/issues/584
+        if (event.inputType === "deleteContentBackward") {
+            const codeBlockMarkerElement =
+                hasClosestByAttribute(startContainer, "data-type", "code-block-open-marker") ||
+                hasClosestByAttribute(startContainer, "data-type", "code-block-close-marker");
+            if (codeBlockMarkerElement) {
+                if (codeBlockMarkerElement.getAttribute("data-type") === "code-block-close-marker") {
+                    const openMarkerElement = getSideByType(startContainer, "code-block-open-marker");
+                    if (openMarkerElement) {
+                        openMarkerElement.textContent = codeBlockMarkerElement.textContent;
+                        processAfterRender(vditor);
+                        return;
+                    }
+                }
+                if (codeBlockMarkerElement.getAttribute("data-type") === "code-block-open-marker") {
+                    const openMarkerElement = getSideByType(startContainer, "code-block-close-marker", false);
+                    if (openMarkerElement) {
+                        openMarkerElement.textContent = codeBlockMarkerElement.textContent;
+                        processAfterRender(vditor);
+                        return;
+                    }
+                }
+            }
+            blockElement.querySelectorAll('[data-type="code-block-open-marker"]').forEach((item: HTMLElement) => {
+                if (item.textContent.length === 1) {
+                    item.remove();
+                }
+            });
+            blockElement.querySelectorAll('[data-type="code-block-close-marker"]').forEach((item: HTMLElement) => {
+                if (item.textContent.length === 1) {
+                    item.remove();
+                }
+            });
+        }
         // 删除或空格不解析,否则会 format 回去
         if ((event.data === " " || event.inputType === "deleteContentBackward") &&
             (hasClosestByAttribute(startContainer, "data-type", "padding") // 场景:b 前进行删除 [> 1. a\n>   b]
                 || hasClosestByAttribute(startContainer, "data-type", "li-marker")  // 场景:删除最后一个字符 [* 1\n* ]
                 || hasClosestByAttribute(startContainer, "data-type", "task-marker")  // 场景:删除最后一个字符 [* [ ] ]
-                // 场景:删除前面的飘号 [```\n``` ]
-                || hasClosestByAttribute(startContainer, "data-type", "code-block-open-marker")
-                // 场景:删除后面的飘号 [```\n``` ]
-                || hasClosestByAttribute(startContainer, "data-type", "code-block-close-marker")
                 || hasClosestByAttribute(startContainer, "data-type", "blockquote-marker")  // 场景:删除最后一个字符 [> ]
             )) {
             processAfterRender(vditor);

+ 14 - 7
src/ts/sv/process.ts

@@ -29,13 +29,20 @@ export const processPaste = (vditor: IVditor, text: string) => {
     scrollCenter(vditor);
 };
 
-const getPreviousNL = (spanElement: Element) => {
-    let previousElement = spanElement;
-    while (previousElement && previousElement.getAttribute("data-type") !== "newline") {
-        previousElement = previousElement.previousElementSibling;
+export const getSideByType = (spanNode: Node, type: string, isPrevious = true) => {
+    let sideElement = spanNode as Element;
+    if (sideElement.nodeType === 3) {
+        sideElement = sideElement.parentElement;
     }
-    if (previousElement && previousElement.getAttribute("data-type") === "newline") {
-        return previousElement;
+    while (sideElement) {
+        if (sideElement.getAttribute("data-type") === type) {
+            return sideElement;
+        }
+        if (isPrevious) {
+            sideElement = sideElement.previousElementSibling;
+        } else {
+            sideElement = sideElement.nextElementSibling;
+        }
     }
     return false;
 };
@@ -166,7 +173,7 @@ export const processToolbar = (vditor: IVditor, actionBtn: Element, prefix: stri
             } else if (commandName === "quote") {
                 marker = "> ";
             }
-            const newLine = getPreviousNL(spanElement);
+            const newLine = getSideByType(spanElement, "newline");
             if (newLine) {
                 newLine.insertAdjacentText("afterend", marker);
             } else {

+ 3 - 1
src/ts/sv/processKeydown.ts

@@ -145,7 +145,9 @@ export const processKeydown = (vditor: IVditor, event: KeyboardEvent) => {
     if (event.key === "Backspace" && !isCtrl(event) && !event.altKey && !event.shiftKey) {
         const spanElement = hasClosestByTag(startContainer, "SPAN");
         if (spanElement && spanElement.previousElementSibling?.getAttribute("data-type") === "newline" &&
-            getSelectPosition(spanElement, vditor.sv.element, range).start === 1) {
+            getSelectPosition(spanElement, vditor.sv.element, range).start === 1 &&
+            // 飘号的处理需在 inputEvent 中,否则上下飘号对不齐
+            spanElement.getAttribute("data-type").indexOf("code-block-") === -1 ) {
             // 光标在每一行的第一个字符后
             range.setStart(spanElement, 0);
             range.extractContents();