diff --git a/app/src/protyle/util/editorCommonEvent.ts b/app/src/protyle/util/editorCommonEvent.ts index bf58344cc..8053c87bf 100644 --- a/app/src/protyle/util/editorCommonEvent.ts +++ b/app/src/protyle/util/editorCommonEvent.ts @@ -346,6 +346,9 @@ const dragSb = async (protyle: IProtyle, sourceElements: Element[], targetElemen const undoOperations: IOperation[] = []; const targetMoveUndo: IOperation = { action: "move", + context: { + removeFold: "true" + }, id: targetElement.getAttribute("data-node-id"), previousID: targetElement.previousElementSibling?.getAttribute("data-node-id"), parentID: getParentBlock(targetElement)?.getAttribute("data-node-id") || protyle.block.parentID || protyle.block.rootID @@ -400,36 +403,39 @@ const dragSb = async (protyle: IProtyle, sourceElements: Element[], targetElemen action: "delete", id: sbElement.getAttribute("data-node-id"), }); - let hasFoldHeading = false; + const foldElements: Element[] = []; newSourceParentElement.forEach(item => { - if (item.getAttribute("data-type") === "NodeHeading" && item.getAttribute("fold") === "1") { - hasFoldHeading = true; - if (item.nextElementSibling && ( + if (item.getAttribute("data-type") === "NodeHeading" && item.getAttribute("fold") === "1" && + item.nextElementSibling && ( item.nextElementSibling.getAttribute("data-type") !== "NodeHeading" || - item.nextElementSibling.getAttribute("data-subtype") > item.getAttribute("data-subtype") + (item.nextElementSibling.getAttribute("data-subtype") || "") > item.getAttribute("data-subtype") )) { - const foldOperations = setFold(protyle, item, true, false, false, true); - doOperations.push(...foldOperations.doOperations); - // 不折叠,否则无法撤销 undoOperations.push(...foldOperations.undoOperations); - } - return true; + foldElements.push(item); } }); + if ((newSourceParentElement.length > 1 || foldElements.length > 0) && direct === "col") { + const mergeOperations = await turnsIntoOneTransaction({ + protyle, + selectsElement: newSourceParentElement.reverse(), + type: "BlocksMergeSuperBlock", + level: "row", + unfocus: true, + getOperations: true + }); + doOperations.push(...mergeOperations.doOperations); + undoOperations.splice(0, 0, ...mergeOperations.undoOperations); + } + foldElements.forEach(item => { + const foldOperations = setFold(protyle, item, true, false, false, true); + doOperations.push(...foldOperations.doOperations); + undoOperations.splice(0, 0, ...foldOperations.undoOperations); + }); if (isSameDoc || isCopy) { transaction(protyle, doOperations, undoOperations); } else { // 跨文档或插入折叠标题下不支持撤销 transaction(protyle, doOperations); } - if ((newSourceParentElement.length > 1 || hasFoldHeading) && direct === "col") { - turnsIntoOneTransaction({ - protyle, - selectsElement: newSourceParentElement.reverse(), - type: "BlocksMergeSuperBlock", - level: "row", - unfocus: true, - }); - } if (document.contains(sourceElements[0])) { focusBlock(sourceElements[0]); } else { diff --git a/app/src/protyle/wysiwyg/transaction.ts b/app/src/protyle/wysiwyg/transaction.ts index 768b11348..10e0bc65b 100644 --- a/app/src/protyle/wysiwyg/transaction.ts +++ b/app/src/protyle/wysiwyg/transaction.ts @@ -684,6 +684,17 @@ export const onTransaction = (protyle: IProtyle, operation: IOperation, isUndo: }); } /// #endif + // 折叠标题移动到横向超级块的第一个块上后撤销 + if (updateElements.length === 0) { + const tempEl = document.createElement("div"); + tempEl.setAttribute("data-node-id", operation.id); + updateElements.push(tempEl); + fetchPost("/api/block/getBlockDOM", { + id: operation.id, + }, (response) => { + document.querySelector(`[data-node-id="${operation.id}"]`).outerHTML = response.data.dom; + }); + } let range; if (isUndo && getSelection().rangeCount > 0) { range = getSelection().getRangeAt(0); @@ -940,7 +951,8 @@ export const turnsIntoOneTransaction = async (options: { selectsElement: Element[], type: TTurnIntoOne, level?: TTurnIntoOneSub, - unfocus?: boolean + unfocus?: boolean, + getOperations?: boolean, }) => { let parentElement: Element; const id = Lute.NewNodeID(); @@ -1055,6 +1067,12 @@ export const turnsIntoOneTransaction = async (options: { doOperations.push(...cancelOperations.doOperations); undoOperations.splice(0, 0, ...cancelOperations.undoOperations); } + if (options.getOperations) { + return { + doOperations, + undoOperations, + }; + } transaction(options.protyle, doOperations, undoOperations); if (!options.unfocus) { focusBlock(options.protyle.wysiwyg.element.querySelector(`[data-node-id="${options.selectsElement[0].getAttribute("data-node-id")}"]`));