mirror of
https://github.com/siyuan-note/siyuan.git
synced 2026-02-11 01:34:20 +01:00
197 lines
8.8 KiB
TypeScript
197 lines
8.8 KiB
TypeScript
import {Constants} from "../../constants";
|
|
import {fetchPost} from "../../util/fetch";
|
|
/// #if !BROWSER
|
|
import {sendGlobalShortcut} from "./keydown";
|
|
import {ipcRenderer} from "electron";
|
|
/// #endif
|
|
import {App} from "../../index";
|
|
import {isMac, isNotCtrl, isOnlyMeta} from "../../protyle/util/compatibility";
|
|
import {showPopover} from "../../block/popover";
|
|
|
|
const matchKeymap = (keymap: Config.IKeys, key1: "general" | "editor", key2?: "general" | "insert" | "heading" | "list" | "table") => {
|
|
if (key1 === "general") {
|
|
if (!window.siyuan.config.keymap[key1]) {
|
|
/// #if !BROWSER
|
|
ipcRenderer.send(Constants.SIYUAN_CMD, {
|
|
cmd: "writeLog",
|
|
msg: "window.siyuan.config.keymap.general is not found"
|
|
});
|
|
/// #endif
|
|
window.siyuan.config.keymap[key1] = keymap as Config.IKeymapGeneral;
|
|
return false;
|
|
}
|
|
} else {
|
|
if (!window.siyuan.config.keymap[key1]) {
|
|
/// #if !BROWSER
|
|
ipcRenderer.send(Constants.SIYUAN_CMD, {
|
|
cmd: "writeLog",
|
|
msg: "window.siyuan.config.keymap.editor is not found"
|
|
});
|
|
/// #endif
|
|
window.siyuan.config.keymap[key1] = JSON.parse(JSON.stringify(Constants.SIYUAN_KEYMAP.editor));
|
|
return false;
|
|
}
|
|
if (!window.siyuan.config.keymap[key1][key2]) {
|
|
/// #if !BROWSER
|
|
ipcRenderer.send(Constants.SIYUAN_CMD, {
|
|
cmd: "writeLog",
|
|
msg: `window.siyuan.config.keymap.editor.${key2} is not found`
|
|
});
|
|
/// #endif
|
|
(window.siyuan.config.keymap[key1][key2] as Config.IKeymapEditor[typeof key2]) = keymap as Config.IKeymapEditor[typeof key2];
|
|
return false;
|
|
}
|
|
}
|
|
let match = true;
|
|
Object.keys(keymap).forEach(key => {
|
|
if (key1 === "general") {
|
|
if (!window.siyuan.config.keymap[key1][key] || window.siyuan.config.keymap[key1][key].default !== keymap[key].default) {
|
|
/// #if !BROWSER
|
|
ipcRenderer.send(Constants.SIYUAN_CMD, {
|
|
cmd: "writeLog",
|
|
msg: `window.siyuan.config.keymap.${key1}.${key} is not found or match: ${window.siyuan.config.keymap[key1][key]?.default}`
|
|
});
|
|
/// #endif
|
|
match = false;
|
|
window.siyuan.config.keymap[key1][key] = keymap[key];
|
|
}
|
|
} else {
|
|
if (!window.siyuan.config.keymap[key1][key2][key] || window.siyuan.config.keymap[key1][key2][key].default !== keymap[key].default) {
|
|
/// #if !BROWSER
|
|
ipcRenderer.send(Constants.SIYUAN_CMD, {
|
|
cmd: "writeLog",
|
|
msg: `window.siyuan.config.keymap.${key1}.${key2}.${key} is not found or match: ${window.siyuan.config.keymap[key1][key2][key]?.default}`
|
|
});
|
|
/// #endif
|
|
match = false;
|
|
window.siyuan.config.keymap[key1][key2][key] = keymap[key];
|
|
}
|
|
}
|
|
});
|
|
return match;
|
|
};
|
|
|
|
const hasKeymap = (keymap: Record<string, IKeymapItem>, key1: "general" | "editor", key2?: "general" | "insert" | "heading" | "list" | "table") => {
|
|
let match = true;
|
|
if (key1 === "editor") {
|
|
if (Object.keys(window.siyuan.config.keymap[key1][key2]).length !== Object.keys(Constants.SIYUAN_KEYMAP[key1][key2]).length) {
|
|
Object.keys(window.siyuan.config.keymap[key1][key2]).forEach(item => {
|
|
if (!Constants.SIYUAN_KEYMAP[key1][key2][item]) {
|
|
match = false;
|
|
delete window.siyuan.config.keymap[key1][key2][item];
|
|
}
|
|
});
|
|
}
|
|
} else {
|
|
if (Object.keys(window.siyuan.config.keymap[key1]).length !== Object.keys(Constants.SIYUAN_KEYMAP[key1]).length) {
|
|
Object.keys(window.siyuan.config.keymap[key1]).forEach(item => {
|
|
if (!Constants.SIYUAN_KEYMAP[key1][item]) {
|
|
match = false;
|
|
delete window.siyuan.config.keymap[key1][item];
|
|
}
|
|
});
|
|
}
|
|
}
|
|
return match;
|
|
};
|
|
|
|
export const correctHotkey = (app: App) => {
|
|
const matchKeymap1 = matchKeymap(Constants.SIYUAN_KEYMAP.general, "general");
|
|
const matchKeymap2 = matchKeymap(Constants.SIYUAN_KEYMAP.editor.general, "editor", "general");
|
|
const matchKeymap3 = matchKeymap(Constants.SIYUAN_KEYMAP.editor.insert, "editor", "insert");
|
|
const matchKeymap4 = matchKeymap(Constants.SIYUAN_KEYMAP.editor.heading, "editor", "heading");
|
|
const matchKeymap5 = matchKeymap(Constants.SIYUAN_KEYMAP.editor.list, "editor", "list");
|
|
const matchKeymap6 = matchKeymap(Constants.SIYUAN_KEYMAP.editor.table, "editor", "table");
|
|
|
|
const hasKeymap1 = hasKeymap(Constants.SIYUAN_KEYMAP.general, "general");
|
|
const hasKeymap2 = hasKeymap(Constants.SIYUAN_KEYMAP.editor.general, "editor", "general");
|
|
const hasKeymap3 = hasKeymap(Constants.SIYUAN_KEYMAP.editor.insert, "editor", "insert");
|
|
const hasKeymap4 = hasKeymap(Constants.SIYUAN_KEYMAP.editor.heading, "editor", "heading");
|
|
const hasKeymap5 = hasKeymap(Constants.SIYUAN_KEYMAP.editor.list, "editor", "list");
|
|
const hasKeymap6 = hasKeymap(Constants.SIYUAN_KEYMAP.editor.table, "editor", "table");
|
|
if (!window.siyuan.config.readonly &&
|
|
(!matchKeymap1 || !matchKeymap2 || !matchKeymap3 || !matchKeymap4 || !matchKeymap5 || !matchKeymap6 ||
|
|
!hasKeymap1 || !hasKeymap2 || !hasKeymap3 || !hasKeymap4 || !hasKeymap5 || !hasKeymap6)) {
|
|
/// #if !BROWSER
|
|
ipcRenderer.send(Constants.SIYUAN_CMD, {
|
|
cmd: "writeLog",
|
|
msg: "update keymap"
|
|
});
|
|
/// #endif
|
|
fetchPost("/api/setting/setKeymap", {
|
|
data: window.siyuan.config.keymap
|
|
}, () => {
|
|
/// #if !BROWSER
|
|
sendGlobalShortcut(app);
|
|
/// #endif
|
|
});
|
|
}
|
|
};
|
|
|
|
export const filterHotkey = (event: KeyboardEvent, app: App) => {
|
|
// https://github.com/siyuan-note/siyuan/issues/9848 忘记为什么要阻止了 .av__mask 的情况,测了下没问题就先移除
|
|
if (document.getElementById("progress") || document.getElementById("errorLog") || event.isComposing) {
|
|
return true;
|
|
}
|
|
const target = event.target as HTMLElement;
|
|
// 点击最近的文档列表会 dispatch keydown 的 Enter https://github.com/siyuan-note/siyuan/issues/12967
|
|
if (event.isTrusted && isNotCtrl(event) && !event.shiftKey && !event.altKey &&
|
|
!["INPUT", "TEXTAREA"].includes(target.tagName) &&
|
|
["0", "1", "2", "3", "4", "j", "k", "l", ";", "s", " ", "p", "enter", "a", "s", "d", "f", "q", "x"].includes(event.key.toLowerCase())) {
|
|
let cardElement: Element;
|
|
window.siyuan.dialogs.find(item => {
|
|
if (item.element.getAttribute("data-key") === Constants.DIALOG_OPENCARD) {
|
|
cardElement = item.element;
|
|
return true;
|
|
}
|
|
});
|
|
if (!cardElement) {
|
|
cardElement = document.querySelector(`.layout__wnd--active div[data-key="${Constants.DIALOG_OPENCARD}"]:not(.fn__none)`);
|
|
}
|
|
if (cardElement) {
|
|
event.preventDefault();
|
|
cardElement.firstElementChild.dispatchEvent(new CustomEvent("click", {detail: event.key.toLowerCase()}));
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// 仅处理以下快捷键操作
|
|
if (isNotCtrl(event) && event.key !== "Escape" && !event.shiftKey && !event.altKey &&
|
|
Constants.KEYCODELIST[event.keyCode] !== "PageUp" &&
|
|
Constants.KEYCODELIST[event.keyCode] !== "PageDown" &&
|
|
event.key !== "Home" && event.key !== "End" &&
|
|
!/^F\d{1,2}$/.test(event.key) && event.key.indexOf("Arrow") === -1 && event.key !== "Enter" && event.key !== "Backspace" && event.key !== "Delete") {
|
|
return true;
|
|
}
|
|
|
|
if (!event.altKey && !event.shiftKey && isOnlyMeta(event)) {
|
|
if ((isMac() ? event.key === "Meta" : event.key === "Control") || isOnlyMeta(event)) {
|
|
window.siyuan.ctrlIsPressed = true;
|
|
if ((event.key === "Meta" || event.key === "Control") &&
|
|
window.siyuan.config.editor.floatWindowMode === 1 && !event.repeat) {
|
|
showPopover(app);
|
|
}
|
|
} else {
|
|
window.siyuan.ctrlIsPressed = false;
|
|
}
|
|
}
|
|
|
|
if (!event.altKey && event.shiftKey && isNotCtrl(event)) {
|
|
if (event.key === "Shift") {
|
|
window.siyuan.shiftIsPressed = true;
|
|
if (!event.repeat) {
|
|
showPopover(app, true);
|
|
}
|
|
} else {
|
|
window.siyuan.shiftIsPressed = false;
|
|
}
|
|
}
|
|
|
|
if (event.altKey && !event.shiftKey && isNotCtrl(event)) {
|
|
if (event.key === "Alt") {
|
|
window.siyuan.altIsPressed = true;
|
|
} else {
|
|
window.siyuan.altIsPressed = false;
|
|
}
|
|
}
|
|
};
|