This commit is contained in:
Vanessa 2022-08-29 20:57:33 +08:00
parent e59cf202f6
commit 6fefdb9064
3 changed files with 306 additions and 221 deletions

View file

@ -6,13 +6,12 @@ import {copySubMenu, openAttr, openWechatNotify} from "../../menus/commonMenuIte
import {updateHotkeyTip, writeText} from "../util/compatibility";
import {
transaction,
turnIntoTransaction,
turnsIntoTransaction,
turnsIntoOneTransaction, turnsIntoTransaction,
updateBatchTransaction,
updateTransaction
} from "../wysiwyg/transaction";
import {removeBlock} from "../wysiwyg/remove";
import {focusBlock, focusByRange, getEditorRange} from "../util/selection";
import {focusBlock, focusByRange, focusByWbr, getEditorRange} from "../util/selection";
import {hideElements} from "../ui/hideElements";
import {processRender} from "../util/processCode";
import {highlightRender} from "../markdown/highlightRender";
@ -20,13 +19,14 @@ import {blockRender} from "../markdown/blockRender";
import {removeEmbed} from "../wysiwyg/removeEmbed";
import {getContenteditableElement, getTopAloneElement, isNotEditBlock} from "../wysiwyg/getBlock";
import * as dayjs from "dayjs";
import {fetchPost} from "../../util/fetch";
import {fetchPost, fetchSyncPost} from "../../util/fetch";
import {cancelSB, insertEmptyBlock, jumpToParentNext} from "../../block/util";
import {scrollCenter} from "../../util/highlightById";
import {isMobile} from "../../util/functions";
import {confirmDialog} from "../../dialog/confirmDialog";
import {enableProtyle} from "../util/onGet";
import {countBlockWord} from "../../layout/status";
import {Constants} from "../../constants";
export class Gutter {
public element: HTMLElement;
@ -230,12 +230,104 @@ export class Gutter {
});
}
private turnInto(options: { icon: string, label: string, protyle: IProtyle, nodeElement: Element, id: string, type: string, level?: number }) {
private turnsOneInto(options: {
icon: string,
label: string,
protyle: IProtyle,
nodeElement: Element,
accelerator?: string
id: string,
type: string,
level?: number
}) {
return {
icon: options.icon,
label: options.label,
click() {
turnIntoTransaction(options);
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
}]);
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.textContent = response.data;
});
}
});
blockRender(options.protyle, options.protyle.wysiwyg.element);
processRender(options.protyle.wysiwyg.element);
highlightRender(options.protyle.wysiwyg.element);
}
};
}
@ -254,7 +346,7 @@ export class Gutter {
label: options.label,
accelerator: options.accelerator,
click() {
turnsIntoTransaction(options);
turnsIntoOneTransaction(options);
}
};
}
@ -267,55 +359,14 @@ export class Gutter {
type: string,
level?: number | string,
isContinue?: boolean
accelerator?: string
}) {
return {
icon: options.icon,
label: options.label,
accelerator: options.accelerator,
click() {
let html = "";
const doOperations: IOperation[] = [];
const undoOperations: IOperation[] = [];
options.selectsElement.forEach((item, index) => {
if (item.getAttribute("data-type") === "NodeHeading" && item.getAttribute("fold") === "1") {
setFold(options.protyle, item);
}
item.classList.remove("protyle-wysiwyg--select");
html += item.outerHTML;
const id = item.getAttribute("data-node-id");
undoOperations.push({
action: "update",
id,
data: item.outerHTML
});
if ((options.type === "Blocks2Ps" || options.type === "Blocks2Hs") && !options.isContinue) {
// @ts-ignore
item.outerHTML = options.protyle.lute[options.type](item.outerHTML, options.level);
} else {
if (index === options.selectsElement.length - 1) {
const tempElement = document.createElement("div");
// @ts-ignore
tempElement.innerHTML = options.protyle.lute[options.type](html, options.level);
item.outerHTML = tempElement.innerHTML;
} else {
item.remove();
}
}
});
undoOperations.forEach(item => {
const nodeElement = options.protyle.wysiwyg.element.querySelector(`[data-node-id="${item.id}"]`);
doOperations.push({
action: "update",
id: item.id,
data: nodeElement.outerHTML
});
});
transaction(options.protyle, doOperations, undoOperations);
processRender(options.protyle.wysiwyg.element);
highlightRender(options.protyle.wysiwyg.element);
blockRender(options.protyle, options.protyle.wysiwyg.element);
focusBlock(options.protyle.wysiwyg.element.querySelector(`[data-node-id="${options.selectsElement[0].getAttribute("data-node-id")}"]`));
hideElements(["gutter"], options.protyle);
turnsIntoTransaction(options);
}
};
}
@ -377,6 +428,7 @@ export class Gutter {
turnIntoSubmenu.push(this.turnsInto({
icon: "iconParagraph",
label: window.siyuan.languages.paragraph,
accelerator: window.siyuan.config.keymap.editor.heading.paragraph.custom,
protyle,
selectsElement,
type: "Blocks2Ps",
@ -386,6 +438,7 @@ export class Gutter {
turnIntoSubmenu.push(this.turnsInto({
icon: "iconH1",
label: window.siyuan.languages.heading1,
accelerator: window.siyuan.config.keymap.editor.heading.heading1.custom,
protyle,
selectsElement,
level: 1,
@ -395,6 +448,7 @@ export class Gutter {
turnIntoSubmenu.push(this.turnsInto({
icon: "iconH2",
label: window.siyuan.languages.heading2,
accelerator: window.siyuan.config.keymap.editor.heading.heading2.custom,
protyle,
selectsElement,
level: 2,
@ -404,6 +458,7 @@ export class Gutter {
turnIntoSubmenu.push(this.turnsInto({
icon: "iconH3",
label: window.siyuan.languages.heading3,
accelerator: window.siyuan.config.keymap.editor.heading.heading3.custom,
protyle,
selectsElement,
level: 3,
@ -413,6 +468,7 @@ export class Gutter {
turnIntoSubmenu.push(this.turnsInto({
icon: "iconH4",
label: window.siyuan.languages.heading4,
accelerator: window.siyuan.config.keymap.editor.heading.heading4.custom,
protyle,
selectsElement,
level: 4,
@ -422,6 +478,7 @@ export class Gutter {
turnIntoSubmenu.push(this.turnsInto({
icon: "iconH5",
label: window.siyuan.languages.heading5,
accelerator: window.siyuan.config.keymap.editor.heading.heading5.custom,
protyle,
selectsElement,
level: 5,
@ -431,6 +488,7 @@ export class Gutter {
turnIntoSubmenu.push(this.turnsInto({
icon: "iconH6",
label: window.siyuan.languages.heading6,
accelerator: window.siyuan.config.keymap.editor.heading.heading6.custom,
protyle,
selectsElement,
level: 6,
@ -630,137 +688,138 @@ export class Gutter {
selectsElement: [nodeElement],
type: "Blocks2Blockquote"
}));
turnIntoSubmenu.push(this.turnInto({
turnIntoSubmenu.push(this.turnsInto({
icon: "iconH1",
label: window.siyuan.languages.heading1,
accelerator: window.siyuan.config.keymap.editor.heading.heading1.custom,
protyle,
nodeElement,
id,
selectsElement: [nodeElement],
level: 1,
type: "P2H"
type: "Blocks2Hs",
}));
turnIntoSubmenu.push(this.turnInto({
turnIntoSubmenu.push(this.turnsInto({
icon: "iconH2",
label: window.siyuan.languages.heading2,
accelerator: window.siyuan.config.keymap.editor.heading.heading2.custom,
protyle,
nodeElement,
id,
selectsElement: [nodeElement],
level: 2,
type: "P2H"
type: "Blocks2Hs",
}));
turnIntoSubmenu.push(this.turnInto({
turnIntoSubmenu.push(this.turnsInto({
icon: "iconH3",
label: window.siyuan.languages.heading3,
accelerator: window.siyuan.config.keymap.editor.heading.heading3.custom,
protyle,
nodeElement,
id,
selectsElement: [nodeElement],
level: 3,
type: "P2H"
type: "Blocks2Hs",
}));
turnIntoSubmenu.push(this.turnInto({
turnIntoSubmenu.push(this.turnsInto({
icon: "iconH4",
label: window.siyuan.languages.heading4,
accelerator: window.siyuan.config.keymap.editor.heading.heading4.custom,
protyle,
nodeElement,
id,
selectsElement: [nodeElement],
level: 4,
type: "P2H"
type: "Blocks2Hs",
}));
turnIntoSubmenu.push(this.turnInto({
turnIntoSubmenu.push(this.turnsInto({
icon: "iconH5",
label: window.siyuan.languages.heading5,
accelerator: window.siyuan.config.keymap.editor.heading.heading5.custom,
protyle,
nodeElement,
id,
selectsElement: [nodeElement],
level: 5,
type: "P2H"
type: "Blocks2Hs",
}));
turnIntoSubmenu.push(this.turnInto({
turnIntoSubmenu.push(this.turnsInto({
icon: "iconH6",
label: window.siyuan.languages.heading6,
accelerator: window.siyuan.config.keymap.editor.heading.heading6.custom,
protyle,
nodeElement,
id,
selectsElement: [nodeElement],
level: 6,
type: "P2H"
type: "Blocks2Hs",
}));
} else if (type === "NodeHeading" && !window.siyuan.config.readonly) {
turnIntoSubmenu.push(this.turnInto({
turnIntoSubmenu.push(this.turnsInto({
icon: "iconParagraph",
label: window.siyuan.languages.paragraph,
accelerator: window.siyuan.config.keymap.editor.heading.paragraph.custom,
protyle,
nodeElement,
id,
type: "H2P"
selectsElement: [nodeElement],
level: 6,
type: "Blocks2Ps",
}));
if (subType !== "h1") {
turnIntoSubmenu.push(this.turnInto({
turnIntoSubmenu.push(this.turnsInto({
icon: "iconH1",
label: window.siyuan.languages.heading1,
accelerator: window.siyuan.config.keymap.editor.heading.heading1.custom,
protyle,
nodeElement,
id,
level: 1,
type: "HLevel"
selectsElement: [nodeElement],
level: 6,
type: "Blocks2Hs",
}));
}
if (subType !== "h2") {
turnIntoSubmenu.push(this.turnInto({
turnIntoSubmenu.push(this.turnsInto({
icon: "iconH2",
label: window.siyuan.languages.heading2,
accelerator: window.siyuan.config.keymap.editor.heading.heading2.custom,
protyle,
nodeElement,
id,
selectsElement: [nodeElement],
level: 2,
type: "HLevel"
type: "Blocks2Hs",
}));
}
if (subType !== "h3") {
turnIntoSubmenu.push(this.turnInto({
turnIntoSubmenu.push(this.turnsInto({
icon: "iconH3",
label: window.siyuan.languages.heading3,
accelerator: window.siyuan.config.keymap.editor.heading.heading3.custom,
protyle,
nodeElement,
id,
selectsElement: [nodeElement],
level: 3,
type: "HLevel"
type: "Blocks2Hs",
}));
}
if (subType !== "h4") {
turnIntoSubmenu.push(this.turnInto({
turnIntoSubmenu.push(this.turnsInto({
icon: "iconH4",
label: window.siyuan.languages.heading4,
accelerator: window.siyuan.config.keymap.editor.heading.heading4.custom,
protyle,
nodeElement,
id,
selectsElement: [nodeElement],
level: 4,
type: "HLevel"
type: "Blocks2Hs",
}));
}
if (subType !== "h5") {
turnIntoSubmenu.push(this.turnInto({
turnIntoSubmenu.push(this.turnsInto({
icon: "iconH5",
label: window.siyuan.languages.heading5,
accelerator: window.siyuan.config.keymap.editor.heading.heading5.custom,
protyle,
nodeElement,
id,
selectsElement: [nodeElement],
level: 5,
type: "HLevel"
type: "Blocks2Hs",
}));
}
if (subType !== "h6") {
turnIntoSubmenu.push(this.turnInto({
turnIntoSubmenu.push(this.turnsInto({
icon: "iconH6",
label: window.siyuan.languages.heading6,
accelerator: window.siyuan.config.keymap.editor.heading.heading6.custom,
protyle,
nodeElement,
id,
selectsElement: [nodeElement],
level: 6,
type: "HLevel"
type: "Blocks2Hs",
}));
}
} else if (type === "NodeList" && !window.siyuan.config.readonly) {
turnIntoSubmenu.push(this.turnInto({
turnIntoSubmenu.push(this.turnsOneInto({
icon: "iconParagraph",
label: window.siyuan.languages.paragraph,
protyle,
@ -769,7 +828,7 @@ export class Gutter {
type: "CancelList"
}));
if (nodeElement.getAttribute("data-subtype") === "o") {
turnIntoSubmenu.push(this.turnInto({
turnIntoSubmenu.push(this.turnsOneInto({
icon: "iconList",
label: window.siyuan.languages.list,
protyle,
@ -777,7 +836,7 @@ export class Gutter {
id,
type: "OL2UL"
}));
turnIntoSubmenu.push(this.turnInto({
turnIntoSubmenu.push(this.turnsOneInto({
icon: "iconCheck",
label: window.siyuan.languages.check,
protyle,
@ -786,7 +845,7 @@ export class Gutter {
type: "UL2TL"
}));
} else if (nodeElement.getAttribute("data-subtype") === "t") {
turnIntoSubmenu.push(this.turnInto({
turnIntoSubmenu.push(this.turnsOneInto({
icon: "iconList",
label: window.siyuan.languages.list,
protyle,
@ -794,7 +853,7 @@ export class Gutter {
id,
type: "TL2UL"
}));
turnIntoSubmenu.push(this.turnInto({
turnIntoSubmenu.push(this.turnsOneInto({
icon: "iconOrderedList",
label: window.siyuan.languages["ordered-list"],
protyle,
@ -803,7 +862,7 @@ export class Gutter {
type: "TL2OL"
}));
} else {
turnIntoSubmenu.push(this.turnInto({
turnIntoSubmenu.push(this.turnsOneInto({
icon: "iconOrderedList",
label: window.siyuan.languages["ordered-list"],
protyle,
@ -811,7 +870,7 @@ export class Gutter {
id,
type: "UL2OL"
}));
turnIntoSubmenu.push(this.turnInto({
turnIntoSubmenu.push(this.turnsOneInto({
icon: "iconCheck",
label: window.siyuan.languages.check,
protyle,
@ -821,7 +880,7 @@ export class Gutter {
}));
}
} else if (type === "NodeBlockquote" && !window.siyuan.config.readonly) {
turnIntoSubmenu.push(this.turnInto({
turnIntoSubmenu.push(this.turnsOneInto({
icon: "iconParagraph",
label: window.siyuan.languages.paragraph,
protyle,

View file

@ -32,9 +32,7 @@ import {matchHotKey} from "../util/hotKey";
import {enter} from "./enter";
import {fixTable} from "../util/table";
import {
phTransaction,
transaction,
turnsIntoTransaction,
transaction, turnsIntoOneTransaction, turnsIntoTransaction,
updateBatchTransaction,
updateTransaction
} from "./transaction";
@ -244,6 +242,7 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => {
!isCtrl(event) && event.key !== "Escape" && !event.shiftKey && !event.altKey && !/^F\d{1,2}$/.test(event.key) &&
event.key !== "Enter" && event.key !== "Tab" && event.key !== "Backspace" && event.key !== "Delete") {
event.stopPropagation();
hideElements(["select"], protyle);
return false;
}
if (!isCtrl(event) && !event.shiftKey && event.key !== "Backspace" && event.key !== "PageUp" && event.key !== "PageDown" && event.key.indexOf("Arrow") === -1) {
@ -1064,38 +1063,78 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => {
}
// h1 - h6 hotkey
if (matchHotKey(window.siyuan.config.keymap.editor.heading.paragraph.custom, event)) {
turnsIntoTransaction({
protyle,
nodeElement,
type: "Blocks2Ps",
})
event.preventDefault();
event.stopPropagation();
return true;
}
if (matchHotKey(window.siyuan.config.keymap.editor.heading.heading1.custom, event)) {
phTransaction(protyle, range, nodeElement, 1);
turnsIntoTransaction({
protyle,
nodeElement,
type: "Blocks2Hs",
level: 1
})
event.preventDefault();
event.stopPropagation();
return true;
}
if (matchHotKey(window.siyuan.config.keymap.editor.heading.heading2.custom, event)) {
phTransaction(protyle, range, nodeElement, 2);
turnsIntoTransaction({
protyle,
nodeElement,
type: "Blocks2Hs",
level: 2
})
event.preventDefault();
event.stopPropagation();
return true;
}
if (matchHotKey(window.siyuan.config.keymap.editor.heading.heading3.custom, event)) {
phTransaction(protyle, range, nodeElement, 3);
turnsIntoTransaction({
protyle,
nodeElement,
type: "Blocks2Hs",
level: 3
})
event.preventDefault();
event.stopPropagation();
return true;
}
if (matchHotKey(window.siyuan.config.keymap.editor.heading.heading4.custom, event)) {
phTransaction(protyle, range, nodeElement, 4);
turnsIntoTransaction({
protyle,
nodeElement,
type: "Blocks2Hs",
level: 4
})
event.preventDefault();
event.stopPropagation();
return true;
}
if (matchHotKey(window.siyuan.config.keymap.editor.heading.heading5.custom, event)) {
phTransaction(protyle, range, nodeElement, 5);
turnsIntoTransaction({
protyle,
nodeElement,
type: "Blocks2Hs",
level: 5
})
event.preventDefault();
event.stopPropagation();
return true;
}
if (matchHotKey(window.siyuan.config.keymap.editor.heading.heading6.custom, event)) {
phTransaction(protyle, range, nodeElement, 6);
turnsIntoTransaction({
protyle,
nodeElement,
type: "Blocks2Hs",
level: 6
})
event.preventDefault();
event.stopPropagation();
return true;
@ -1474,7 +1513,7 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => {
if (selectsElement.length < 2) {
return;
}
turnsIntoTransaction({
turnsIntoOneTransaction({
protyle, selectsElement,
type: "BlocksMergeSuperBlock",
level: "row"
@ -1489,7 +1528,7 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => {
if (selectsElement.length < 2) {
return;
}
turnsIntoTransaction({
turnsIntoOneTransaction({
protyle, selectsElement,
type: "BlocksMergeSuperBlock",
level: "col"

View file

@ -469,7 +469,7 @@ export const onTransaction = (protyle: IProtyle, operation: IOperation, focus: b
}
};
export const turnsIntoTransaction = (options: { protyle: IProtyle, selectsElement: Element[], type: string, level?: string }) => {
export const turnsIntoOneTransaction = (options: { protyle: IProtyle, selectsElement: Element[], type: string, level?: string }) => {
let parentElement: Element;
const id = Lute.NewNodeID();
if (options.type === "BlocksMergeSuperBlock") {
@ -559,110 +559,97 @@ export const turnsIntoTransaction = (options: { protyle: IProtyle, selectsElemen
hideElements(["gutter"], options.protyle);
};
export const turnIntoTransaction = 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 === "HLevel" && options.nodeElement.getAttribute("data-type") === "NodeHeading" &&
options.nodeElement.getAttribute("fold") === "1") {
setFold(options.protyle, options.nodeElement);
}
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
}]);
item.insertAdjacentHTML("afterend", response.data[0].doOperations[0].retData);
export const turnsIntoTransaction = (options: {
protyle: IProtyle,
selectsElement?: Element[],
nodeElement?: Element,
type: string,
level?: number | string,
isContinue?: boolean
}) => {
let selectsElement: Element[] = options.selectsElement;
// 通过快捷键触发
if (options.nodeElement) {
selectsElement = Array.from(options.protyle.wysiwyg.element.querySelectorAll(".protyle-wysiwyg--select"));
if (selectsElement.length === 0) {
selectsElement = [options.nodeElement];
}
}
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;
let isContinue = false;
let hasEmbedBlock = false;
let isList = false;
selectsElement.find((item, index) => {
if (item.classList.contains("li")) {
isList = true;
return true;
}
if (item.classList.contains("bq") || item.classList.contains("sb") || item.classList.contains("p")) {
hasEmbedBlock = 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 || (hasEmbedBlock && options.type === "Blocks2Ps")) {
return;
}
if (selectsElement.length === 1 && options.type === "Blocks2Hs" &&
selectsElement[0].getAttribute("data-type") === "NodeHeading" &&
options.level === parseInt(selectsElement[0].getAttribute("data-subtype").substr(1))) {
// 快捷键同级转换,消除标题
options.type = "Blocks2Ps";
}
options.isContinue = isContinue;
}
let html = "";
const doOperations: IOperation[] = [];
const undoOperations: IOperation[] = [];
selectsElement.forEach((item, index) => {
if ((options.type === "Blocks2Ps" || options.type === "Blocks2Hs") &&
item.getAttribute("data-type") === "NodeHeading" && item.getAttribute("fold") === "1") {
setFold(options.protyle, item);
}
item.classList.remove("protyle-wysiwyg--select");
html += item.outerHTML;
const id = item.getAttribute("data-node-id");
undoOperations.push({
action: "insert",
data: oldHTML,
id: options.id,
previousID: previousId,
parentID: parentId
action: "update",
id,
data: item.outerHTML
});
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.textContent = response.data;
});
if ((options.type === "Blocks2Ps" || options.type === "Blocks2Hs") && !options.isContinue) {
// @ts-ignore
item.outerHTML = options.protyle.lute[options.type](item.outerHTML, options.level);
} else {
if (index === selectsElement.length - 1) {
const tempElement = document.createElement("div");
// @ts-ignore
tempElement.innerHTML = options.protyle.lute[options.type](html, options.level);
item.outerHTML = tempElement.innerHTML;
} else {
item.remove();
}
}
});
blockRender(options.protyle, options.protyle.wysiwyg.element);
undoOperations.forEach(item => {
const nodeElement = options.protyle.wysiwyg.element.querySelector(`[data-node-id="${item.id}"]`);
doOperations.push({
action: "update",
id: item.id,
data: nodeElement.outerHTML
});
});
transaction(options.protyle, doOperations, undoOperations);
processRender(options.protyle.wysiwyg.element);
highlightRender(options.protyle.wysiwyg.element);
};
export const phTransaction = (protyle: IProtyle, range: Range, nodeElement: HTMLElement, level: number) => {
const id = nodeElement.getAttribute("data-node-id");
const nodeType = nodeElement.getAttribute("data-type");
range.insertNode(document.createElement("wbr"));
if (nodeType === "NodeHeading") {
const subType = parseInt(nodeElement.getAttribute("data-subtype").substr(1));
if (subType === level) {
turnIntoTransaction({protyle, nodeElement, id, type: "H2P"});
} else {
turnIntoTransaction({protyle, nodeElement, id, type: "HLevel", level});
}
} else if (nodeType === "NodeParagraph") {
turnIntoTransaction({protyle, nodeElement, id, type: "P2H", level});
}
blockRender(options.protyle, options.protyle.wysiwyg.element);
focusBlock(options.protyle.wysiwyg.element.querySelector(`[data-node-id="${selectsElement[0].getAttribute("data-node-id")}"]`));
hideElements(["gutter"], options.protyle);
};
const updateRef = (protyle: IProtyle, id: string, index = 0) => {