Vanessa 2025-04-01 17:05:15 +08:00
parent f8babd38b3
commit e3b9e7070a
5 changed files with 38 additions and 26 deletions

View file

@ -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",

View file

@ -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);

View file

@ -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
}

View file

@ -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);
}

View file

@ -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);