diff --git a/app/src/block/util.ts b/app/src/block/util.ts index 196772f85..174cde554 100644 --- a/app/src/block/util.ts +++ b/app/src/block/util.ts @@ -7,11 +7,11 @@ import {scrollCenter} from "../util/highlightById"; import {Constants} from "../constants"; import {hideElements} from "../protyle/ui/hideElements"; import {blockRender} from "../protyle/render/blockRender"; -import {fetchPost} from "../util/fetch"; +import {fetchPost, fetchSyncPost} from "../util/fetch"; import {openFileById} from "../editor/util"; import {openMobileFileById} from "../mobile/editor"; -export const cancelSB = (protyle: IProtyle, nodeElement: Element) => { +export const cancelSB = async (protyle: IProtyle, nodeElement: Element) => { const doOperations: IOperation[] = []; const undoOperations: IOperation[] = []; let previousId = nodeElement.previousElementSibling ? nodeElement.previousElementSibling.getAttribute("data-node-id") : undefined; @@ -21,12 +21,23 @@ export const cancelSB = (protyle: IProtyle, nodeElement: Element) => { const id = nodeElement.getAttribute("data-node-id"); const sbElement = nodeElement.cloneNode() as HTMLElement; sbElement.innerHTML = nodeElement.lastElementChild.outerHTML; + let parentID = nodeElement.parentElement.getAttribute("data-node-id"); + // 缩放和反链需要接口获取 + if (!previousId && !parentID) { + if (protyle.block.showAll || protyle.options.backlinkData) { + const idData = await fetchSyncPost("/api/block/getBlockSiblingID", {id}); + previousId = idData.data.previous; + parentID = idData.data.parent; + } else { + parentID = protyle.block.rootID; + } + } undoOperations.push({ action: "insert", id, data: sbElement.outerHTML, previousID: nodeElement.previousElementSibling ? nodeElement.previousElementSibling.getAttribute("data-node-id") : undefined, - parentID: nodeElement.parentElement.getAttribute("data-node-id") || protyle.block.parentID + parentID, }); Array.from(nodeElement.children).forEach((item, index) => { if (index === nodeElement.childElementCount - 1) { @@ -46,7 +57,7 @@ export const cancelSB = (protyle: IProtyle, nodeElement: Element) => { action: "move", id: item.getAttribute("data-node-id"), previousID: previousId, - parentID: nodeElement.parentElement.getAttribute("data-node-id") || protyle.block.parentID + parentID, }); undoOperations.push({ action: "move", diff --git a/app/src/protyle/gutter/index.ts b/app/src/protyle/gutter/index.ts index c0cc9b670..d4d193194 100644 --- a/app/src/protyle/gutter/index.ts +++ b/app/src/protyle/gutter/index.ts @@ -1365,8 +1365,8 @@ export class Gutter { id: "cancelSuperBlock", label: window.siyuan.languages.cancel + " " + window.siyuan.languages.superBlock, accelerator: window.siyuan.config.keymap.editor.general[isCol ? "hLayout" : "vLayout"].custom, - click() { - const sbData = cancelSB(protyle, nodeElement); + async click() { + const sbData = await cancelSB(protyle, nodeElement); transaction(protyle, sbData.doOperations, sbData.undoOperations); focusBlock(protyle.wysiwyg.element.querySelector(`[data-node-id="${sbData.previousId}"]`)); hideElements(["gutter"], protyle); diff --git a/app/src/protyle/util/editorCommonEvent.ts b/app/src/protyle/util/editorCommonEvent.ts index d0febb3e6..4a4ac3548 100644 --- a/app/src/protyle/util/editorCommonEvent.ts +++ b/app/src/protyle/util/editorCommonEvent.ts @@ -528,23 +528,24 @@ const dragSb = async (protyle: IProtyle, sourceElements: Element[], targetElemen if (!isCopy && oldSourceParentElement && oldSourceParentElement.classList.contains("sb") && oldSourceParentElement.childElementCount === 2) { // 拖拽后,sb 只剩下一个元素 if (isSameDoc) { - const sbData = cancelSB(protyle, oldSourceParentElement); + const sbData = await cancelSB(protyle, oldSourceParentElement); doOperations.push(sbData.doOperations[0], sbData.doOperations[1]); undoOperations.splice(0, 0, sbData.undoOperations[0], sbData.undoOperations[1]); } else { /// #if !MOBILE const otherProtyleElement = hasClosestByClassName(oldSourceParentElement, "protyle", true); if (otherProtyleElement) { - getAllEditor().find(item => { - if (item.protyle.element.isSameNode(otherProtyleElement)) { - const otherSbData = cancelSB(item.protyle, oldSourceParentElement); + const allEditor = getAllEditor() + for (let i = 0; i < allEditor.length; i++) { + if (allEditor[i].protyle.element.isSameNode(otherProtyleElement)) { + const otherSbData = await cancelSB(allEditor[i].protyle, oldSourceParentElement); doOperations.push(otherSbData.doOperations[0], otherSbData.doOperations[1]); undoOperations.splice(0, 0, otherSbData.undoOperations[0], otherSbData.undoOperations[1]); // 需清空操作栈,否则撤销到移动出去的块的操作会抛异常 - item.protyle.undo.clear(); + allEditor[i].protyle.undo.clear(); return true; } - }); + } } /// #endif } @@ -730,23 +731,23 @@ const dragSame = async (protyle: IProtyle, sourceElements: Element[], targetElem if (!isCopy && oldSourceParentElement && oldSourceParentElement.classList.contains("sb") && oldSourceParentElement.childElementCount === 2) { // 拖拽后,sb 只剩下一个元素 if (isSameDoc) { - const sbData = cancelSB(protyle, oldSourceParentElement); + const sbData = await cancelSB(protyle, oldSourceParentElement); doOperations.push(sbData.doOperations[0], sbData.doOperations[1]); undoOperations.splice(0, 0, sbData.undoOperations[0], sbData.undoOperations[1]); } else { /// #if !MOBILE const otherProtyleElement = hasClosestByClassName(oldSourceParentElement, "protyle", true); if (otherProtyleElement) { - getAllEditor().find(item => { - if (item.protyle.element.isSameNode(otherProtyleElement)) { - const otherSbData = cancelSB(item.protyle, oldSourceParentElement); + const allEditor = getAllEditor() + for (let i = 0; i < allEditor.length; i++) { + if (allEditor[i].protyle.element.isSameNode(otherProtyleElement)) { + const otherSbData = await cancelSB(allEditor[i].protyle, oldSourceParentElement); doOperations.push(otherSbData.doOperations[0], otherSbData.doOperations[1]); undoOperations.splice(0, 0, otherSbData.undoOperations[0], otherSbData.undoOperations[1]); // 需清空操作栈,否则撤销到移动出去的块的操作会抛异常 - item.protyle.undo.clear(); - return true; + allEditor[i].protyle.undo.clear(); } - }); + } } /// #endif } diff --git a/app/src/protyle/wysiwyg/keydown.ts b/app/src/protyle/wysiwyg/keydown.ts index bda3e0acf..8efc527f1 100644 --- a/app/src/protyle/wysiwyg/keydown.ts +++ b/app/src/protyle/wysiwyg/keydown.ts @@ -86,7 +86,7 @@ export const getContentByInlineHTML = (range: Range, cb: (content: string) => vo }; export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => { - editorElement.addEventListener("keydown", (event: KeyboardEvent & { target: HTMLElement }) => { + editorElement.addEventListener("keydown", async (event: KeyboardEvent & { target: HTMLElement }) => { if (event.target.localName === "protyle-html" || event.target.localName === "input") { event.stopPropagation(); return; @@ -1665,7 +1665,7 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => { updateTransaction(protyle, selectsElement[0].getAttribute("data-node-id"), selectsElement[0].outerHTML, oldHTML); } else { range.insertNode(document.createElement("wbr")); - const sbData = cancelSB(protyle, selectsElement[0]); + const sbData = await cancelSB(protyle, selectsElement[0]); transaction(protyle, sbData.doOperations, sbData.undoOperations); focusByWbr(protyle.wysiwyg.element, range); } @@ -1694,7 +1694,7 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => { updateTransaction(protyle, selectsElement[0].getAttribute("data-node-id"), selectsElement[0].outerHTML, oldHTML); } else { range.insertNode(document.createElement("wbr")); - const sbData = cancelSB(protyle, selectsElement[0]); + const sbData = await cancelSB(protyle, selectsElement[0]); transaction(protyle, sbData.doOperations, sbData.undoOperations); focusByWbr(protyle.wysiwyg.element, range); } diff --git a/app/src/protyle/wysiwyg/remove.ts b/app/src/protyle/wysiwyg/remove.ts index 048739daa..93825e050 100644 --- a/app/src/protyle/wysiwyg/remove.ts +++ b/app/src/protyle/wysiwyg/remove.ts @@ -20,7 +20,7 @@ import {scrollCenter} from "../../util/highlightById"; import {isMobile} from "../../util/functions"; import {mathRender} from "../render/mathRender"; -export const removeBlock = (protyle: IProtyle, blockElement: Element, range: Range, type: "Delete" | "Backspace" | "remove") => { +export const removeBlock = async (protyle: IProtyle, blockElement: Element, range: Range, type: "Delete" | "Backspace" | "remove") => { // 删除后,防止滚动条滚动后调用 get 请求,因为返回的请求已查找不到内容块了 preventScroll(protyle); const selectElements = Array.from(protyle.wysiwyg.element.querySelectorAll(".protyle-wysiwyg--select")); @@ -181,7 +181,7 @@ export const removeBlock = (protyle: IProtyle, blockElement: Element, range: Ran } if (deletes.length > 0) { if (topParentElement && topParentElement.getAttribute("data-type") === "NodeSuperBlock" && topParentElement.childElementCount === 2) { - const sbData = cancelSB(protyle, topParentElement); + const sbData = await cancelSB(protyle, topParentElement); transaction(protyle, deletes.concat(sbData.doOperations), sbData.undoOperations.concat(inserts.reverse())); } else { transaction(protyle, deletes, inserts.reverse()); @@ -351,7 +351,7 @@ export const removeBlock = (protyle: IProtyle, blockElement: Element, range: Ran blockElement.remove(); // 取消超级块 if (parentElement.getAttribute("data-type") === "NodeSuperBlock" && parentElement.childElementCount === 2) { - const sbData = cancelSB(protyle, parentElement); + const sbData = await cancelSB(protyle, parentElement); transaction(protyle, doOperations.concat(sbData.doOperations), sbData.undoOperations.concat(undoOperations)); } else { transaction(protyle, doOperations, undoOperations); @@ -428,7 +428,7 @@ export const removeBlock = (protyle: IProtyle, blockElement: Element, range: Ran }); } if (parentElement.getAttribute("data-type") === "NodeSuperBlock" && parentElement.childElementCount === 2) { - const sbData = cancelSB(protyle, parentElement); + const sbData = await cancelSB(protyle, parentElement); transaction(protyle, doOperations.concat(sbData.doOperations), sbData.undoOperations.concat(undoOperations)); } else { transaction(protyle, doOperations, undoOperations);