Liyuan Li 5 years ago
parent
commit
795346e66f
6 changed files with 141 additions and 227 deletions
  1. 1 1
      CHANGELOG.md
  2. 18 45
      src/ts/sv/inputEvent.ts
  3. 12 14
      src/ts/sv/process.ts
  4. 103 143
      src/ts/sv/processKeydown.ts
  5. 1 1
      src/ts/toolbar/EditMode.ts
  6. 6 23
      src/ts/undo/index.ts

+ 1 - 1
CHANGELOG.md

@@ -65,10 +65,10 @@
 
 * [open issues](https://github.com/Vanessa219/vditor/issues)
 * [346](https://github.com/Vanessa219/vditor/issues/346) 内容主题推荐(长期有效) `改进功能`
-* [567](https://github.com/Vanessa219/vditor/issues/567) SV 模式块引用嵌套列表、代码块问题 `修复缺陷`
 
 ### v3.3.7 / 2020-07-xx
 
+* [567](https://github.com/Vanessa219/vditor/issues/567) SV 模式块引用嵌套列表、代码块问题 `修复缺陷`
 * [563](https://github.com/Vanessa219/vditor/issues/563) SV 模式列表项下的代码块问题 `修复缺陷`
 * [579](https://github.com/Vanessa219/vditor/issues/579) 样式调整 `改进功能`
 * [575](https://github.com/Vanessa219/vditor/issues/575) 编辑器存在 form 中,情景菜单会出发提交事件 `修复缺陷`

+ 18 - 45
src/ts/sv/inputEvent.ts

@@ -1,11 +1,15 @@
 import {scrollCenter} from "../util/editorCommonEvent";
-import {hasClosestByAttribute, hasTopClosestByAttribute} from "../util/hasClosest";
+import {hasClosestByAttribute} from "../util/hasClosest";
 import {getSelectPosition, setRangeByWbr} from "../util/selection";
 import {processAfterRender, processSpinVditorSVDOM} from "./process";
 
 export const inputEvent = (vditor: IVditor, event?: InputEvent) => {
     const range = getSelection().getRangeAt(0).cloneRange();
-    let blockElement = hasClosestByAttribute(range.startContainer, "data-block", "0");
+    let startContainer = range.startContainer;
+    if (range.startContainer.nodeType !== 3 && (range.startContainer as HTMLElement).tagName === "DIV") {
+        startContainer = range.startContainer.childNodes[range.startOffset - 1];
+    }
+    let blockElement = hasClosestByAttribute(startContainer, "data-block", "0");
     // 不调用 lute 解析
     if (blockElement && event && (event.inputType === "deleteContentBackward" || event.data === " ")) {
         // 开始可以输入空格
@@ -28,40 +32,16 @@ export const inputEvent = (vditor: IVditor, event?: InputEvent) => {
             processAfterRender(vditor);
             return;
         }
-        //  list item marker 删除或空格
+        // 删除或空格不解析,否则会 format 回去
         if ((event.data === " " || event.inputType === "deleteContentBackward") &&
-            (hasClosestByAttribute(range.startContainer, "data-type", "li-marker") ||
-                hasClosestByAttribute(range.startContainer, "data-type", "task-marker")
+            (hasClosestByAttribute(startContainer, "data-type", "padding") // 场景:b 前进行删除 [> 1. a\n>   b]
+                || hasClosestByAttribute(startContainer, "data-type", "li-marker")  // 场景:删除最后一个字符 [* 1\n* ]
+                || hasClosestByAttribute(startContainer, "data-type", "task-marker")  // 场景:删除最后一个字符 [* [ ] ]
+                || hasClosestByAttribute(startContainer, "data-type", "blockquote-marker")  // 场景:删除最后一个字符 [> ]
             )) {
             processAfterRender(vditor);
             return;
         }
-        // heading marker 删除或空格
-        const headingElement = hasClosestByAttribute(range.startContainer, "data-type", "heading-marker");
-        if (headingElement && (event.data === " " || event.inputType === "deleteContentBackward")) {
-            processAfterRender(vditor);
-            return;
-        }
-        // blockquote marker 删除或空格
-        const blockquoteElement = hasClosestByAttribute(range.startContainer, "data-type", "blockquote-marker");
-        if (blockquoteElement && (event.data === " " || event.inputType === "deleteContentBackward")) {
-            processAfterRender(vditor);
-            return;
-        }
-        // block code marker 删除
-        const blockCodeElement =
-            hasClosestByAttribute(range.startContainer, "data-type", "code-block");
-        if (blockCodeElement && event.inputType === "deleteContentBackward") {
-            const startIndex = getSelectPosition(blockElement, vditor.sv.element, range).start;
-            if (startIndex <= 2 || startIndex === blockCodeElement.textContent.length - 1) {
-                if (blockElement.querySelectorAll(".vditor-sv__marker").length < 2) {
-                    blockElement.querySelector(".vditor-sv__marker")?.remove();
-                    blockElement.setAttribute("data-type", "p");
-                }
-                processAfterRender(vditor);
-                return;
-            }
-        }
     }
     if (blockElement && blockElement.textContent.trimRight() === "$$") {
         // 内联数学公式
@@ -71,7 +51,7 @@ export const inputEvent = (vditor: IVditor, event?: InputEvent) => {
     if (!blockElement) {
         blockElement = vditor.sv.element;
     }
-    const footnotesElement = hasClosestByAttribute(range.startContainer, "data-type", "footnotes-block");
+    const footnotesElement = hasClosestByAttribute(startContainer, "data-type", "footnotes-block");
     if (footnotesElement) {
         // 修改脚注
         blockElement = footnotesElement;
@@ -80,22 +60,10 @@ export const inputEvent = (vditor: IVditor, event?: InputEvent) => {
         // 修改链接引用
         blockElement = vditor.sv.element;
     }
-    if (hasClosestByAttribute(range.startContainer, "data-type", "footnotes-link")) {
+    if (hasClosestByAttribute(startContainer, "data-type", "footnotes-link")) {
         // 修改脚注角标
         blockElement = vditor.sv.element;
     }
-    // 有 blockquote 需到 blockquote
-    const blockquoteElement = hasTopClosestByAttribute(blockElement, "data-type", "blockquote");
-    if (blockquoteElement) {
-        blockElement = blockquoteElement;
-    }
-    // 列表需到顶层
-    const topListElement = hasTopClosestByAttribute(blockElement, "data-type", "ol") ||
-        hasTopClosestByAttribute(blockElement, "data-type", "ul") ||
-        hasTopClosestByAttribute(blockElement, "data-type", "task");
-    if (topListElement) {
-        blockElement = topListElement;
-    }
     // 添加光标位置
     if (blockElement.textContent.indexOf(Lute.Caret) === -1) {
         // 点击工具栏会插入 Caret
@@ -119,6 +87,11 @@ export const inputEvent = (vditor: IVditor, event?: InputEvent) => {
     if (isSVElement) {
         html = blockElement.textContent;
     } else {
+        // 添加前一个块元素
+        if (blockElement.previousElementSibling) {
+            html = blockElement.previousElementSibling.textContent + html;
+            blockElement.previousElementSibling.remove();
+        }
         // 添加链接引用
         const allLinkRefDefsElement = vditor.sv.element.querySelector("[data-type='link-ref-defs-block']");
         if (allLinkRefDefsElement && !blockElement.isEqualNode(allLinkRefDefsElement)) {

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

@@ -1,10 +1,10 @@
 import {getMarkdown} from "../markdown/getMarkdown";
 import {accessLocalStorage} from "../util/compatibility";
 import {hasClosestBlock, hasClosestByAttribute} from "../util/hasClosest";
+import {log} from "../util/log";
 import {getEditorRange, setRangeByWbr} from "../util/selection";
 import {highlightToolbarSV} from "./highlightToolbarSV";
 import {inputEvent} from "./inputEvent";
-import {log} from "../util/log";
 
 export const processSpinVditorSVDOM = (html: string, vditor: IVditor) => {
     log("SpinVditorSVDOM", html, "argument", vditor.options.debugger);
@@ -13,21 +13,19 @@ export const processSpinVditorSVDOM = (html: string, vditor: IVditor) => {
         "</div>";
     log("SpinVditorSVDOM", html, "result", vditor.options.debugger);
     return html;
-}
+};
 
-export const getBlockquoteMarkers = (pElement: HTMLElement) => {
-    let markerText = ''
-    const previousElement = pElement.previousElementSibling
-    if (previousElement) {
-        if (previousElement.getAttribute("data-type") === "li-marker") {
-            // >   * 2 中的 [   * ]
-            markerText = previousElement.previousElementSibling.textContent + previousElement.textContent + markerText
-        } else if (previousElement.getAttribute("data-type") === "blockquote-marker") {
-            // >   * > 3 中的 [> ]
-            markerText = previousElement.textContent + markerText;
-        }
-        // previousElement = '';
+export const processPreviousMarkers = (textElement: HTMLElement) => {
+    let previousElement = textElement.previousElementSibling;
+    let markerText = "";
+    while (previousElement && (previousElement.getAttribute("data-type") === "li-marker" ||
+        previousElement.getAttribute("data-type") === "blockquote-marker" ||
+        previousElement.getAttribute("data-type") === "task-marker" ||
+        previousElement.getAttribute("data-type") === "padding")) {
+        markerText = previousElement.textContent + markerText;
+        previousElement = previousElement.previousElementSibling;
     }
+    return markerText;
 };
 
 export const processAfterRender = (vditor: IVditor, options = {

+ 103 - 143
src/ts/sv/processKeydown.ts

@@ -1,10 +1,10 @@
 import {isCtrl} from "../util/compatibility";
 import {fixTab} from "../util/fixBrowserBehavior";
-import {hasClosestByAttribute, hasTopClosestByAttribute} from "../util/hasClosest";
-import {matchHotKey} from "../util/hotKey";
+import {hasClosestByAttribute} from "../util/hasClosest";
+import {hasClosestByTag} from "../util/hasClosestByHeadings";
 import {getEditorRange, getSelectPosition} from "../util/selection";
 import {inputEvent} from "./inputEvent";
-import {processAfterRender} from "./process";
+import {processAfterRender, processPreviousMarkers} from "./process";
 
 export const processKeydown = (vditor: IVditor, event: KeyboardEvent) => {
     vditor.sv.composingLock = event.isComposing;
@@ -20,45 +20,25 @@ export const processKeydown = (vditor: IVditor, event: KeyboardEvent) => {
         return false;
     }
     const range = getEditorRange(vditor.sv.element);
-    const startContainer = range.startContainer;
-    const codeBlockElement = hasClosestByAttribute(startContainer, "data-type", "code-block");
+    let startContainer = range.startContainer;
+    if (range.startContainer.nodeType !== 3 && (range.startContainer as HTMLElement).tagName === "DIV") {
+        startContainer = range.startContainer.childNodes[range.startOffset - 1];
+    }
+    const textElement = hasClosestByAttribute(startContainer, "data-type", "text");
+
     // blockquote
-    const blockquoteLineElement = hasClosestByAttribute(startContainer, "data-type", "blockquote-line");
-    if (blockquoteLineElement && !codeBlockElement) {
-        const startIndex = getSelectPosition(blockquoteLineElement, vditor.sv.element, range).start;
-        if (event.key === "Enter" && !isCtrl(event) && !event.altKey && startIndex !== 0) {
-            const markerText = Array(blockquoteLineElement.querySelectorAll('[data-type="blockquote-marker"]').length)
-                .fill(">").join(" ") + " ";
-            if (startIndex === markerText.length && markerText.length > 1) {
-                // 在 marker 中换行,删除 marker 标记
-                blockquoteLineElement.firstElementChild.remove();
-                event.preventDefault();
-                processAfterRender(vditor);
-                return true;
-            } else if (blockquoteLineElement.textContent.trim() !== "") {
-                // 换行应延续 >
-                let newMarker = "\n" + markerText;
-                const liMarkerElement = blockquoteLineElement.querySelector('[data-type="li-marker"]');
-                if (liMarkerElement) {
-                    newMarker += liMarkerElement.parentElement.getAttribute("data-space") + liMarkerElement.textContent;
-                    if (blockquoteLineElement.querySelector('[data-type="task-marker"]')) {
-                        newMarker += "[ ] ";
-                    }
-                }
-                range.insertNode(document.createTextNode(newMarker));
-                range.collapse(false);
-                inputEvent(vditor);
-                event.preventDefault();
-                return true;
-            }
-        }
-        // 光标在每一行的第一个字符后删除
-        if (event.key === "Backspace" && !isCtrl(event) && !event.altKey && !event.shiftKey && startIndex === 1) {
-            range.setStart(startContainer, 0);
-            range.extractContents();
-            if (blockquoteLineElement.firstElementChild.textContent === "") {
-                blockquoteLineElement.firstElementChild.remove();
-            }
+    let blockquoteMarkerElement = hasClosestByAttribute(startContainer, "data-type", "blockquote-marker");
+    if (!blockquoteMarkerElement && range.startOffset === 0 && textElement && textElement.previousElementSibling &&
+        textElement.previousElementSibling.getAttribute("data-type") === "blockquote-marker") {
+        blockquoteMarkerElement = textElement.previousElementSibling as HTMLElement;
+    }
+    // 回车逐个删除 marker 标记
+    if (blockquoteMarkerElement) {
+        if (event.key === "Enter" && !isCtrl(event) && !event.altKey &&
+            blockquoteMarkerElement.nextElementSibling.textContent.trim() === "" &&
+            getSelectPosition(blockquoteMarkerElement, vditor.sv.element, range).start ===
+            blockquoteMarkerElement.textContent.length) {
+            blockquoteMarkerElement.remove();
             processAfterRender(vditor);
             event.preventDefault();
             return true;
@@ -66,86 +46,58 @@ export const processKeydown = (vditor: IVditor, event: KeyboardEvent) => {
     }
 
     // list item
-    const listElement = hasClosestByAttribute(startContainer, "data-type", "li");
-    if (listElement && !codeBlockElement) {
-        const startIndex = getSelectPosition(listElement, vditor.sv.element, range).start;
-        const markerElement = listElement.querySelector('[data-type="li-marker"]');
-        const taskMarkerElements = listElement.querySelectorAll('[data-type="task-marker"]');
-        const paddingElement = listElement.querySelector('[data-type="padding"]');
-        const paddingText = paddingElement ? paddingElement.textContent : "";
-        // 回车
-        if (event.key === "Enter" && !isCtrl(event) && !event.altKey && !event.shiftKey && startIndex !== 0) {
-            // enter
-            if (markerElement && startIndex ===
-                markerElement.textContent.length + paddingText.length + (taskMarkerElements.length > 0 ? 4 : 0)) {
-                let addUndoStack = true;
-                const parentLiElement = hasClosestByAttribute(listElement.parentElement, "data-type", "li");
-                // 清空列表标记符
-                if (parentLiElement) {
-                    paddingElement.textContent = paddingText.substr(0, paddingText.length -
-                        parentLiElement.querySelector('[data-type="li-marker"]').textContent.length);
-                    inputEvent(vditor);
-                    addUndoStack = false;
+    const listMarkerElement = hasClosestByAttribute(startContainer, "data-type", "li-marker") as HTMLElement;
+    const taskMarkerElement = hasClosestByAttribute(startContainer, "data-type", "task-marker") as HTMLElement;
+    let listLastMarkerElement = listMarkerElement;
+    if (!listLastMarkerElement) {
+        if (taskMarkerElement && taskMarkerElement.nextElementSibling.getAttribute("data-type") !== "task-marker") {
+            listLastMarkerElement = taskMarkerElement;
+        }
+    }
+    if (!listLastMarkerElement && range.startOffset === 0 && textElement && textElement.previousElementSibling &&
+        (textElement.previousElementSibling.getAttribute("data-type") === "li-marker" ||
+            textElement.previousElementSibling.getAttribute("data-type") === "task-marker")) {
+        listLastMarkerElement = textElement.previousElementSibling as HTMLElement;
+    }
+    if (listLastMarkerElement) {
+        const startIndex = getSelectPosition(listLastMarkerElement, vditor.sv.element, range).start;
+        const isTask = listLastMarkerElement.getAttribute("data-type") === "task-marker";
+        let listFirstMarkerElement = listLastMarkerElement;
+        if (isTask) {
+            listFirstMarkerElement = listLastMarkerElement.previousElementSibling.previousElementSibling
+                .previousElementSibling as HTMLElement;
+        }
+        if (startIndex === listLastMarkerElement.textContent.length) {
+            // 回车清空列表标记符
+            if (event.key === "Enter" && !isCtrl(event) && !event.altKey && !event.shiftKey &&
+                listLastMarkerElement.nextElementSibling.textContent.trim() === "") {
+                if (listFirstMarkerElement.previousElementSibling?.getAttribute("data-type") === "padding") {
+                    listFirstMarkerElement.previousElementSibling.remove();
                 } else {
-                    markerElement.remove();
-                }
-                if (taskMarkerElements.length > 0) {
-                    listElement.querySelectorAll('[data-type="task-marker"]').forEach((item: HTMLElement) => {
-                        item.remove();
-                    });
-                }
-                if (addUndoStack) {
-                    processAfterRender(vditor);
-                }
-            } else {
-                // 添加标记符号
-                let newMarker = "\n" + paddingText;
-                if (markerElement) {
-                    newMarker += markerElement.textContent;
+                    if (isTask) {
+                        listFirstMarkerElement.remove();
+                        listLastMarkerElement.previousElementSibling.previousElementSibling.remove();
+                        listLastMarkerElement.previousElementSibling.remove();
+                    }
+                    listLastMarkerElement.remove();
                 }
-                if (taskMarkerElements.length > 0) {
-                    newMarker += "[ ] ";
+                processAfterRender(vditor);
+                event.preventDefault();
+                return true;
+            }
+            // 第一个 marker 后 tab 进行缩进
+            if (event.key === "Tab") {
+                if (/^\d/.test(listFirstMarkerElement.textContent)) {
+                    listFirstMarkerElement.textContent = "1. ";
+                    range.selectNodeContents(listLastMarkerElement.firstChild);
+                    range.collapse(false);
                 }
-                range.insertNode(document.createTextNode(newMarker));
-                range.collapse(false);
+                listFirstMarkerElement.insertAdjacentHTML("beforebegin",
+                    `<span data-type="padding">${listFirstMarkerElement.textContent.replace(/\S/g, " ")}</span>`);
                 inputEvent(vditor);
+                event.preventDefault();
+                return true;
             }
-            event.preventDefault();
-            return true;
-        }
-        // 光标在每一行的第一个字符后删除
-        if (event.key === "Backspace" && !isCtrl(event) && !event.altKey && !event.shiftKey && startIndex === 1) {
-            range.setStart(startContainer, 0);
-            range.extractContents();
-            // 不能使用 inputEvent,否则子列表会合并为松散列表
-            processAfterRender(vditor);
-            event.preventDefault();
-            return true;
-        }
-        // 第一个 marker 后 tab 进行缩进
-        if (event.key === "Tab" && markerElement && startIndex === markerElement.textContent.length + paddingText.length
-            + (taskMarkerElements.length > 0 ? taskMarkerElements[1].textContent.length + 3 : 0)) {
-            if (/^\d/.test(markerElement.textContent)) {
-                markerElement.textContent = "1. ";
-                range.selectNodeContents(markerElement.firstChild);
-                range.collapse(false);
-            }
-            markerElement.insertAdjacentHTML("beforebegin",
-                `<span data-type="padding">${markerElement.textContent.replace(/\S/g, " ")}</span>`);
-            inputEvent(vditor);
-            event.preventDefault();
-            return true;
-        }
-        // toggle checked
-        if (taskMarkerElements.length > 0 && matchHotKey("⌘-⇧-J", event)) {
-            if (taskMarkerElements[1].textContent === " ") {
-                taskMarkerElements[1].textContent = "x";
-            } else {
-                taskMarkerElements[1].textContent = " ";
-            }
-            processAfterRender(vditor);
-            event.preventDefault();
-            return true;
         }
     }
 
@@ -155,20 +107,32 @@ export const processKeydown = (vditor: IVditor, event: KeyboardEvent) => {
     }
 
     const blockElement = hasClosestByAttribute(startContainer, "data-block", "0");
-    // 回车。list,blockquote marker 延续和清除
-    if (event.key === "Enter" && !isCtrl(event) && !event.altKey && blockElement) {
+    // 回车
+    if (event.key === "Enter" && !isCtrl(event) && !event.altKey && !event.shiftKey && blockElement) {
         let isFirst = false;
-        if (getSelectPosition(blockElement, vditor.sv.element).start === 0) {
+        const newLineMatch = blockElement.textContent.match(/^\n+/);
+        if (getSelectPosition(blockElement, vditor.sv.element).start <= (newLineMatch ? newLineMatch[0].length : 0)) {
             // 允许段落开始换行
             isFirst = true;
         }
         let newLineText = "\n";
-        if (blockElement.getAttribute("data-type") === "code-block") {
-            newLineText += blockElement.querySelector('[data-type="padding"]')?.textContent || "";
+        if (textElement) {
+            newLineText += processPreviousMarkers(textElement);
+        } else {
+            let codeMarkerElement = hasClosestByAttribute(startContainer, "data-type", "code-block-open-marker")
+            if (!codeMarkerElement) {
+                codeMarkerElement = hasClosestByAttribute(startContainer, "data-type", "code-block-info");
+                if (codeMarkerElement) {
+                    codeMarkerElement = codeMarkerElement.previousElementSibling as HTMLElement;
+                }
+            }
+            if (codeMarkerElement) {
+                newLineText += processPreviousMarkers(codeMarkerElement);
+            }
         }
         range.insertNode(document.createTextNode(newLineText));
         range.collapse(false);
-        if ((!blockElement || blockElement?.textContent.trim() !== "") && !isFirst) {
+        if (blockElement && blockElement.textContent.trim() !== "" && !isFirst) {
             inputEvent(vditor);
         } else {
             processAfterRender(vditor);
@@ -179,30 +143,26 @@ export const processKeydown = (vditor: IVditor, event: KeyboardEvent) => {
 
     // 删除后光标前有 newline 的处理
     if (event.key === "Backspace" && !isCtrl(event) && !event.altKey && !event.shiftKey) {
-        let deleteElement = hasTopClosestByAttribute(startContainer, "data-block", "0");
-        if (deleteElement) {
-            const startIndex = getSelectPosition(deleteElement, vditor.sv.element, range).start;
-            // 光标在每一块的开始位置
-            if (startIndex === 0 && deleteElement.previousElementSibling &&
-                deleteElement.previousElementSibling.lastElementChild.getAttribute("data-type") === "newline") {
-                deleteElement.previousElementSibling.lastElementChild.remove();
-                range.extractContents();
+        const spanElement = hasClosestByTag(startContainer, "SPAN");
+        if (spanElement && spanElement.previousElementSibling?.getAttribute("data-type") === "newline" &&
+            getSelectPosition(spanElement, vditor.sv.element, range).start === 1) {
+            // 光标在每一行的第一个字符后
+            range.setStart(spanElement, 0);
+            range.extractContents();
+            if (spanElement.textContent.trim() !== "") {
                 inputEvent(vditor);
-                event.preventDefault();
-                return true;
             }
+            event.preventDefault();
+            return true;
         }
-        // 光标在每一行的第一个字符后, blockquote, list 处理在上方
-        deleteElement = hasClosestByAttribute(startContainer, "data-type", "text");
-        if (deleteElement) {
-            const startIndex = getSelectPosition(deleteElement, vditor.sv.element, range).start;
-            if (startIndex === 1) {
-                range.setStart(startContainer, 0);
-                range.extractContents();
-                inputEvent(vditor);
-                event.preventDefault();
-                return true;
-            }
+        // 每一段第一个字符前
+        if (blockElement && getSelectPosition(blockElement, vditor.sv.element, range).start === 0 &&
+            blockElement.previousElementSibling) {
+            blockElement.previousElementSibling.lastElementChild.remove();
+            range.extractContents();
+            inputEvent(vditor);
+            event.preventDefault();
+            return true;
         }
     }
     return false;

+ 1 - 1
src/ts/toolbar/EditMode.ts

@@ -90,7 +90,7 @@ export const setEditMode = (vditor: IVditor, type: string, event: Event | string
             vditor.sv.element.style.display = "block";
         }
         vditor.currentMode = "sv";
-        vditor.sv.element.innerHTML =  processSpinVditorSVDOM(markdownText, vditor);;
+        vditor.sv.element.innerHTML =  processSpinVditorSVDOM(markdownText, vditor);
         processSVAfterRender(vditor, {
             enableAddUndoStack: true,
             enableHint: false,

+ 6 - 23
src/ts/undo/index.ts

@@ -6,7 +6,6 @@ import {execAfterRender} from "../util/fixBrowserBehavior";
 import {highlightToolbar} from "../util/highlightToolbar";
 import {processCodeRender} from "../util/processCode";
 import {setRangeByWbr, setSelectionFocus} from "../util/selection";
-import {processSpinVditorSVDOM} from "../sv/process";
 
 interface IUndo {
     hasUndo: boolean;
@@ -94,14 +93,7 @@ class Undo {
             // Safari keydown 在 input 之后,不需要重复记录历史
             return;
         }
-        if (vditor.currentMode === "sv") {
-            const caretElement = document.createElement("span");
-            caretElement.className = "wbr";
-            caretElement.textContent = Lute.Caret;
-            getSelection().getRangeAt(0).insertNode(caretElement);
-        } else {
-            getSelection().getRangeAt(0).insertNode(document.createElement("wbr"));
-        }
+        getSelection().getRangeAt(0).insertNode(document.createElement("wbr"));
         if (vditor.currentMode === "wysiwyg") {
             this[vditor.currentMode].undoStack[0][0].diffs[0][1] =
                 vditor.lute.SpinVditorDOM(vditor[vditor.currentMode].element.innerHTML);
@@ -109,12 +101,11 @@ class Undo {
             this[vditor.currentMode].undoStack[0][0].diffs[0][1] =
                 vditor.lute.SpinVditorIRDOM(vditor[vditor.currentMode].element.innerHTML);
         } else {
-            this[vditor.currentMode].undoStack[0][0].diffs[0][1] =
-                processSpinVditorSVDOM(vditor[vditor.currentMode].element.textContent, vditor);
+            this[vditor.currentMode].undoStack[0][0].diffs[0][1] = vditor[vditor.currentMode].element.innerHTML;
         }
         this[vditor.currentMode].lastText = this[vditor.currentMode].undoStack[0][0].diffs[0][1];
         const wbrElement =
-            vditor[vditor.currentMode].element.querySelector(vditor.currentMode === "sv" ? ".wbr" : "wbr");
+            vditor[vditor.currentMode].element.querySelector("wbr");
         if (wbrElement) {
             wbrElement.remove();
         }
@@ -128,14 +119,7 @@ class Undo {
             const range = getSelection().getRangeAt(0);
             if (vditor[vditor.currentMode].element.contains(range.startContainer)) {
                 cloneRange = range.cloneRange();
-                if (vditor.currentMode === "sv") {
-                    const caretElement = document.createElement("span");
-                    caretElement.className = "wbr";
-                    caretElement.textContent = Lute.Caret;
-                    range.insertNode(caretElement);
-                } else {
-                    range.insertNode(document.createElement("wbr"));
-                }
+                range.insertNode(document.createElement("wbr"));
             }
         }
         let text;
@@ -144,10 +128,9 @@ class Undo {
         } else if (vditor.currentMode === "ir") {
             text = vditor.lute.SpinVditorIRDOM(vditor[vditor.currentMode].element.innerHTML);
         } else {
-            text = processSpinVditorSVDOM(vditor[vditor.currentMode].element.textContent, vditor);
+            text = vditor[vditor.currentMode].element.innerHTML;
         }
-        const wbrElement =
-            vditor[vditor.currentMode].element.querySelector(vditor.currentMode === "sv" ? ".wbr" : "wbr");
+        const wbrElement = vditor[vditor.currentMode].element.querySelector("wbr");
         if (wbrElement) {
             wbrElement.remove();
         }