mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-23 01:50:12 +01:00
This commit is contained in:
parent
c533dd49a8
commit
9084fe20b0
4 changed files with 97 additions and 59 deletions
|
|
@ -6,6 +6,50 @@ import {transaction, updateTransaction} from "../protyle/wysiwyg/transaction";
|
||||||
import {scrollCenter} from "../util/highlightById";
|
import {scrollCenter} from "../util/highlightById";
|
||||||
import {Constants} from "../constants";
|
import {Constants} from "../constants";
|
||||||
|
|
||||||
|
export const cancelSB = (protyle: IProtyle, nodeElement: Element) => {
|
||||||
|
const doOperations: IOperation[] = [];
|
||||||
|
const undoOperations: IOperation[] = [];
|
||||||
|
let previousId = nodeElement.previousElementSibling ? nodeElement.previousElementSibling.getAttribute("data-node-id") : undefined;
|
||||||
|
nodeElement.classList.remove("protyle-wysiwyg--select");
|
||||||
|
const id = nodeElement.getAttribute("data-node-id")
|
||||||
|
const sbElement = genSBElement(nodeElement.getAttribute("data-sb-layout"), id, nodeElement.lastElementChild.outerHTML);
|
||||||
|
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
|
||||||
|
});
|
||||||
|
Array.from(nodeElement.children).forEach((item, index) => {
|
||||||
|
if (index === nodeElement.childElementCount - 1) {
|
||||||
|
doOperations.push({
|
||||||
|
action: "delete",
|
||||||
|
id,
|
||||||
|
});
|
||||||
|
nodeElement.lastElementChild.remove();
|
||||||
|
nodeElement.outerHTML = nodeElement.innerHTML;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
doOperations.push({
|
||||||
|
action: "move",
|
||||||
|
id: item.getAttribute("data-node-id"),
|
||||||
|
previousID: previousId,
|
||||||
|
parentID: nodeElement.parentElement.getAttribute("data-node-id") || protyle.block.parentID
|
||||||
|
});
|
||||||
|
undoOperations.push({
|
||||||
|
action: "move",
|
||||||
|
id: item.getAttribute("data-node-id"),
|
||||||
|
previousID: item.previousElementSibling ? item.previousElementSibling.getAttribute("data-node-id") : undefined,
|
||||||
|
parentID: id
|
||||||
|
});
|
||||||
|
previousId = item.getAttribute("data-node-id");
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
doOperations, undoOperations, previousId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const genSBElement = (layout: string, id?: string, attrHTML?: string) => {
|
export const genSBElement = (layout: string, id?: string, attrHTML?: string) => {
|
||||||
const sbElement = document.createElement("div");
|
const sbElement = document.createElement("div");
|
||||||
sbElement.setAttribute("data-node-id", id || Lute.NewNodeID());
|
sbElement.setAttribute("data-node-id", id || Lute.NewNodeID());
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import {removeEmbed} from "../wysiwyg/removeEmbed";
|
||||||
import {getContenteditableElement, getTopAloneElement, isNotEditBlock} from "../wysiwyg/getBlock";
|
import {getContenteditableElement, getTopAloneElement, isNotEditBlock} from "../wysiwyg/getBlock";
|
||||||
import * as dayjs from "dayjs";
|
import * as dayjs from "dayjs";
|
||||||
import {fetchPost} from "../../util/fetch";
|
import {fetchPost} from "../../util/fetch";
|
||||||
import {genSBElement, insertEmptyBlock} from "../../block/util";
|
import {cancelSB, insertEmptyBlock} from "../../block/util";
|
||||||
import {scrollCenter} from "../../util/highlightById";
|
import {scrollCenter} from "../../util/highlightById";
|
||||||
import {isMobile} from "../../util/functions";
|
import {isMobile} from "../../util/functions";
|
||||||
import {confirmDialog} from "../../dialog/confirmDialog";
|
import {confirmDialog} from "../../dialog/confirmDialog";
|
||||||
|
|
@ -883,44 +883,9 @@ export class Gutter {
|
||||||
window.siyuan.menus.menu.append(new MenuItem({
|
window.siyuan.menus.menu.append(new MenuItem({
|
||||||
label: window.siyuan.languages.cancel + " " + window.siyuan.languages.superBlock,
|
label: window.siyuan.languages.cancel + " " + window.siyuan.languages.superBlock,
|
||||||
click() {
|
click() {
|
||||||
const doOperations: IOperation[] = [];
|
const sbData = cancelSB(protyle, nodeElement);
|
||||||
const undoOperations: IOperation[] = [];
|
transaction(protyle, sbData.doOperations, sbData.undoOperations);
|
||||||
let previousId = nodeElement.previousElementSibling ? nodeElement.previousElementSibling.getAttribute("data-node-id") : undefined;
|
focusBlock(protyle.wysiwyg.element.querySelector(`[data-node-id="${sbData.previousId}"]`));
|
||||||
nodeElement.classList.remove("protyle-wysiwyg--select");
|
|
||||||
const sbElement = genSBElement(nodeElement.getAttribute("data-sb-layout"), id, nodeElement.lastElementChild.outerHTML);
|
|
||||||
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
|
|
||||||
});
|
|
||||||
Array.from(nodeElement.children).forEach((item, index) => {
|
|
||||||
if (index === nodeElement.childElementCount - 1) {
|
|
||||||
doOperations.push({
|
|
||||||
action: "delete",
|
|
||||||
id,
|
|
||||||
});
|
|
||||||
nodeElement.lastElementChild.remove();
|
|
||||||
nodeElement.outerHTML = nodeElement.innerHTML;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
doOperations.push({
|
|
||||||
action: "move",
|
|
||||||
id: item.getAttribute("data-node-id"),
|
|
||||||
previousID: previousId,
|
|
||||||
parentID: nodeElement.parentElement.getAttribute("data-node-id") || protyle.block.parentID
|
|
||||||
});
|
|
||||||
undoOperations.push({
|
|
||||||
action: "move",
|
|
||||||
id: item.getAttribute("data-node-id"),
|
|
||||||
previousID: item.previousElementSibling ? item.previousElementSibling.getAttribute("data-node-id") : undefined,
|
|
||||||
parentID: id
|
|
||||||
});
|
|
||||||
previousId = item.getAttribute("data-node-id");
|
|
||||||
});
|
|
||||||
transaction(protyle, doOperations, undoOperations);
|
|
||||||
focusBlock(protyle.wysiwyg.element.querySelector(`[data-node-id="${previousId}"]`));
|
|
||||||
hideElements(["gutter"], protyle);
|
hideElements(["gutter"], protyle);
|
||||||
}
|
}
|
||||||
}).element);
|
}).element);
|
||||||
|
|
|
||||||
|
|
@ -139,6 +139,7 @@ export const getTopAloneElement = (topSourceElement: Element) => {
|
||||||
} else if (topSourceElement.parentElement.getAttribute("data-type") === "NodeListItem" && topSourceElement.parentElement.childElementCount === 3) {
|
} else if (topSourceElement.parentElement.getAttribute("data-type") === "NodeListItem" && topSourceElement.parentElement.childElementCount === 3) {
|
||||||
topSourceElement = topSourceElement.parentElement;
|
topSourceElement = topSourceElement.parentElement;
|
||||||
} else {
|
} else {
|
||||||
|
topSourceElement = getTopAloneElement(topSourceElement);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import {
|
||||||
getTopEmptyElement, hasNextSibling
|
getTopEmptyElement, hasNextSibling
|
||||||
} from "./getBlock";
|
} from "./getBlock";
|
||||||
import {transaction, updateTransaction} from "./transaction";
|
import {transaction, updateTransaction} from "./transaction";
|
||||||
import {genEmptyElement} from "../../block/util";
|
import {cancelSB, genEmptyElement} from "../../block/util";
|
||||||
import {listOutdent, updateListOrder} from "./list";
|
import {listOutdent, updateListOrder} from "./list";
|
||||||
import {setFold, zoomOut} from "../../menus/protyle";
|
import {setFold, zoomOut} from "../../menus/protyle";
|
||||||
import {preventScroll} from "../scroll/preventScroll";
|
import {preventScroll} from "../scroll/preventScroll";
|
||||||
|
|
@ -180,9 +180,11 @@ export const removeBlock = (protyle: IProtyle, blockElement: Element, range: Ran
|
||||||
let sideElement = selectElements[0].previousElementSibling || selectElements[selectElements.length - 1].nextElementSibling;
|
let sideElement = selectElements[0].previousElementSibling || selectElements[selectElements.length - 1].nextElementSibling;
|
||||||
let listElement: Element;
|
let listElement: Element;
|
||||||
let topElementId: string;
|
let topElementId: string;
|
||||||
|
let topParentElement: Element
|
||||||
selectElements.find((item: HTMLElement) => {
|
selectElements.find((item: HTMLElement) => {
|
||||||
item.classList.remove("protyle-wysiwyg--select");
|
item.classList.remove("protyle-wysiwyg--select");
|
||||||
const topElement = getTopAloneElement(item);
|
const topElement = getTopAloneElement(item);
|
||||||
|
topParentElement = topElement.parentElement
|
||||||
topElementId = topElement.getAttribute("data-node-id");
|
topElementId = topElement.getAttribute("data-node-id");
|
||||||
const id = topElement.getAttribute("data-node-id");
|
const id = topElement.getAttribute("data-node-id");
|
||||||
deletes.push({
|
deletes.push({
|
||||||
|
|
@ -238,8 +240,7 @@ export const removeBlock = (protyle: IProtyle, blockElement: Element, range: Ran
|
||||||
zoomOut(protyle, protyle.block.parent2ID, protyle.block.parent2ID);
|
zoomOut(protyle, protyle.block.parent2ID, protyle.block.parent2ID);
|
||||||
}, Constants.TIMEOUT_INPUT * 2 + 100);
|
}, Constants.TIMEOUT_INPUT * 2 + 100);
|
||||||
} else {
|
} else {
|
||||||
if ((sideElement.classList.contains("protyle-wysiwyg") && protyle.wysiwyg.element.childElementCount === 0) ||
|
if ((sideElement.classList.contains("protyle-wysiwyg") && protyle.wysiwyg.element.childElementCount === 0)) {
|
||||||
((sideElement.classList.contains("bq") || sideElement.classList.contains("sb")) && sideElement.childElementCount === 1)) {
|
|
||||||
const emptyElement = genEmptyElement(false, true, topElementId);
|
const emptyElement = genEmptyElement(false, true, topElementId);
|
||||||
sideElement.insertAdjacentElement("afterbegin", emptyElement);
|
sideElement.insertAdjacentElement("afterbegin", emptyElement);
|
||||||
deletes.push({
|
deletes.push({
|
||||||
|
|
@ -273,8 +274,14 @@ export const removeBlock = (protyle: IProtyle, blockElement: Element, range: Ran
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (deletes.length > 0) {
|
if (deletes.length > 0) {
|
||||||
transaction(protyle, deletes, inserts.reverse());
|
if (topParentElement && topParentElement.getAttribute("data-type") === "NodeSuperBlock" && topParentElement.childElementCount === 2) {
|
||||||
|
const sbData = cancelSB(protyle, topParentElement);
|
||||||
|
transaction(protyle, deletes.concat(sbData.doOperations), sbData.undoOperations.concat(inserts.reverse()));
|
||||||
|
} else {
|
||||||
|
transaction(protyle, deletes, inserts.reverse());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hideElements(["util"], protyle);
|
hideElements(["util"], protyle);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -371,29 +378,42 @@ export const removeBlock = (protyle: IProtyle, blockElement: Element, range: Ran
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const parentElement = blockElement.parentElement
|
||||||
const editableElement = getContenteditableElement(blockElement);
|
const editableElement = getContenteditableElement(blockElement);
|
||||||
const previousLastElement = getLastBlock(previousElement) as HTMLElement;
|
const previousLastElement = getLastBlock(previousElement) as HTMLElement;
|
||||||
const isSelectNode = previousLastElement && (previousLastElement.classList.contains("table") || previousLastElement.classList.contains("render-node") || previousLastElement.classList.contains("iframe") || previousLastElement.classList.contains("hr") || previousLastElement.classList.contains("code-block"));
|
const isSelectNode = previousLastElement && (previousLastElement.classList.contains("table") || previousLastElement.classList.contains("render-node") || previousLastElement.classList.contains("iframe") || previousLastElement.classList.contains("hr") || previousLastElement.classList.contains("code-block"));
|
||||||
if (isSelectNode) {
|
if (isSelectNode) {
|
||||||
if (previousLastElement.classList.contains("code-block")) {
|
if (previousLastElement.classList.contains("code-block")) {
|
||||||
focusBlock(previousLastElement, undefined, false);
|
|
||||||
if (editableElement.textContent.trim() === "") {
|
if (editableElement.textContent.trim() === "") {
|
||||||
|
const previousId = previousLastElement.getAttribute("data-node-id")
|
||||||
const id = blockElement.getAttribute("data-node-id");
|
const id = blockElement.getAttribute("data-node-id");
|
||||||
transaction(protyle, [{
|
const doOperations: IOperation[] = [{
|
||||||
action: "delete",
|
action: "delete",
|
||||||
id,
|
id,
|
||||||
}], [{
|
}]
|
||||||
|
const undoOperations: IOperation[] = [{
|
||||||
action: "insert",
|
action: "insert",
|
||||||
data: blockElement.outerHTML,
|
data: blockElement.outerHTML,
|
||||||
id: id,
|
id: id,
|
||||||
previousID: previousLastElement.getAttribute("data-node-id")
|
previousID: blockElement.previousElementSibling?.getAttribute("data-node-id"),
|
||||||
}]);
|
parentID: blockElement.parentElement.getAttribute("data-node-id")
|
||||||
|
}]
|
||||||
blockElement.remove();
|
blockElement.remove();
|
||||||
|
// 取消超级块
|
||||||
|
if (parentElement.getAttribute("data-type") === "NodeSuperBlock" && parentElement.childElementCount === 2) {
|
||||||
|
const sbData = cancelSB(protyle, parentElement);
|
||||||
|
transaction(protyle, doOperations.concat(sbData.doOperations), sbData.undoOperations.concat(undoOperations));
|
||||||
|
} else {
|
||||||
|
transaction(protyle, doOperations, undoOperations);
|
||||||
|
}
|
||||||
|
focusBlock(protyle.wysiwyg.element.querySelector(`[data-node-id="${previousId}"]`), undefined, false);
|
||||||
|
} else {
|
||||||
|
focusBlock(previousLastElement, undefined, false);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
previousLastElement.classList.add("protyle-wysiwyg--select");
|
previousLastElement.classList.add("protyle-wysiwyg--select");
|
||||||
if (previousLastElement.getAttribute("data-type") === "NodeBlockQueryEmbed" || editableElement.textContent !== "" || protyle.wysiwyg.element.childElementCount === 2) {
|
if (previousLastElement.getAttribute("data-type") === "NodeBlockQueryEmbed" || editableElement.textContent !== "") {
|
||||||
focusByRange(range);
|
focusByRange(range);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -412,7 +432,12 @@ export const removeBlock = (protyle: IProtyle, blockElement: Element, range: Ran
|
||||||
data: removeElement.outerHTML,
|
data: removeElement.outerHTML,
|
||||||
id: removeId,
|
id: removeId,
|
||||||
// 不能使用 previousLastElement,否则在超级块下的元素前删除撤销错误
|
// 不能使用 previousLastElement,否则在超级块下的元素前删除撤销错误
|
||||||
previousID: previousElement.getAttribute("data-node-id"),
|
previousID: blockElement.previousElementSibling?.getAttribute("data-node-id"),
|
||||||
|
parentID: parentElement.getAttribute("data-node-id")
|
||||||
|
}];
|
||||||
|
const doOperations: IOperation[] = [{
|
||||||
|
action: "delete",
|
||||||
|
id: removeId,
|
||||||
}];
|
}];
|
||||||
|
|
||||||
if (isSelectNode) {
|
if (isSelectNode) {
|
||||||
|
|
@ -441,14 +466,17 @@ export const removeBlock = (protyle: IProtyle, blockElement: Element, range: Ran
|
||||||
// extractContents 内容过多时需要进行滚动条重置,否则位置会错位
|
// extractContents 内容过多时需要进行滚动条重置,否则位置会错位
|
||||||
protyle.contentElement.scrollTop = scroll;
|
protyle.contentElement.scrollTop = scroll;
|
||||||
protyle.scroll.lastScrollTop = scroll - 1;
|
protyle.scroll.lastScrollTop = scroll - 1;
|
||||||
|
doOperations.push({
|
||||||
|
action: "update",
|
||||||
|
data: previousLastElement.outerHTML,
|
||||||
|
id: newId,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
transaction(protyle, [{
|
if (parentElement.getAttribute("data-type") === "NodeSuperBlock" && parentElement.childElementCount === 2) {
|
||||||
action: "delete",
|
const sbData = cancelSB(protyle, parentElement);
|
||||||
id: removeId,
|
transaction(protyle, doOperations.concat(sbData.doOperations), sbData.undoOperations.concat(undoOperations));
|
||||||
}, {
|
} else {
|
||||||
action: "update",
|
transaction(protyle, doOperations, undoOperations);
|
||||||
data: previousLastElement.outerHTML,
|
}
|
||||||
id: newId,
|
focusByWbr(protyle.wysiwyg.element, range);
|
||||||
}], undoOperations);
|
|
||||||
focusByWbr(previousLastElement, range);
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue