From 67cf800d960ae2a0567a68f55dd30433e9ddd896 Mon Sep 17 00:00:00 2001 From: Vanessa Date: Sun, 13 Apr 2025 00:06:02 +0800 Subject: [PATCH] :art: https://github.com/siyuan-note/siyuan/issues/14551 --- app/src/protyle/wysiwyg/transaction.ts | 121 +++++++++++++++---------- 1 file changed, 74 insertions(+), 47 deletions(-) diff --git a/app/src/protyle/wysiwyg/transaction.ts b/app/src/protyle/wysiwyg/transaction.ts index 12efee664..f97a28712 100644 --- a/app/src/protyle/wysiwyg/transaction.ts +++ b/app/src/protyle/wysiwyg/transaction.ts @@ -1036,7 +1036,7 @@ export const turnsIntoTransaction = (options: { let html = ""; const doOperations: IOperation[] = []; const undoOperations: IOperation[] = []; - const tempElement = document.createElement("div"); + let previousId: string; selectsElement.forEach((item, index) => { if ((options.type === "Blocks2Ps" || options.type === "Blocks2Hs") && item.getAttribute("data-type") === "NodeHeading" && item.getAttribute("fold") === "1") { @@ -1047,64 +1047,91 @@ export const turnsIntoTransaction = (options: { item.removeAttribute("select-end"); html += item.outerHTML; const id = item.getAttribute("data-node-id"); - undoOperations.push({ - action: "update", - id, - data: item.outerHTML, - parentID: item.parentElement?.getAttribute("data-node-id") || options.protyle.block.parentID || options.protyle.block.rootID, - previousID: undoOperations[undoOperations.length - 1]?.id || item.previousElementSibling?.getAttribute("data-node-id") - }); + const tempElement = document.createElement("template"); if (!options.isContinue) { // @ts-ignore - item.outerHTML = options.protyle.lute[options.type](item.outerHTML, options.level); - } else { - if (index === selectsElement.length - 1) { - // @ts-ignore - tempElement.innerHTML = options.protyle.lute[options.type](html, options.level); - item.outerHTML = tempElement.innerHTML; + const newHTML = options.protyle.lute[options.type](item.outerHTML, options.level); + tempElement.innerHTML = newHTML; + + if (!tempElement.content.querySelector(`[data-node-id="${id}"]`)) { + undoOperations.push({ + action: "insert", + id, + previousID: previousId || item.previousElementSibling?.getAttribute("data-node-id"), + data: item.outerHTML, + parentID: item.parentElement?.getAttribute("data-node-id") || options.protyle.block.parentID || options.protyle.block.rootID, + }); + Array.from(tempElement.content.children).forEach((tempItem: HTMLElement) => { + const tempItemId = tempItem.getAttribute("data-node-id"); + doOperations.push({ + action: "insert", + id: tempItemId, + previousID: tempItem.previousElementSibling?.getAttribute("data-node-id") || item.previousElementSibling?.getAttribute("data-node-id"), + data: tempItem.outerHTML, + parentID: item.parentElement?.getAttribute("data-node-id") || options.protyle.block.parentID || options.protyle.block.rootID, + }); + undoOperations.splice(0, 0, { + action: "delete", + id: tempItemId, + }); + }); + doOperations.push({ + action: "delete", + id, + }); + if (item.isSameNode(selectsElement[index + 1]?.previousElementSibling)) { + previousId = id; + } else { + previousId = undefined; + } } else { - item.remove(); + undoOperations.push({ + action: "update", + id, + data: item.outerHTML, + }); + doOperations.push({ + action: "update", + id: item.id, + data: newHTML + }); } - } - }); - undoOperations.forEach(item => { - const nodeElement = options.protyle.wysiwyg.element.querySelector(`[data-node-id="${item.id}"]`); - if (!nodeElement) { - item.action = "insert"; - doOperations.push({ - action: "delete", - id: item.id, - }); + item.outerHTML = newHTML; } else { - doOperations.push({ - action: "update", - id: item.id, - data: nodeElement.outerHTML - }); - } - }); - Array.from(tempElement.children).forEach(item => { - const itemId = item.getAttribute("data-node-id"); - let find = false; - undoOperations.find(undoItem => { - if (itemId === undoItem.id) { - find = true; - return true; - } - }); - if (!find) { - doOperations.push({ + undoOperations.push({ action: "insert", - id: itemId, - previousID: item.previousElementSibling?.getAttribute("data-node-id") || undoOperations[0].previousID, + id, + previousID: doOperations[doOperations.length - 1]?.id || item.previousElementSibling?.getAttribute("data-node-id"), data: item.outerHTML, parentID: item.parentElement?.getAttribute("data-node-id") || options.protyle.block.parentID || options.protyle.block.rootID, }); - undoOperations.splice(0, 0, { + doOperations.push({ action: "delete", - id: itemId, + id, }); + if (index === selectsElement.length - 1) { + // @ts-ignore + const newHTML = options.protyle.lute[options.type](html, options.level); + tempElement.innerHTML = newHTML; + Array.from(tempElement.content.children).forEach((tempItem: HTMLElement) => { + const tempItemId = tempItem.getAttribute("data-node-id"); + doOperations.push({ + action: "insert", + id: tempItemId, + previousID: tempItem.previousElementSibling?.getAttribute("data-node-id") || item.previousElementSibling?.getAttribute("data-node-id"), + data: tempItem.outerHTML, + parentID: item.parentElement?.getAttribute("data-node-id") || options.protyle.block.parentID || options.protyle.block.rootID, + }); + undoOperations.splice(0, 0, { + action: "delete", + id: tempItemId, + }); + }); + item.outerHTML = newHTML; + } else { + item.remove(); + } } }); transaction(options.protyle, doOperations, undoOperations);