From 6f577f87abd6b32ec3d7f1e804efcda5a6365bfa Mon Sep 17 00:00:00 2001 From: Vanessa Date: Mon, 21 Nov 2022 23:36:49 +0800 Subject: [PATCH] :bug: https://github.com/siyuan-note/siyuan/issues/6648 --- app/src/protyle/util/editorCommonEvent.ts | 60 ++++++++++++---- app/src/protyle/wysiwyg/transaction.ts | 86 +++++++++++------------ 2 files changed, 90 insertions(+), 56 deletions(-) diff --git a/app/src/protyle/util/editorCommonEvent.ts b/app/src/protyle/util/editorCommonEvent.ts index 123e5240e..10edc840f 100644 --- a/app/src/protyle/util/editorCommonEvent.ts +++ b/app/src/protyle/util/editorCommonEvent.ts @@ -242,7 +242,7 @@ const dragSb = (protyle: IProtyle, sourceElements: Element[], targetElement: Ele focusBlock(sourceElements[0]); }; -const dragSame = (protyle: IProtyle, sourceElements: Element[], targetElement: Element, isBottom: boolean) => { +const dragSame = async (protyle: IProtyle, sourceElements: Element[], targetElement: Element, isBottom: boolean) => { const isSameDoc = protyle.element.contains(sourceElements[0]); const doOperations: IOperation[] = []; const undoOperations: IOperation[] = []; @@ -258,6 +258,7 @@ const dragSame = (protyle: IProtyle, sourceElements: Element[], targetElement: E } let topSourceElement: Element; let oldSourceParentElement = sourceElements[0].parentElement; + const targetId = targetElement.getAttribute("data-node-id") if (isBottom) { if (newSourceElement) { targetElement.insertAdjacentElement("afterend", newSourceElement); @@ -265,7 +266,7 @@ const dragSame = (protyle: IProtyle, sourceElements: Element[], targetElement: E action: "insert", data: newSourceElement.outerHTML, id: newSourceElement.getAttribute("data-node-id"), - previousID: targetElement.getAttribute("data-node-id"), + previousID: targetId, }); sourceElements.reverse().forEach((item, index) => { if (index === sourceElements.length - 1) { @@ -313,8 +314,13 @@ const dragSame = (protyle: IProtyle, sourceElements: Element[], targetElement: E id: newSourceElement.getAttribute("data-node-id"), }); } else { - sourceElements.reverse().forEach((item, index) => { - if (index === sourceElements.length - 1) { + const foldHeadingIds: string[] = [] + for (let i = sourceElements.length - 1; i >= 0; i--) { + const item = sourceElements[i]; + const id = item.getAttribute("data-node-id"); + const previousID = item.previousElementSibling?.getAttribute("data-node-id"); + const parentID = item.parentElement.getAttribute("data-node-id") || protyle.block.rootID + if (i === 0) { topSourceElement = getTopAloneElement(item); if (topSourceElement.isSameNode(item)) { topSourceElement = undefined; @@ -323,15 +329,32 @@ const dragSame = (protyle: IProtyle, sourceElements: Element[], targetElement: E topSourceElement = targetElement; } } + if (item.getAttribute("data-type") === "NodeHeading" && item.getAttribute("fold") === "1") { + foldHeadingIds.push(id); + const headingIds = await fetchSyncPost("/api/block/getHeadingChildrenIDs", {id}) + headingIds.data.reverse().forEach((headingId: string) => { + undoOperations.push({ + action: "move", + id, + previousID, + parentID, + }); + doOperations.push({ + action: "move", + id:headingId, + previousID: targetId, + }); + }) + } undoOperations.push({ action: "move", - id: item.getAttribute("data-node-id"), - previousID: item.previousElementSibling?.getAttribute("data-node-id"), - parentID: item.parentElement.getAttribute("data-node-id") || protyle.block.rootID, + id, + previousID, + parentID, }); if (!isSameDoc) { // 打开两个相同的文档 - const sameElement = protyle.wysiwyg.element.querySelector(`[data-node-id="${item.getAttribute("data-node-id")}"]`); + const sameElement = protyle.wysiwyg.element.querySelector(`[data-node-id="${id}"]`); if (sameElement) { sameElement.remove(); } @@ -339,11 +362,22 @@ const dragSame = (protyle: IProtyle, sourceElements: Element[], targetElement: E targetElement.insertAdjacentElement("afterend", item); doOperations.push({ action: "move", - id: item.getAttribute("data-node-id"), - previousID: targetElement.getAttribute("data-node-id"), + id, + previousID: targetId, }); - }); + } undoOperations.reverse(); + foldHeadingIds.forEach(id => { + undoOperations.push({ + action: "foldHeading", + id, + data: "remove" + }); + doOperations.push({ + action: "unfoldHeading", + id, + }); + }) } } else { if (newSourceElement) { @@ -352,7 +386,7 @@ const dragSame = (protyle: IProtyle, sourceElements: Element[], targetElement: E action: "insert", data: newSourceElement.outerHTML, id: newSourceElement.getAttribute("data-node-id"), - nextID: targetElement.getAttribute("data-node-id"), + nextID: targetId, }); sourceElements.reverse().forEach((item, index) => { if (index === sourceElements.length - 1) { @@ -644,7 +678,7 @@ export const dropEvent = (protyle: IProtyle, editorElement: HTMLElement) => { && targetElement && !protyle.options.backlinkData) { // 文件树拖拽 const scrollTop = protyle.contentElement.scrollTop; - const ids = event.dataTransfer.getData(Constants.SIYUAN_DROP_FILE).split(","); + const ids = event.dataTransfer.getData(Constants.SIYUAN_DROP_FILE).split(","); for (let i = 0; i < ids.length; i++) { if (ids[i]) { const response = await fetchSyncPost("/api/filetree/doc2Heading", { diff --git a/app/src/protyle/wysiwyg/transaction.ts b/app/src/protyle/wysiwyg/transaction.ts index 7f9c52105..8b54d84ae 100644 --- a/app/src/protyle/wysiwyg/transaction.ts +++ b/app/src/protyle/wysiwyg/transaction.ts @@ -73,49 +73,6 @@ const promiseTransaction = () => { return; } countBlockWord([], protyle.block.rootID, true); - if (doOperations.length === 1 && (doOperations[0].action === "unfoldHeading" || doOperations[0].action === "foldHeading")) { - const gutterFoldElement = protyle.gutter.element.querySelector('[data-type="fold"]'); - if (gutterFoldElement) { - gutterFoldElement.removeAttribute("disabled"); - } - if (doOperations[0].action === "unfoldHeading") { - const scrollTop = protyle.contentElement.scrollTop; - protyle.wysiwyg.element.querySelectorAll(`[data-node-id="${doOperations[0].id}"]`).forEach(item => { - if (!item.lastElementChild.classList.contains("protyle-attr")) { - item.lastElementChild.remove(); - } - removeUnfoldRepeatBlock(response.data[0].doOperations[0].retData, protyle); - item.insertAdjacentHTML("afterend", response.data[0].doOperations[0].retData); - if (doOperations[0].data === "remove") { - // https://github.com/siyuan-note/siyuan/issues/2188 - const selection = getSelection(); - if (selection.rangeCount > 0 && item.contains(selection.getRangeAt(0).startContainer)) { - focusBlock(item.nextElementSibling, undefined, true); - } - item.remove(); - } - }); - processRender(protyle.wysiwyg.element); - highlightRender(protyle.wysiwyg.element); - blockRender(protyle, protyle.wysiwyg.element); - protyle.contentElement.scrollTop = scrollTop; - protyle.scroll.lastScrollTop = scrollTop; - } else if (doOperations[0].action === "foldHeading") { - // 折叠标题后未触发动态加载 https://github.com/siyuan-note/siyuan/issues/4168 - if (protyle.wysiwyg.element.lastElementChild.getAttribute("data-eof") !== "true" && - !protyle.scroll.element.classList.contains("fn__none")) { - fetchPost("/api/filetree/getDoc", { - id: protyle.wysiwyg.element.lastElementChild.getAttribute("data-node-id"), - mode: 2, - k: protyle.options.key || "", - size: window.siyuan.config.editor.dynamicLoadBlocks, - }, getResponse => { - onGet(getResponse, protyle, [Constants.CB_GET_APPEND, Constants.CB_GET_UNCHANGEID]); - }); - } - } - return; - } if (doOperations[0].action === "setAttrs") { const gutterFoldElement = protyle.gutter.element.querySelector('[data-type="fold"]'); if (gutterFoldElement) { @@ -136,6 +93,49 @@ const promiseTransaction = () => { range = getSelection().getRangeAt(0); } doOperations.forEach(operation => { + if (operation.action === "unfoldHeading" || operation.action === "foldHeading") { + const gutterFoldElement = protyle.gutter.element.querySelector('[data-type="fold"]'); + if (gutterFoldElement) { + gutterFoldElement.removeAttribute("disabled"); + } + if (operation.action === "unfoldHeading") { + const scrollTop = protyle.contentElement.scrollTop; + protyle.wysiwyg.element.querySelectorAll(`[data-node-id="${operation.id}"]`).forEach(item => { + if (!item.lastElementChild.classList.contains("protyle-attr")) { + item.lastElementChild.remove(); + } + removeUnfoldRepeatBlock(operation.retData, protyle); + item.insertAdjacentHTML("afterend", operation.retData); + if (operation.data === "remove") { + // https://github.com/siyuan-note/siyuan/issues/2188 + const selection = getSelection(); + if (selection.rangeCount > 0 && item.contains(selection.getRangeAt(0).startContainer)) { + focusBlock(item.nextElementSibling, undefined, true); + } + item.remove(); + } + }); + processRender(protyle.wysiwyg.element); + highlightRender(protyle.wysiwyg.element); + blockRender(protyle, protyle.wysiwyg.element); + protyle.contentElement.scrollTop = scrollTop; + protyle.scroll.lastScrollTop = scrollTop; + return; + } + // 折叠标题后未触发动态加载 https://github.com/siyuan-note/siyuan/issues/4168 + if (protyle.wysiwyg.element.lastElementChild.getAttribute("data-eof") !== "true" && + !protyle.scroll.element.classList.contains("fn__none")) { + fetchPost("/api/filetree/getDoc", { + id: protyle.wysiwyg.element.lastElementChild.getAttribute("data-node-id"), + mode: 2, + k: protyle.options.key || "", + size: window.siyuan.config.editor.dynamicLoadBlocks, + }, getResponse => { + onGet(getResponse, protyle, [Constants.CB_GET_APPEND, Constants.CB_GET_UNCHANGEID]); + }); + } + return; + } if (operation.action === "update") { if (protyle.options.backlinkData) { // 反链中有多个相同块的情况