mirror of
https://github.com/siyuan-note/siyuan.git
synced 2026-01-06 00:38:49 +01:00
This commit is contained in:
parent
49e07f92f5
commit
7a249761e2
2 changed files with 91 additions and 31 deletions
|
|
@ -44,10 +44,25 @@ const moveToNew = (protyle: IProtyle, sourceElements: Element[], targetElement:
|
|||
const newSourceId = newSourceElement.getAttribute("data-node-id");
|
||||
const doOperations: IOperation[] = [];
|
||||
const undoOperations: IOperation[] = [];
|
||||
targetElement.insertAdjacentElement(isBottom ? "afterend" : "beforebegin", newSourceElement);
|
||||
let ignoreInsert = false;
|
||||
if (isBottom &&
|
||||
targetElement.getAttribute("data-type") === "NodeHeading" &&
|
||||
targetElement.getAttribute("fold") === "1") {
|
||||
ignoreInsert = true;
|
||||
} else if (!isBottom && targetElement.previousElementSibling &&
|
||||
targetElement.previousElementSibling.getAttribute("data-type") === "NodeHeading" &&
|
||||
targetElement.previousElementSibling.getAttribute("fold") === "1") {
|
||||
ignoreInsert = true;
|
||||
}
|
||||
if (!ignoreInsert) {
|
||||
targetElement.insertAdjacentElement(isBottom ? "afterend" : "beforebegin", newSourceElement);
|
||||
}
|
||||
if (isBottom) {
|
||||
doOperations.push({
|
||||
action: "insert",
|
||||
context: {
|
||||
ignoreProcess: ignoreInsert.toString(),
|
||||
},
|
||||
data: newSourceElement.outerHTML,
|
||||
id: newSourceId,
|
||||
previousID: targetId,
|
||||
|
|
@ -55,6 +70,9 @@ const moveToNew = (protyle: IProtyle, sourceElements: Element[], targetElement:
|
|||
} else {
|
||||
doOperations.push({
|
||||
action: "insert",
|
||||
context: {
|
||||
ignoreProcess: ignoreInsert.toString(),
|
||||
},
|
||||
data: newSourceElement.outerHTML,
|
||||
id: newSourceId,
|
||||
nextID: targetId,
|
||||
|
|
@ -139,6 +157,7 @@ const moveToNew = (protyle: IProtyle, sourceElements: Element[], targetElement:
|
|||
id: newSourceId,
|
||||
});
|
||||
return {
|
||||
ignoreInsert,
|
||||
doOperations,
|
||||
undoOperations,
|
||||
topSourceElement,
|
||||
|
|
@ -150,9 +169,31 @@ const moveTo = async (protyle: IProtyle, sourceElements: Element[], targetElemen
|
|||
let topSourceElement;
|
||||
const doOperations: IOperation[] = [];
|
||||
const undoOperations: IOperation[] = [];
|
||||
const foldHeadingIds: { id: string, parentID: string }[] = [];
|
||||
const copyFoldHeadingIds: string[] = [];
|
||||
const targetId = targetElement.getAttribute("data-node-id");
|
||||
let tempTargetElement = targetElement;
|
||||
let ignoreInsert = "";
|
||||
if (position === "afterend" &&
|
||||
targetElement.getAttribute("data-type") === "NodeHeading" &&
|
||||
targetElement.getAttribute("fold") === "1") {
|
||||
ignoreInsert = targetElement.getAttribute("data-subtype");
|
||||
} else if (position === "beforebegin" && targetElement.previousElementSibling &&
|
||||
targetElement.previousElementSibling.getAttribute("data-type") === "NodeHeading" &&
|
||||
targetElement.previousElementSibling.getAttribute("fold") === "1") {
|
||||
ignoreInsert = targetElement.getAttribute("data-subtype");
|
||||
}
|
||||
if (ignoreInsert) {
|
||||
let breakIgnore = false;
|
||||
sourceElements.forEach(item => {
|
||||
if (item.getAttribute("data-type") === "NodeHeading" &&
|
||||
parseInt(item.getAttribute("data-subtype")) >= parseInt(ignoreInsert)) {
|
||||
breakIgnore = true;
|
||||
}
|
||||
if (!breakIgnore) {
|
||||
item.setAttribute("data-remove", "true");
|
||||
}
|
||||
});
|
||||
}
|
||||
sourceElements.reverse().forEach((item, index) => {
|
||||
const id = item.getAttribute("data-node-id");
|
||||
const parentID = item.parentElement.getAttribute("data-node-id") || protyle.block.rootID;
|
||||
|
|
@ -166,8 +207,7 @@ const moveTo = async (protyle: IProtyle, sourceElements: Element[], targetElemen
|
|||
}
|
||||
}
|
||||
if (isCopy && item.getAttribute("data-type") === "NodeHeading" && item.getAttribute("fold") === "1") {
|
||||
item.removeAttribute("fold");
|
||||
foldHeadingIds.push({id, parentID});
|
||||
copyFoldHeadingIds.push(id);
|
||||
}
|
||||
let copyId;
|
||||
let copyElement;
|
||||
|
|
@ -193,7 +233,10 @@ const moveTo = async (protyle: IProtyle, sourceElements: Element[], targetElemen
|
|||
}
|
||||
}
|
||||
|
||||
const needInset = !ignoreInsert || (ignoreInsert && !item.hasAttribute("data-remove"));
|
||||
|
||||
if (isCopy) {
|
||||
item.removeAttribute("data-remove");
|
||||
copyElement = item.cloneNode(true) as HTMLElement;
|
||||
copyElement.setAttribute("data-node-id", copyId);
|
||||
copyElement.querySelectorAll("[data-node-id]").forEach((e) => {
|
||||
|
|
@ -201,20 +244,30 @@ const moveTo = async (protyle: IProtyle, sourceElements: Element[], targetElemen
|
|||
e.setAttribute("data-node-id", newId);
|
||||
e.setAttribute("updated", newId.split("-")[0]);
|
||||
});
|
||||
tempTargetElement.insertAdjacentElement(position, copyElement);
|
||||
if (needInset) {
|
||||
tempTargetElement.insertAdjacentElement(position, copyElement);
|
||||
}
|
||||
doOperations.push({
|
||||
action: "insert",
|
||||
context: {
|
||||
ignoreProcess: (!needInset).toString(),
|
||||
},
|
||||
id: copyId,
|
||||
data: copyElement.outerHTML,
|
||||
previousID: position === "afterend" ? targetId : copyElement.previousElementSibling?.getAttribute("data-node-id"), // 不能使用常量,移动后会被修改
|
||||
previousID: position === "afterend" ? targetId : (!needInset ? targetElement : copyElement).previousElementSibling?.getAttribute("data-node-id"), // 不能使用常量,移动后会被修改
|
||||
parentID: copyElement.parentElement?.getAttribute("data-node-id") || protyle.block.parentID || protyle.block.rootID,
|
||||
});
|
||||
} else {
|
||||
tempTargetElement.insertAdjacentElement(position, item);
|
||||
if (needInset) {
|
||||
tempTargetElement.insertAdjacentElement(position, item);
|
||||
}
|
||||
doOperations.push({
|
||||
action: "move",
|
||||
context: {
|
||||
ignoreProcess: (!needInset).toString(),
|
||||
},
|
||||
id,
|
||||
previousID: position === "afterend" ? targetId : item.previousElementSibling?.getAttribute("data-node-id"), // 不能使用常量,移动后会被修改
|
||||
previousID: position === "afterend" ? targetId : (!needInset ? targetElement : item).previousElementSibling?.getAttribute("data-node-id"), // 不能使用常量,移动后会被修改
|
||||
parentID: item.parentElement?.getAttribute("data-node-id") || protyle.block.parentID || protyle.block.rootID,
|
||||
});
|
||||
}
|
||||
|
|
@ -222,29 +275,24 @@ const moveTo = async (protyle: IProtyle, sourceElements: Element[], targetElemen
|
|||
tempTargetElement = isCopy ? copyElement : item;
|
||||
}
|
||||
});
|
||||
undoOperations.reverse();
|
||||
for (let j = 0; j < foldHeadingIds.length; j++) {
|
||||
const childrenItem = foldHeadingIds[j];
|
||||
const headingIds = await fetchSyncPost("/api/block/getHeadingChildrenIDs", {id: childrenItem.id});
|
||||
headingIds.data.reverse().forEach((headingId: string) => {
|
||||
undoOperations.push({
|
||||
action: "move",
|
||||
id: headingId,
|
||||
previousID: childrenItem.id,
|
||||
parentID: childrenItem.parentID,
|
||||
});
|
||||
});
|
||||
undoOperations.push({
|
||||
action: "foldHeading",
|
||||
id: childrenItem.id,
|
||||
data: "remove"
|
||||
});
|
||||
doOperations.push({
|
||||
action: "unfoldHeading",
|
||||
id: childrenItem.id,
|
||||
if (ignoreInsert) {
|
||||
// 不能在上一个循环中移除,否则会影响位置的判断和 tempTargetElement
|
||||
sourceElements.forEach(item => {
|
||||
if (item.hasAttribute("data-remove")) {
|
||||
item.remove();
|
||||
}
|
||||
});
|
||||
}
|
||||
undoOperations.reverse();
|
||||
for (let j = 0; j < copyFoldHeadingIds.length; j++) {
|
||||
const childrenItem = copyFoldHeadingIds[j];
|
||||
const responseTransaction = await fetchSyncPost("/api/block/getHeadingInsertTransaction", {id: childrenItem});
|
||||
doOperations.push(...responseTransaction.data.doOperations);
|
||||
undoOperations.push(...responseTransaction.data.undoOperations);
|
||||
}
|
||||
// debugger
|
||||
return {
|
||||
ignoreInsert: ignoreInsert ? true : false,
|
||||
doOperations,
|
||||
undoOperations,
|
||||
topSourceElement,
|
||||
|
|
@ -622,6 +670,7 @@ const dragSame = async (protyle: IProtyle, sourceElements: Element[], targetElem
|
|||
newSourceElement.insertAdjacentHTML("beforeend", `<div class="protyle-attr" contenteditable="false">${Constants.ZWSP}</div>`);
|
||||
}
|
||||
let topSourceElement: Element;
|
||||
let ignoreInsert = false;
|
||||
let oldSourceParentElement = sourceElements[0].parentElement;
|
||||
if (isBottom) {
|
||||
if (newSourceElement) {
|
||||
|
|
@ -629,11 +678,13 @@ const dragSame = async (protyle: IProtyle, sourceElements: Element[], targetElem
|
|||
doOperations.push(...moveToResult.doOperations);
|
||||
undoOperations.push(...moveToResult.undoOperations);
|
||||
topSourceElement = moveToResult.topSourceElement;
|
||||
ignoreInsert = moveToResult.ignoreInsert;
|
||||
} else {
|
||||
const moveToResult = await moveTo(protyle, sourceElements, targetElement, isSameDoc, "afterend", isCopy);
|
||||
doOperations.push(...moveToResult.doOperations);
|
||||
undoOperations.push(...moveToResult.undoOperations);
|
||||
topSourceElement = moveToResult.topSourceElement;
|
||||
ignoreInsert = moveToResult.ignoreInsert;
|
||||
}
|
||||
} else {
|
||||
if (newSourceElement) {
|
||||
|
|
@ -641,11 +692,13 @@ const dragSame = async (protyle: IProtyle, sourceElements: Element[], targetElem
|
|||
doOperations.push(...moveToResult.doOperations);
|
||||
undoOperations.push(...moveToResult.undoOperations);
|
||||
topSourceElement = moveToResult.topSourceElement;
|
||||
ignoreInsert = moveToResult.ignoreInsert;
|
||||
} else {
|
||||
const moveToResult = await moveTo(protyle, sourceElements, targetElement, isSameDoc, "beforebegin", isCopy);
|
||||
doOperations.push(...moveToResult.doOperations);
|
||||
undoOperations.push(...moveToResult.undoOperations);
|
||||
topSourceElement = moveToResult.topSourceElement;
|
||||
ignoreInsert = moveToResult.ignoreInsert;
|
||||
}
|
||||
}
|
||||
if (targetElement.getAttribute("data-type") === "NodeListItem" && targetElement.getAttribute("data-subtype") === "o") {
|
||||
|
|
@ -783,9 +836,9 @@ const dragSame = async (protyle: IProtyle, sourceElements: Element[], targetElem
|
|||
/// #endif
|
||||
}
|
||||
if (isSameDoc || isCopy) {
|
||||
transaction(protyle, doOperations, undoOperations);
|
||||
transaction(protyle, doOperations, ignoreInsert ? undefined : undoOperations);
|
||||
} else {
|
||||
// 跨文档不支持撤销
|
||||
// 跨文档或插入折叠标题下不支持撤销
|
||||
transaction(protyle, doOperations);
|
||||
}
|
||||
let hasFoldHeading = false;
|
||||
|
|
@ -805,7 +858,11 @@ const dragSame = async (protyle: IProtyle, sourceElements: Element[], targetElem
|
|||
level: "row"
|
||||
});
|
||||
}
|
||||
focusBlock(sourceElements[0]);
|
||||
if (document.contains(sourceElements[0])) {
|
||||
focusBlock(sourceElements[0]);
|
||||
} else {
|
||||
focusBlock(targetElement);
|
||||
}
|
||||
};
|
||||
|
||||
export const dropEvent = (protyle: IProtyle, editorElement: HTMLElement) => {
|
||||
|
|
|
|||
|
|
@ -643,6 +643,9 @@ export const onTransaction = (protyle: IProtyle, operation: IOperation, isUndo:
|
|||
return;
|
||||
}
|
||||
if (operation.action === "move") {
|
||||
if (operation.context?.ignoreProcess === "true") {
|
||||
return;
|
||||
}
|
||||
/// #if !MOBILE
|
||||
if (updateElements.length === 0) {
|
||||
// 打开两个相同的文档 A、A1,从 A 拖拽块 B 到 A1,在后续 ws 处理中,无法获取到拖拽出去的 B
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue