diff --git a/app/src/constants.ts b/app/src/constants.ts
index 60c3a7f06..421bcc222 100644
--- a/app/src/constants.ts
+++ b/app/src/constants.ts
@@ -416,6 +416,7 @@ export abstract class Constants {
// "⌘", "⇧", "⌥", "⌃"
// "⌘A", "⌘X", "⌘C", "⌘V", "⌘-", "⌘=", "⌘0", "⇧⌘V", "⌘/", "⇧↑", "⇧↓", "⇧→", "⇧←", "⇧⇥", "⌃D", "⇧⌘→", "⇧⌘←",
// "⌘Home", "⌘End", "⇧↩", "↩", "PageUp", "PageDown", "⌫", "⌦", "Escape" 不可自定义
+ // "⌥↩" 写死,但可自定义
public static readonly SIYUAN_KEYMAP: Config.IKeymap = {
general: {
mainMenu: {default: "⌥\\", custom: "⌥\\"},
diff --git a/app/src/protyle/wysiwyg/callout.ts b/app/src/protyle/wysiwyg/callout.ts
index c290821aa..c8bffc020 100644
--- a/app/src/protyle/wysiwyg/callout.ts
+++ b/app/src/protyle/wysiwyg/callout.ts
@@ -1,5 +1,4 @@
-import {hasClosestBlock} from "../util/hasClosest";
-import {updateTransaction} from "./transaction";
+import {transaction} from "./transaction";
import {focusBlock} from "../util/selection";
import {Dialog} from "../../dialog";
import {Menu} from "../../plugin/Menu";
@@ -7,12 +6,11 @@ import {isMobile} from "../../util/functions";
import {Constants} from "../../constants";
import {openEmojiPanel, unicode2Emoji} from "../../emoji";
-export const updateCalloutType = (titleElement: HTMLElement, protyle: IProtyle) => {
- const blockElement = hasClosestBlock(titleElement);
- if (!blockElement) {
+export const updateCalloutType = (blockElements: HTMLElement[], protyle: IProtyle) => {
+ if (blockElements.length === 0) {
return;
}
- const blockCalloutElement = blockElement.querySelector(".callout-icon");
+ const blockCalloutElement = blockElements[0].querySelector(".callout-icon");
const dialog = new Dialog({
title: window.siyuan.languages.callout,
content: `
@@ -32,7 +30,7 @@ export const updateCalloutType = (titleElement: HTMLElement, protyle: IProtyle)
-
+
@@ -56,19 +54,34 @@ export const updateCalloutType = (titleElement: HTMLElement, protyle: IProtyle)
dialog.destroy();
});
btnElements[1].addEventListener("click", () => {
- const oldHTML = blockElement.outerHTML;
- blockElement.setAttribute("data-subtype", textElements[0].value.trim());
- let title = textElements[1].value.trim();
- if (title) {
- const template = document.createElement("template");
- template.innerHTML = protyle.lute.Md2BlockDOM(textElements[1].value.trim());
- title = template.content.firstElementChild.firstElementChild.innerHTML;
- }
- titleElement.innerHTML = title ||
- (textElements[0].value.trim().substring(0, 1).toUpperCase() + textElements[0].value.trim().substring(1).toLowerCase());
- blockCalloutElement.innerHTML = dialogCalloutIconElement.innerHTML;
- updateTransaction(protyle, blockElement.getAttribute("data-node-id"), blockElement.outerHTML, oldHTML);
- focusBlock(blockElement);
+ const doOperations: IOperation[] = [];
+ const undoOperations: IOperation[] = [];
+ blockElements.filter(item => {
+ const id = item.getAttribute("data-node-id");
+ const oldHTML = item.outerHTML;
+ item.setAttribute("data-subtype", textElements[0].value.trim());
+ let title = textElements[1].value.trim();
+ if (title) {
+ const template = document.createElement("template");
+ template.innerHTML = protyle.lute.Md2BlockDOM(textElements[1].value.trim());
+ title = template.content.firstElementChild.firstElementChild.innerHTML;
+ }
+ item.querySelector(".callout-title").innerHTML = title ||
+ (textElements[0].value.trim().substring(0, 1).toUpperCase() + textElements[0].value.trim().substring(1).toLowerCase());
+ item.querySelector(".callout-icon").innerHTML = dialogCalloutIconElement.innerHTML;
+ doOperations.push({
+ id,
+ data: item.outerHTML,
+ action: "update"
+ });
+ undoOperations.push({
+ id,
+ data: oldHTML,
+ action: "update"
+ });
+ });
+ transaction(protyle, doOperations, undoOperations);
+ focusBlock(blockElements[0]);
dialog.destroy();
});
const textElements: NodeListOf = dialog.element.querySelectorAll(".b3-text-field");
@@ -88,7 +101,7 @@ export const updateCalloutType = (titleElement: HTMLElement, protyle: IProtyle)
});
textElements[0].focus();
textElements[0].select();
- textElements[1].value = protyle.lute.BlockDOM2StdMd(titleElement.innerHTML);
+ textElements[1].value = protyle.lute.BlockDOM2StdMd(blockElements[0].querySelector(".callout-title").innerHTML);
const dialogCalloutIconElement = dialog.element.querySelector(".callout-icon");
dialogCalloutIconElement.addEventListener("click", () => {
const emojiRect = dialogCalloutIconElement.getBoundingClientRect();
diff --git a/app/src/protyle/wysiwyg/index.ts b/app/src/protyle/wysiwyg/index.ts
index 0c0099a76..6d6d72337 100644
--- a/app/src/protyle/wysiwyg/index.ts
+++ b/app/src/protyle/wysiwyg/index.ts
@@ -3048,7 +3048,7 @@ export class WYSIWYG {
const calloutTitleElement = hasTopClosestByClassName(event.target, "callout-title");
if (!protyle.disabled && !event.shiftKey && !ctrlIsPressed && calloutTitleElement) {
- updateCalloutType(calloutTitleElement, protyle);
+ updateCalloutType([hasClosestBlock(calloutTitleElement) as HTMLElement], protyle);
event.preventDefault();
event.stopPropagation();
return;
diff --git a/app/src/protyle/wysiwyg/keydown.ts b/app/src/protyle/wysiwyg/keydown.ts
index e7380cb7e..73a6967b6 100644
--- a/app/src/protyle/wysiwyg/keydown.ts
+++ b/app/src/protyle/wysiwyg/keydown.ts
@@ -73,6 +73,7 @@ import {AIActions} from "../../ai/actions";
import {openLink} from "../../editor/openLink";
import {onlyProtyleCommand} from "../../boot/globalEvent/command/protyle";
import {AIChat} from "../../ai/chat";
+import {updateCalloutType} from "./callout";
export const getContentByInlineHTML = (range: Range, cb: (content: string) => void) => {
let html = "";
@@ -1083,17 +1084,24 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => {
selectElements.push(nodeElement);
}
if (selectElements.length > 0 && !isIncludesHotKey("⌥↩")) {
- const otherElement = selectElements.find(item => {
- return !item.classList.contains("code-block");
- });
- if (!otherElement) {
- const languageElements: HTMLElement[] = [];
- selectElements.forEach(item => {
+ const languageElements: HTMLElement[] = [];
+ const calloutElements: HTMLElement[] = [];
+ selectElements.forEach(item => {
+ if (item.classList.contains("code-block")) {
languageElements.push(item.querySelector(".protyle-action__language"));
- });
+ } else {
+ const calloutElement = hasClosestByClassName(item, "callout");
+ if (calloutElement) {
+ calloutElements.push(calloutElement);
+ }
+ }
+ });
+ if (languageElements.length > 0) {
protyle.toolbar.showCodeLanguage(protyle, languageElements);
- } else {
- addSubList(protyle, nodeElement, range);
+ } else if (addSubList(protyle, nodeElement, range)) {
+ // 函数内部已处理
+ } else if (calloutElements.length > 0) {
+ updateCalloutType(calloutElements, protyle);
}
event.stopPropagation();
event.preventDefault();
diff --git a/app/src/protyle/wysiwyg/list.ts b/app/src/protyle/wysiwyg/list.ts
index 7d42a82a5..78732e588 100644
--- a/app/src/protyle/wysiwyg/list.ts
+++ b/app/src/protyle/wysiwyg/list.ts
@@ -52,11 +52,11 @@ export const genListItemElement = (listItemElement: Element, offset = 0, wbr = f
export const addSubList = (protyle: IProtyle, nodeElement: Element, range: Range) => {
const parentItemElement = hasClosestByClassName(nodeElement, "li");
if (!parentItemElement) {
- return;
+ return false;
}
const lastSubItem = parentItemElement.querySelector(".list")?.lastElementChild.previousElementSibling;
if (!lastSubItem) {
- return;
+ return false;
}
const newListElement = genListItemElement(lastSubItem, 0, true);
const id = newListElement.getAttribute("data-node-id");
@@ -78,6 +78,7 @@ export const addSubList = (protyle: IProtyle, nodeElement: Element, range: Range
id,
}]);
focusByWbr(newListElement, range);
+ return true;
};
export const listIndent = (protyle: IProtyle, liItemElements: Element[], range: Range) => {