diff --git a/app/src/protyle/util/insertHTML.ts b/app/src/protyle/util/insertHTML.ts index c552652f6..684b68038 100644 --- a/app/src/protyle/util/insertHTML.ts +++ b/app/src/protyle/util/insertHTML.ts @@ -2,7 +2,13 @@ import {hasClosestBlock, hasClosestByAttribute, hasClosestByClassName, hasCloses import * as dayjs from "dayjs"; import {transaction, updateTransaction} from "../wysiwyg/transaction"; import {getContenteditableElement} from "../wysiwyg/getBlock"; -import {fixTableRange, focusBlock, focusByWbr, getEditorRange} from "./selection"; +import { + fixTableRange, + focusBlock, + focusByWbr, + getEditorRange, + getSelectionOffset, +} from "./selection"; import {Constants} from "../../constants"; import {highlightRender} from "../render/highlightRender"; import {scrollCenter} from "../../util/highlightById"; @@ -189,7 +195,8 @@ const processAV = (range: Range, html: string, protyle: IProtyle, blockElement: export const insertHTML = (html: string, protyle: IProtyle, isBlock = false, // 移动端插入嵌入块时,获取到的 range 为旧值 - useProtyleRange = false) => { + useProtyleRange = false, + insertByCursor = false) => { if (html === "") { return; } @@ -331,7 +338,14 @@ export const insertHTML = (html: string, protyle: IProtyle, isBlock = false, } } let lastElement: Element; - Array.from(tempElement.content.children).reverse().forEach((item) => { + let insertBefore = false + if (!range.toString() && insertByCursor) { + const positon = getSelectionOffset(blockElement, protyle.wysiwyg.element, range) + if (positon.start === 0 && editableElement.textContent !== "") { + insertBefore = true; + } + } + (insertBefore ? Array.from(tempElement.content.children) : Array.from(tempElement.content.children).reverse()).forEach((item) => { let addId = item.getAttribute("data-node-id"); if (addId === id) { doOperation.push({ @@ -361,14 +375,19 @@ export const insertHTML = (html: string, protyle: IProtyle, isBlock = false, action: "insert", data: item.outerHTML, id: addId, - previousID: id + nextID: insertBefore ? id : undefined, + previousID: insertBefore ? undefined : id }); undoOperation.push({ action: "delete", id: addId, }); } - blockElement.after(item); + if (insertBefore) { + blockElement.before(item); + } else { + blockElement.after(item); + } if (!lastElement) { lastElement = item; } diff --git a/app/src/protyle/util/paste.ts b/app/src/protyle/util/paste.ts index a38108edf..97440672b 100644 --- a/app/src/protyle/util/paste.ts +++ b/app/src/protyle/util/paste.ts @@ -172,7 +172,7 @@ export const pasteAsPlainText = async (protyle: IProtyle) => { textPlain = textPlain.replace(//g, ";;;gt;;;"); const content = protyle.lute.BlockDOM2EscapeMarkerContent(protyle.lute.Md2BlockDOM(textPlain)); // insertHTML 会进行内部反转义 - insertHTML(content, protyle); + insertHTML(content, protyle, false, false, true); filterClipboardHint(protyle, textPlain); }); } @@ -197,7 +197,7 @@ export const pasteText = (protyle: IProtyle, textPlain: string, nodeElement: Ele } } } - insertHTML(protyle.lute.Md2BlockDOM(textPlain), protyle); + insertHTML(protyle.lute.Md2BlockDOM(textPlain), protyle, false, false, true); blockRender(protyle, protyle.wysiwyg.element); processRender(protyle.wysiwyg.element); @@ -355,10 +355,10 @@ export const paste = async (protyle: IProtyle, event: (ClipboardEvent | DragEven e.setAttribute("contenteditable", "true"); }); const tempInnerHTML = tempElement.innerHTML; - if (!nodeElement.classList.contains("av") && tempInnerHTML.startsWith("[{") && tempInnerHTML.endsWith("}]")) { + if (!nodeElement.classList.contains("av") && tempInnerHTML.startsWith("[[{") && tempInnerHTML.endsWith("}]]")) { try { const json = JSON.parse(tempInnerHTML); - if (json.length > 0 && json[0].id && json[0].type) { + if (json.length > 0 && json[0].length > 0 && json[0][0].id && json[0][0].type) { insertHTML(textPlain, protyle, isBlock); } else { insertHTML(tempInnerHTML, protyle, isBlock); @@ -367,7 +367,7 @@ export const paste = async (protyle: IProtyle, event: (ClipboardEvent | DragEven insertHTML(tempInnerHTML, protyle, isBlock); } } else { - insertHTML(tempInnerHTML, protyle, isBlock); + insertHTML(tempInnerHTML, protyle, isBlock, false, true); } filterClipboardHint(protyle, protyle.lute.BlockDOM2StdMd(tempInnerHTML)); blockRender(protyle, protyle.wysiwyg.element); @@ -379,7 +379,7 @@ export const paste = async (protyle: IProtyle, event: (ClipboardEvent | DragEven // 原有代码在行内元素中粘贴会嵌套 insertHTML(code, protyle); } else { - insertHTML(code, protyle, true); + insertHTML(code, protyle, true, false, true); highlightRender(protyle.wysiwyg.element); } hideElements(["hint"], protyle); @@ -412,7 +412,7 @@ export const paste = async (protyle: IProtyle, event: (ClipboardEvent | DragEven fetchPost("/api/lute/html2BlockDOM", { dom: tempElement.innerHTML }, (response) => { - insertHTML(response.data, protyle); + insertHTML(response.data, protyle, false, false, true); protyle.wysiwyg.element.querySelectorAll('[data-type~="block-ref"]').forEach(item => { if (item.textContent === "") { fetchPost("/api/block/getRefText", {id: item.getAttribute("data-id")}, (response) => { @@ -459,7 +459,7 @@ export const paste = async (protyle: IProtyle, event: (ClipboardEvent | DragEven } } const textPlainDom = protyle.lute.Md2BlockDOM(textPlain); - insertHTML(textPlainDom, protyle); + insertHTML(textPlainDom, protyle, false, false, true); filterClipboardHint(protyle, textPlain); } blockRender(protyle, protyle.wysiwyg.element);