Vanessa 2024-06-05 22:50:53 +08:00
parent bb1314c66f
commit bd264d7104
6 changed files with 179 additions and 123 deletions

View file

@ -14,20 +14,19 @@ import {copyPlainText, isMac, isOnlyMeta, openByMobile, updateHotkeyTip, writeTe
import {
transaction,
turnsIntoOneTransaction,
turnsIntoTransaction,
turnsIntoTransaction, turnsOneInto,
updateBatchTransaction,
updateTransaction
} from "../wysiwyg/transaction";
import {removeBlock} from "../wysiwyg/remove";
import {focusBlock, focusByRange, focusByWbr, getEditorRange} from "../util/selection";
import {focusBlock, focusByRange, getEditorRange} from "../util/selection";
import {hideElements} from "../ui/hideElements";
import {processRender} from "../util/processCode";
import {highlightRender} from "../render/highlightRender";
import {blockRender} from "../render/blockRender";
import {removeEmbed} from "../wysiwyg/removeEmbed";
import {getContenteditableElement, getTopAloneElement, isNotEditBlock} from "../wysiwyg/getBlock";
import * as dayjs from "dayjs";
import {fetchPost, fetchSyncPost} from "../../util/fetch";
import {fetchPost} from "../../util/fetch";
import {
cancelSB,
genEmptyElement,
@ -449,91 +448,8 @@ export class Gutter {
icon: options.icon,
label: options.label,
accelerator: options.accelerator,
async click() {
if (!options.nodeElement.querySelector("wbr")) {
getContenteditableElement(options.nodeElement)?.insertAdjacentHTML("afterbegin", "<wbr>");
}
if (options.type === "CancelList" || options.type === "CancelBlockquote") {
for await(const item of options.nodeElement.querySelectorAll('[data-type="NodeHeading"][fold="1"]')) {
const itemId = item.getAttribute("data-node-id");
item.removeAttribute("fold");
const response = await fetchSyncPost("/api/transactions", {
session: options.protyle.id,
app: Constants.SIYUAN_APPID,
transactions: [{
doOperations: [{
action: "unfoldHeading",
id: itemId,
}],
undoOperations: [{
action: "foldHeading",
id: itemId
}],
}]
});
options.protyle.undo.add([{
action: "unfoldHeading",
id: itemId,
}], [{
action: "foldHeading",
id: itemId
}], options.protyle);
item.insertAdjacentHTML("afterend", response.data[0].doOperations[0].retData);
}
}
const oldHTML = options.nodeElement.outerHTML;
const previousId = options.nodeElement.previousElementSibling?.getAttribute("data-node-id");
const parentId = options.nodeElement.parentElement.getAttribute("data-node-id") || options.protyle.block.parentID;
// @ts-ignore
const newHTML = options.protyle.lute[options.type](options.nodeElement.outerHTML, options.level);
options.nodeElement.outerHTML = newHTML;
if (options.type === "CancelList" || options.type === "CancelBlockquote") {
const tempElement = document.createElement("template");
tempElement.innerHTML = newHTML;
const doOperations: IOperation[] = [{
action: "delete",
id: options.id
}];
const undoOperations: IOperation[] = [];
let tempPreviousId = previousId;
Array.from(tempElement.content.children).forEach((item) => {
const tempId = item.getAttribute("data-node-id");
doOperations.push({
action: "insert",
data: item.outerHTML,
id: tempId,
previousID: tempPreviousId,
parentID: parentId
});
undoOperations.push({
action: "delete",
id: tempId
});
tempPreviousId = tempId;
});
undoOperations.push({
action: "insert",
data: oldHTML,
id: options.id,
previousID: previousId,
parentID: parentId
});
transaction(options.protyle, doOperations, undoOperations);
} else {
updateTransaction(options.protyle, options.id, newHTML, oldHTML);
}
focusByWbr(options.protyle.wysiwyg.element, getEditorRange(options.protyle.wysiwyg.element));
options.protyle.wysiwyg.element.querySelectorAll('[data-type~="block-ref"]').forEach(item => {
if (item.textContent === "") {
fetchPost("/api/block/getRefText", {id: item.getAttribute("data-id")}, (response) => {
item.innerHTML = response.data;
});
}
});
blockRender(options.protyle, options.protyle.wysiwyg.element);
processRender(options.protyle.wysiwyg.element);
highlightRender(options.protyle.wysiwyg.element);
avRender(options.protyle.wysiwyg.element, options.protyle);
click() {
turnsOneInto(options);
}
};
}

View file

@ -31,7 +31,13 @@ import {
import {matchHotKey} from "../util/hotKey";
import {enter, softEnter} from "./enter";
import {fixTable} from "../util/table";
import {turnsIntoOneTransaction, turnsIntoTransaction, updateBatchTransaction, updateTransaction} from "./transaction";
import {
turnsIntoOneTransaction,
turnsIntoTransaction,
turnsOneInto,
updateBatchTransaction,
updateTransaction
} from "./transaction";
import {fontEvent} from "../toolbar/Font";
import {addSubList, listIndent, listOutdent} from "./list";
import {newFileContentBySelect, rename, replaceFileName} from "../../editor/rename";
@ -1330,10 +1336,73 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => {
return true;
}
}
if (matchHotKey(window.siyuan.config.keymap.editor.insert.check.custom, event)) {
protyle.hint.splitChar = "/";
protyle.hint.lastIndex = -1;
protyle.hint.fill("* [ ] " + Lute.Caret, protyle);
const isMatchList = matchHotKey(window.siyuan.config.keymap.editor.insert.list.custom, event)
const isMatchCheck = matchHotKey(window.siyuan.config.keymap.editor.insert.check.custom, event)
const isMatchOList = matchHotKey(window.siyuan.config.keymap.editor.insert["ordered-list"].custom, event)
if (isMatchList || isMatchOList || isMatchCheck) {
const selectsElement: HTMLElement[] = Array.from(protyle.wysiwyg.element.querySelectorAll(".protyle-wysiwyg--select"));
if (selectsElement.length === 0) {
protyle.hint.splitChar = "/";
protyle.hint.lastIndex = -1;
protyle.hint.fill((isMatchCheck ? "* [ ] " : (isMatchList ? "* " : "1. ")) + Lute.Caret, protyle);
} else if (selectsElement.length === 1) {
const subType = selectsElement[0].dataset.subtype
const type = selectsElement[0].dataset.type
if (type === "NodeParagraph") {
turnsIntoOneTransaction({
protyle,
selectsElement,
type: isMatchCheck ? "Blocks2TLs" : (isMatchList ? "Blocks2ULs" : "Blocks2OLs")
});
} else if (type === "NodeList") {
const id = selectsElement[0].dataset.nodeId
if (subType === "o" && (isMatchList || isMatchCheck)) {
turnsOneInto({
protyle,
nodeElement: selectsElement[0],
id,
type: isMatchCheck ? "UL2TL" : "OL2UL",
});
} else if (subType === "t" && (isMatchList || isMatchOList)) {
turnsOneInto({
protyle,
nodeElement: selectsElement[0],
id,
type: isMatchList ? "TL2UL" : "TL2OL",
});
} else if (isMatchCheck || isMatchOList) {
turnsOneInto({
protyle,
nodeElement: selectsElement[0],
id,
type: isMatchCheck ? "OL2TL" : "UL2OL",
});
}
}
} else {
let isList = false;
let isContinue = false;
selectsElement.find((item, index) => {
if (item.classList.contains("li")) {
isList = true;
return true;
}
if (item.nextElementSibling && selectsElement[index + 1] &&
item.nextElementSibling.isSameNode(selectsElement[index + 1])) {
isContinue = true;
} else if (index !== selectsElement.length - 1) {
isContinue = false;
return true;
}
});
if (!isList && isContinue) {
turnsIntoOneTransaction({
protyle,
selectsElement,
type: isMatchCheck ? "Blocks2TLs" : (isMatchList ? "Blocks2ULs" : "Blocks2OLs")
});
}
}
event.preventDefault();
event.stopPropagation();
return;

View file

@ -1,6 +1,6 @@
import {fetchPost} from "../../util/fetch";
import {fetchPost, fetchSyncPost} from "../../util/fetch";
import {focusBlock, focusByWbr, focusSideBlock, getEditorRange} from "../util/selection";
import {getTopAloneElement} from "./getBlock";
import {getContenteditableElement, getTopAloneElement} from "./getBlock";
import {Constants} from "../../constants";
import {blockRender} from "../render/blockRender";
import {processRender} from "../util/processCode";
@ -1025,6 +1025,99 @@ export const turnsIntoTransaction = (options: {
hideElements(["gutter"], options.protyle);
};
export const turnsOneInto = async (options: {
protyle: IProtyle,
nodeElement: Element,
id: string,
type: string,
level?: number
}) => {
if (!options.nodeElement.querySelector("wbr")) {
getContenteditableElement(options.nodeElement)?.insertAdjacentHTML("afterbegin", "<wbr>");
}
if (options.type === "CancelList" || options.type === "CancelBlockquote") {
for await(const item of options.nodeElement.querySelectorAll('[data-type="NodeHeading"][fold="1"]')) {
const itemId = item.getAttribute("data-node-id");
item.removeAttribute("fold");
const response = await fetchSyncPost("/api/transactions", {
session: options.protyle.id,
app: Constants.SIYUAN_APPID,
transactions: [{
doOperations: [{
action: "unfoldHeading",
id: itemId,
}],
undoOperations: [{
action: "foldHeading",
id: itemId
}],
}]
});
options.protyle.undo.add([{
action: "unfoldHeading",
id: itemId,
}], [{
action: "foldHeading",
id: itemId
}], options.protyle);
item.insertAdjacentHTML("afterend", response.data[0].doOperations[0].retData);
}
}
const oldHTML = options.nodeElement.outerHTML;
const previousId = options.nodeElement.previousElementSibling?.getAttribute("data-node-id");
const parentId = options.nodeElement.parentElement.getAttribute("data-node-id") || options.protyle.block.parentID;
// @ts-ignore
const newHTML = options.protyle.lute[options.type](options.nodeElement.outerHTML, options.level);
options.nodeElement.outerHTML = newHTML;
if (options.type === "CancelList" || options.type === "CancelBlockquote") {
const tempElement = document.createElement("template");
tempElement.innerHTML = newHTML;
const doOperations: IOperation[] = [{
action: "delete",
id: options.id
}];
const undoOperations: IOperation[] = [];
let tempPreviousId = previousId;
Array.from(tempElement.content.children).forEach((item) => {
const tempId = item.getAttribute("data-node-id");
doOperations.push({
action: "insert",
data: item.outerHTML,
id: tempId,
previousID: tempPreviousId,
parentID: parentId
});
undoOperations.push({
action: "delete",
id: tempId
});
tempPreviousId = tempId;
});
undoOperations.push({
action: "insert",
data: oldHTML,
id: options.id,
previousID: previousId,
parentID: parentId
});
transaction(options.protyle, doOperations, undoOperations);
} else {
updateTransaction(options.protyle, options.id, newHTML, oldHTML);
}
focusByWbr(options.protyle.wysiwyg.element, getEditorRange(options.protyle.wysiwyg.element));
options.protyle.wysiwyg.element.querySelectorAll('[data-type~="block-ref"]').forEach(item => {
if (item.textContent === "") {
fetchPost("/api/block/getRefText", {id: item.getAttribute("data-id")}, (response) => {
item.innerHTML = response.data;
});
}
});
blockRender(options.protyle, options.protyle.wysiwyg.element);
processRender(options.protyle.wysiwyg.element);
highlightRender(options.protyle.wysiwyg.element);
avRender(options.protyle.wysiwyg.element, options.protyle);
}
const updateRef = (protyle: IProtyle, id: string, index = 0) => {
if (index > 6) {
return;