2023-11-12 12:28:20 +08:00
|
|
|
|
import {isMac, updateHotkeyTip} from "../protyle/util/compatibility";
|
2022-05-26 15:18:53 +08:00
|
|
|
|
import {Constants} from "../constants";
|
2023-10-22 17:23:22 +08:00
|
|
|
|
import {hideMessage, showMessage} from "../dialog/message";
|
2022-05-26 15:18:53 +08:00
|
|
|
|
import {fetchPost} from "../util/fetch";
|
2022-06-11 21:46:06 +08:00
|
|
|
|
import {exportLayout} from "../layout/util";
|
2022-11-05 16:36:12 +08:00
|
|
|
|
import {confirmDialog} from "../dialog/confirmDialog";
|
2023-05-30 00:27:47 +08:00
|
|
|
|
import {App} from "../index";
|
2023-10-22 17:23:22 +08:00
|
|
|
|
/// #if !BROWSER
|
|
|
|
|
|
import {ipcRenderer} from "electron";
|
|
|
|
|
|
/// #endif
|
2023-08-30 17:15:17 +08:00
|
|
|
|
import {sendGlobalShortcut} from "../boot/globalEvent/keydown";
|
2022-05-26 15:18:53 +08:00
|
|
|
|
|
|
|
|
|
|
export const keymap = {
|
|
|
|
|
|
element: undefined as Element,
|
2024-03-25 09:33:22 +08:00
|
|
|
|
_genItem(keymap: Record<string, Config.IKey>, keys: string) {
|
2022-05-26 15:18:53 +08:00
|
|
|
|
let html = "";
|
|
|
|
|
|
Object.keys(keymap).forEach(key => {
|
|
|
|
|
|
if (window.siyuan.languages[key]) {
|
2023-03-16 11:19:46 +08:00
|
|
|
|
const keyValue = updateHotkeyTip(keymap[key].custom);
|
2024-05-24 08:55:24 +08:00
|
|
|
|
let keymapName = window.siyuan.languages[key];
|
|
|
|
|
|
if ("editor" + Constants.ZWSP + "general" === keys && key === "duplicate") {
|
|
|
|
|
|
keymapName = `${window.siyuan.languages.duplicate} / ${window.siyuan.languages.duplicateMirror}`;
|
|
|
|
|
|
}
|
2023-03-15 23:34:47 +08:00
|
|
|
|
html += `<label class="b3-list-item b3-list-item--narrow b3-list-item--hide-action">
|
2024-05-24 08:55:24 +08:00
|
|
|
|
<span class="b3-list-item__text">${keymapName}</span>
|
2022-05-26 15:18:53 +08:00
|
|
|
|
<span data-type="reset" class="b3-list-item__action b3-tooltips b3-tooltips__w" aria-label="${window.siyuan.languages.reset}">
|
|
|
|
|
|
<svg><use xlink:href="#iconUndo"></use></svg>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
<span data-type="clear" class="b3-list-item__action b3-tooltips b3-tooltips__w" aria-label="${window.siyuan.languages.remove}">
|
|
|
|
|
|
<svg><use xlink:href="#iconTrashcan"></use></svg>
|
|
|
|
|
|
</span>
|
2023-03-15 23:34:47 +08:00
|
|
|
|
<span data-type="update" class="config-keymap__key">${keyValue}</span>
|
2023-05-30 00:27:47 +08:00
|
|
|
|
<input data-key="${keys + Constants.ZWSP + key}" data-value="${keymap[key].custom}" data-default="${keymap[key].default}" class="b3-text-field fn__none" value="${keyValue}" spellcheck="false">
|
2022-10-18 00:03:34 +08:00
|
|
|
|
</label>`;
|
2022-05-26 15:18:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
return html;
|
|
|
|
|
|
},
|
2023-05-30 00:27:47 +08:00
|
|
|
|
genHTML(app: App) {
|
2023-05-30 00:35:13 +08:00
|
|
|
|
let pluginHtml = "";
|
2023-05-30 00:27:47 +08:00
|
|
|
|
app.plugins.forEach(item => {
|
2023-05-30 00:35:13 +08:00
|
|
|
|
let commandHTML = "";
|
2023-05-30 00:27:47 +08:00
|
|
|
|
item.commands.forEach(command => {
|
|
|
|
|
|
const keyValue = updateHotkeyTip(command.customHotkey);
|
|
|
|
|
|
commandHTML += `<label class="b3-list-item b3-list-item--narrow b3-list-item--hide-action">
|
2023-10-23 17:52:00 +08:00
|
|
|
|
<span class="b3-list-item__text">${command.langText || (item.i18n ? item.i18n[command.langKey] : "") || command.langKey}</span>
|
2023-05-30 00:27:47 +08:00
|
|
|
|
<span data-type="reset" class="b3-list-item__action b3-tooltips b3-tooltips__w" aria-label="${window.siyuan.languages.reset}">
|
|
|
|
|
|
<svg><use xlink:href="#iconUndo"></use></svg>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
<span data-type="clear" class="b3-list-item__action b3-tooltips b3-tooltips__w" aria-label="${window.siyuan.languages.remove}">
|
|
|
|
|
|
<svg><use xlink:href="#iconTrashcan"></use></svg>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
<span data-type="update" class="config-keymap__key">${keyValue}</span>
|
|
|
|
|
|
<input data-key="plugin${Constants.ZWSP}${item.name}${Constants.ZWSP}${command.langKey}" data-value="${command.customHotkey}" data-default="${command.hotkey}" class="b3-text-field fn__none" value="${keyValue}" spellcheck="false">
|
2024-03-19 23:14:18 +08:00
|
|
|
|
</label>`;
|
|
|
|
|
|
});
|
|
|
|
|
|
Object.keys(item.docks).forEach(key => {
|
|
|
|
|
|
const dockConfig = item.docks[key].config;
|
2024-03-22 09:35:26 +08:00
|
|
|
|
if (!dockConfig.hotkey) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2024-03-26 21:04:06 +08:00
|
|
|
|
const dockKeymap = window.siyuan.config.keymap.plugin[item.name][key];
|
2024-03-19 23:14:18 +08:00
|
|
|
|
const keyValue = updateHotkeyTip(dockKeymap.custom);
|
|
|
|
|
|
commandHTML += `<label class="b3-list-item b3-list-item--narrow b3-list-item--hide-action">
|
|
|
|
|
|
<span class="b3-list-item__text">${dockConfig.title}</span>
|
|
|
|
|
|
<span data-type="reset" class="b3-list-item__action b3-tooltips b3-tooltips__w" aria-label="${window.siyuan.languages.reset}">
|
|
|
|
|
|
<svg><use xlink:href="#iconUndo"></use></svg>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
<span data-type="clear" class="b3-list-item__action b3-tooltips b3-tooltips__w" aria-label="${window.siyuan.languages.remove}">
|
|
|
|
|
|
<svg><use xlink:href="#iconTrashcan"></use></svg>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
<span data-type="update" class="config-keymap__key">${keyValue}</span>
|
|
|
|
|
|
<input data-key="plugin${Constants.ZWSP}${item.name}${Constants.ZWSP}${key}" data-value="${dockKeymap.custom}" data-default="${dockKeymap.default}" class="b3-text-field fn__none" value="${keyValue}" spellcheck="false">
|
2023-05-30 00:27:47 +08:00
|
|
|
|
</label>`;
|
|
|
|
|
|
});
|
|
|
|
|
|
if (commandHTML) {
|
2023-08-10 11:40:44 +08:00
|
|
|
|
pluginHtml += `<div class="b3-list-item b3-list-item--narrow toggle">
|
|
|
|
|
|
<span class="b3-list-item__toggle b3-list-item__toggle--hl">
|
|
|
|
|
|
<svg class="b3-list-item__arrow"><use xlink:href="#iconRight"></use></svg>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
<span class="b3-list-item__text ft__on-surface">${item.displayName}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="fn__none b3-list__panel">
|
|
|
|
|
|
${commandHTML}
|
|
|
|
|
|
</div>`;
|
2023-05-30 00:27:47 +08:00
|
|
|
|
}
|
2023-05-30 00:35:13 +08:00
|
|
|
|
});
|
2023-05-30 00:27:47 +08:00
|
|
|
|
if (pluginHtml) {
|
|
|
|
|
|
pluginHtml = `<div class="b3-list b3-list--border b3-list--background">
|
|
|
|
|
|
<div class="b3-list-item b3-list-item--narrow toggle">
|
|
|
|
|
|
<span class="b3-list-item__toggle b3-list-item__toggle--hl">
|
|
|
|
|
|
<svg class="b3-list-item__arrow b3-list-item__arrow--open"><use xlink:href="#iconRight"></use></svg>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
<span class="b3-list-item__text ft__on-surface">${window.siyuan.languages.plugin}</span>
|
|
|
|
|
|
</div>
|
2023-08-10 11:35:20 +08:00
|
|
|
|
<div class="b3-list__panel">
|
|
|
|
|
|
${pluginHtml}
|
|
|
|
|
|
</div>
|
2023-05-30 00:35:13 +08:00
|
|
|
|
</div>`;
|
2023-05-30 00:27:47 +08:00
|
|
|
|
}
|
2023-12-19 12:20:25 +08:00
|
|
|
|
return `<div class="fn__flex b3-label config__item">
|
2022-05-26 15:18:53 +08:00
|
|
|
|
<span class="fn__flex-center">${window.siyuan.languages.keymapTip}</span>
|
|
|
|
|
|
<span class="fn__flex-1"></span>
|
2022-06-11 21:46:06 +08:00
|
|
|
|
<button id="keymapRefreshBtn" class="b3-button b3-button--outline fn__flex-center fn__size200">
|
|
|
|
|
|
<svg><use xlink:href="#iconRefresh"></use></svg>
|
|
|
|
|
|
${window.siyuan.languages.refresh}
|
|
|
|
|
|
</button>
|
2023-12-19 12:20:25 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
<div class="fn__flex b3-label config__item">
|
2022-06-11 21:46:06 +08:00
|
|
|
|
<span class="fn__flex-center">${window.siyuan.languages.keymapTip2}</span>
|
|
|
|
|
|
<span class="fn__flex-1"></span>
|
|
|
|
|
|
<span class="fn__space"></span>
|
2022-05-26 15:18:53 +08:00
|
|
|
|
<button id="keymapResetBtn" class="b3-button b3-button--outline fn__flex-center fn__size200">
|
|
|
|
|
|
<svg><use xlink:href="#iconUndo"></use></svg>
|
|
|
|
|
|
${window.siyuan.languages.reset}
|
|
|
|
|
|
</button>
|
2023-12-19 12:20:25 +08:00
|
|
|
|
</div>
|
2022-05-26 15:18:53 +08:00
|
|
|
|
<div class="b3-label file-tree config-keymap" id="keymapList">
|
2023-01-02 16:12:03 +08:00
|
|
|
|
<div class="fn__flex config__item">
|
2023-03-15 23:34:47 +08:00
|
|
|
|
<label class="b3-form__icon fn__block">
|
2022-09-24 11:12:56 +08:00
|
|
|
|
<svg class="b3-form__icon-icon"><use xlink:href="#iconSearch"></use></svg>
|
|
|
|
|
|
<input id="keymapInput" class="b3-form__icon-input b3-text-field fn__block" placeholder="${window.siyuan.languages.search}">
|
|
|
|
|
|
</label>
|
|
|
|
|
|
<div class="fn__space"></div>
|
2023-03-15 23:34:47 +08:00
|
|
|
|
<label class="b3-form__icon fn__block searchByKeyLabel">
|
2022-09-24 11:12:56 +08:00
|
|
|
|
<svg class="b3-form__icon-icon"><use xlink:href="#iconKeymap"></use></svg>
|
2024-05-24 08:55:24 +08:00
|
|
|
|
<input id="searchByKey" data-value="" class="b3-form__icon-input b3-text-field fn__block" spellcheck="false" placeholder="${window.siyuan.languages.keymap}">
|
2022-09-24 11:12:56 +08:00
|
|
|
|
</label>
|
|
|
|
|
|
<div class="fn__space"></div>
|
|
|
|
|
|
<button id="clearSearchBtn" class="b3-button b3-button--outline fn__flex-center fn__size200">
|
|
|
|
|
|
<svg style="height: 14px"><use xlink:href="#iconClose"></use></svg>
|
|
|
|
|
|
${window.siyuan.languages.clear}
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</div>
|
2022-06-11 21:46:06 +08:00
|
|
|
|
<div class="fn__hr"></div>
|
2022-10-18 00:03:34 +08:00
|
|
|
|
<div class="b3-list b3-list--border b3-list--background">
|
2023-03-15 23:34:47 +08:00
|
|
|
|
<div class="b3-list-item b3-list-item--narrow toggle">
|
2022-10-18 22:58:46 +08:00
|
|
|
|
<span class="b3-list-item__toggle b3-list-item__toggle--hl"><svg class="b3-list-item__arrow"><use xlink:href="#iconRight"></use></svg></span>
|
2022-05-26 15:18:53 +08:00
|
|
|
|
<span class="b3-list-item__text ft__on-surface">${window.siyuan.languages.general}</span>
|
2022-10-18 00:03:34 +08:00
|
|
|
|
</div>
|
2023-03-15 23:34:47 +08:00
|
|
|
|
<div class="fn__none b3-list__panel">${keymap._genItem(window.siyuan.config.keymap.general, "general")}</div>
|
2022-10-18 00:03:34 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
<div class="b3-list b3-list--border b3-list--background">
|
2023-03-15 23:34:47 +08:00
|
|
|
|
<div class="b3-list-item b3-list-item--narrow toggle">
|
2022-10-18 22:58:46 +08:00
|
|
|
|
<span class="b3-list-item__toggle b3-list-item__toggle--hl">
|
2022-05-26 15:18:53 +08:00
|
|
|
|
<svg class="b3-list-item__arrow b3-list-item__arrow--open"><use xlink:href="#iconRight"></use></svg>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
<span class="b3-list-item__text ft__on-surface">${window.siyuan.languages.editor}</span>
|
2022-10-18 00:03:34 +08:00
|
|
|
|
</div>
|
2023-03-15 23:34:47 +08:00
|
|
|
|
<div class="b3-list__panel">
|
|
|
|
|
|
<div class="b3-list-item b3-list-item--narrow toggle">
|
2022-10-18 22:58:46 +08:00
|
|
|
|
<span class="b3-list-item__toggle b3-list-item__toggle--hl">
|
2022-05-26 15:18:53 +08:00
|
|
|
|
<svg class="b3-list-item__arrow"><use xlink:href="#iconRight"></use></svg>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
<span class="b3-list-item__text ft__on-surface">${window.siyuan.languages.general}</span>
|
2023-03-15 23:34:47 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
<div class="fn__none b3-list__panel">${keymap._genItem(window.siyuan.config.keymap.editor.general, "editor" + Constants.ZWSP + "general")}</div>
|
|
|
|
|
|
<div class="b3-list-item b3-list-item--narrow toggle">
|
2022-10-18 22:58:46 +08:00
|
|
|
|
<span class="b3-list-item__toggle b3-list-item__toggle--hl">
|
2022-05-26 15:18:53 +08:00
|
|
|
|
<svg class="b3-list-item__arrow"><use xlink:href="#iconRight"></use></svg>
|
|
|
|
|
|
</span>
|
2024-06-05 12:01:53 +08:00
|
|
|
|
<span class="b3-list-item__text ft__on-surface">${window.siyuan.languages.element}</span>
|
2023-03-15 23:34:47 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
<div class="fn__none b3-list__panel">${keymap._genItem(window.siyuan.config.keymap.editor.insert, "editor" + Constants.ZWSP + "insert")}</div>
|
|
|
|
|
|
<div class="b3-list-item b3-list-item--narrow toggle">
|
2022-10-18 22:58:46 +08:00
|
|
|
|
<span class="b3-list-item__toggle b3-list-item__toggle--hl">
|
2022-05-26 15:18:53 +08:00
|
|
|
|
<svg class="b3-list-item__arrow"><use xlink:href="#iconRight"></use></svg>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
<span class="b3-list-item__text ft__on-surface">${window.siyuan.languages.headings}</span>
|
2023-03-15 23:34:47 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
<div class="fn__none b3-list__panel">${keymap._genItem(window.siyuan.config.keymap.editor.heading, "editor" + Constants.ZWSP + "heading")}</div>
|
|
|
|
|
|
<div class="b3-list-item b3-list-item--narrow toggle">
|
2022-10-18 22:58:46 +08:00
|
|
|
|
<span class="b3-list-item__toggle b3-list-item__toggle--hl">
|
2022-05-26 15:18:53 +08:00
|
|
|
|
<svg class="b3-list-item__arrow"><use xlink:href="#iconRight"></use></svg>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
<span class="b3-list-item__text ft__on-surface">${window.siyuan.languages.list1}</span>
|
2023-03-15 23:34:47 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
<div class="fn__none b3-list__panel">${keymap._genItem(window.siyuan.config.keymap.editor.list, "editor" + Constants.ZWSP + "list")}</div>
|
|
|
|
|
|
<div class="b3-list-item b3-list-item--narrow toggle">
|
2022-10-18 22:58:46 +08:00
|
|
|
|
<span class="b3-list-item__toggle b3-list-item__toggle--hl">
|
2022-05-26 15:18:53 +08:00
|
|
|
|
<svg class="b3-list-item__arrow"><use xlink:href="#iconRight"></use></svg>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
<span class="b3-list-item__text ft__on-surface">${window.siyuan.languages.table}</span>
|
2023-03-15 23:34:47 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
<div class="fn__none b3-list__panel">${keymap._genItem(window.siyuan.config.keymap.editor.table, "editor" + Constants.ZWSP + "table")}</div>
|
2022-10-18 00:03:34 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
2023-05-30 00:27:47 +08:00
|
|
|
|
${pluginHtml}
|
2022-05-26 15:18:53 +08:00
|
|
|
|
</div>`;
|
|
|
|
|
|
},
|
2023-05-31 15:54:44 +08:00
|
|
|
|
_setkeymap(app: App) {
|
2024-03-24 22:35:30 +08:00
|
|
|
|
const data: Config.IKeymap = JSON.parse(JSON.stringify(Constants.SIYUAN_KEYMAP));
|
2024-03-29 09:47:40 +08:00
|
|
|
|
const oldToggleWin = window.siyuan.config.keymap.general.toggleWin.custom;
|
2022-10-18 00:03:34 +08:00
|
|
|
|
keymap.element.querySelectorAll("label.b3-list-item input").forEach((item) => {
|
2022-05-26 15:18:53 +08:00
|
|
|
|
const keys = item.getAttribute("data-key").split(Constants.ZWSP);
|
2023-06-01 20:50:49 +08:00
|
|
|
|
const newHotkey = item.getAttribute("data-value");
|
2023-05-30 00:27:47 +08:00
|
|
|
|
if (keys[0] === "plugin") {
|
2023-05-31 15:54:44 +08:00
|
|
|
|
window.siyuan.config.keymap.plugin[keys[1]][keys[2]].custom = newHotkey;
|
2023-05-30 00:27:47 +08:00
|
|
|
|
data.plugin = window.siyuan.config.keymap.plugin;
|
2023-05-31 15:54:44 +08:00
|
|
|
|
app.plugins.forEach((plugin) => {
|
|
|
|
|
|
if (plugin.name === keys[1]) {
|
|
|
|
|
|
plugin.commands.forEach(command => {
|
|
|
|
|
|
if (command.langKey === keys[2]) {
|
|
|
|
|
|
command.customHotkey = newHotkey;
|
|
|
|
|
|
}
|
2023-06-01 20:50:49 +08:00
|
|
|
|
});
|
2023-05-31 15:54:44 +08:00
|
|
|
|
}
|
2023-06-01 20:50:49 +08:00
|
|
|
|
});
|
2023-05-30 00:27:47 +08:00
|
|
|
|
} else if (keys[0] === "general") {
|
2023-05-31 15:54:44 +08:00
|
|
|
|
data[keys[0]][keys[1]].custom = newHotkey;
|
2022-05-26 15:18:53 +08:00
|
|
|
|
} else if (keys[0] === "editor" && (keys[1] === "general" || keys[1] === "insert" || keys[1] === "heading" || keys[1] === "list" || keys[1] === "table")) {
|
2023-05-31 15:54:44 +08:00
|
|
|
|
data[keys[0]][keys[1]][keys[2]].custom = newHotkey;
|
2022-05-26 15:18:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
window.siyuan.config.keymap = data;
|
|
|
|
|
|
fetchPost("/api/setting/setKeymap", {
|
|
|
|
|
|
data
|
|
|
|
|
|
}, () => {
|
2024-04-28 11:47:34 +08:00
|
|
|
|
ipcRenderer.send(Constants.SIYUAN_CMD, {
|
|
|
|
|
|
cmd: "writeLog",
|
|
|
|
|
|
msg: "user update keymap:" + JSON.stringify(window.siyuan.config.keymap)
|
|
|
|
|
|
});
|
2024-03-26 21:04:06 +08:00
|
|
|
|
if (oldToggleWin !== window.siyuan.config.keymap.general.toggleWin.custom) {
|
|
|
|
|
|
ipcRenderer.send(Constants.SIYUAN_CMD, {
|
|
|
|
|
|
cmd: "unregisterGlobalShortcut",
|
|
|
|
|
|
accelerator: oldToggleWin
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2023-08-30 17:15:17 +08:00
|
|
|
|
sendGlobalShortcut(app);
|
2022-05-26 15:18:53 +08:00
|
|
|
|
});
|
|
|
|
|
|
},
|
2023-04-19 10:46:24 +08:00
|
|
|
|
search(value: string, keymapString: string) {
|
2022-09-24 11:12:56 +08:00
|
|
|
|
keymap.element.querySelectorAll("#keymapList .b3-list-item--hide-action > .b3-list-item__text").forEach(item => {
|
2022-09-24 20:01:52 +08:00
|
|
|
|
const liElement = item.parentElement;
|
2022-09-24 11:12:56 +08:00
|
|
|
|
let matchedKeymap = false;
|
2024-05-23 17:14:52 +08:00
|
|
|
|
if (keymapString === "" || liElement.querySelector(".b3-text-field").getAttribute("data-value").indexOf(keymapString) > -1) {
|
2022-09-24 20:01:52 +08:00
|
|
|
|
matchedKeymap = true;
|
2022-09-24 11:12:56 +08:00
|
|
|
|
}
|
2023-05-14 09:55:50 +08:00
|
|
|
|
if ((item.textContent.toLowerCase().indexOf(value.toLowerCase()) > -1 || value.toLowerCase().indexOf(item.textContent.toLowerCase()) > -1 || value === "") && matchedKeymap) {
|
2022-09-24 11:12:56 +08:00
|
|
|
|
liElement.classList.remove("fn__none");
|
|
|
|
|
|
liElement.parentElement.classList.remove("fn__none");
|
|
|
|
|
|
liElement.parentElement.parentElement.classList.remove("fn__none");
|
|
|
|
|
|
} else {
|
|
|
|
|
|
liElement.classList.add("fn__none");
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!liElement.nextElementSibling) {
|
2022-09-24 20:01:52 +08:00
|
|
|
|
const toggleElement = liElement.parentElement.previousElementSibling;
|
|
|
|
|
|
const toggleIconElement = toggleElement.querySelector(".b3-list-item__arrow");
|
2022-09-24 11:12:56 +08:00
|
|
|
|
if (value === "" && keymapString === "") {
|
|
|
|
|
|
// 复原折叠状态
|
|
|
|
|
|
if (toggleIconElement.classList.contains("b3-list-item__arrow--open")) {
|
2022-09-24 20:01:52 +08:00
|
|
|
|
liElement.parentElement.classList.remove("fn__none");
|
2022-09-24 09:40:25 +08:00
|
|
|
|
} else {
|
2022-09-24 20:01:52 +08:00
|
|
|
|
liElement.parentElement.classList.add("fn__none");
|
2022-09-24 09:40:25 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2022-09-24 11:12:56 +08:00
|
|
|
|
// 隐藏没有子项的快捷键项目
|
2023-03-15 23:34:47 +08:00
|
|
|
|
if (liElement.parentElement.childElementCount === liElement.parentElement.querySelectorAll(".b3-list-item.fn__none").length) {
|
2022-09-24 11:12:56 +08:00
|
|
|
|
toggleElement.classList.add("fn__none");
|
|
|
|
|
|
} else {
|
|
|
|
|
|
toggleElement.classList.remove("fn__none");
|
|
|
|
|
|
}
|
2022-06-11 21:46:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
});
|
2022-09-24 11:12:56 +08:00
|
|
|
|
// 编辑器中三级菜单单独处理
|
2022-09-24 20:01:52 +08:00
|
|
|
|
const editorKeymapElement = keymap.element.querySelector("#keymapList").lastElementChild;
|
2022-09-24 11:12:56 +08:00
|
|
|
|
if (value === "" && keymapString === "") {
|
|
|
|
|
|
// 复原折叠状态
|
|
|
|
|
|
if (editorKeymapElement.querySelector(".b3-list-item__arrow").classList.contains("b3-list-item__arrow--open")) {
|
2022-09-24 20:01:52 +08:00
|
|
|
|
editorKeymapElement.lastElementChild.classList.remove("fn__none");
|
2022-09-24 11:12:56 +08:00
|
|
|
|
} else {
|
2022-09-24 20:01:52 +08:00
|
|
|
|
editorKeymapElement.lastElementChild.classList.add("fn__none");
|
2022-09-24 11:12:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
// 隐藏没有子项的快捷键项目
|
|
|
|
|
|
if (editorKeymapElement.querySelectorAll(".b3-list-item--hide-action.fn__none").length === editorKeymapElement.querySelectorAll(".b3-list-item--hide-action").length) {
|
|
|
|
|
|
editorKeymapElement.firstElementChild.classList.add("fn__none");
|
|
|
|
|
|
} else {
|
|
|
|
|
|
editorKeymapElement.firstElementChild.classList.remove("fn__none");
|
|
|
|
|
|
}
|
2022-06-11 21:46:06 +08:00
|
|
|
|
},
|
2023-05-30 00:27:47 +08:00
|
|
|
|
_getTip(element: HTMLElement) {
|
|
|
|
|
|
const thirdElement = element.parentElement;
|
2023-05-30 00:35:13 +08:00
|
|
|
|
let tip = thirdElement.querySelector(".b3-list-item__text").textContent.trim();
|
2023-05-30 00:27:47 +08:00
|
|
|
|
const secondElement = thirdElement.parentElement.previousElementSibling;
|
|
|
|
|
|
tip = secondElement.textContent.trim() + "-" + tip;
|
|
|
|
|
|
const firstElement = secondElement.parentElement.previousElementSibling;
|
|
|
|
|
|
if (firstElement.classList.contains("b3-list-item")) {
|
|
|
|
|
|
tip = firstElement.textContent.trim() + "-" + tip;
|
|
|
|
|
|
}
|
2023-05-30 00:35:13 +08:00
|
|
|
|
return tip;
|
2023-05-30 00:27:47 +08:00
|
|
|
|
},
|
2023-05-31 15:54:44 +08:00
|
|
|
|
bindEvent(app: App) {
|
2022-06-11 21:46:06 +08:00
|
|
|
|
keymap.element.querySelector("#keymapRefreshBtn").addEventListener("click", () => {
|
2023-05-11 12:22:53 +08:00
|
|
|
|
exportLayout({
|
2023-12-31 16:51:31 +08:00
|
|
|
|
cb() {
|
|
|
|
|
|
window.location.reload();
|
|
|
|
|
|
},
|
2023-05-11 12:22:53 +08:00
|
|
|
|
errorExit: false,
|
|
|
|
|
|
});
|
2022-06-11 21:46:06 +08:00
|
|
|
|
});
|
2022-06-11 21:47:20 +08:00
|
|
|
|
const searchElement = keymap.element.querySelector("#keymapInput") as HTMLInputElement;
|
2022-09-24 11:12:56 +08:00
|
|
|
|
const searchKeymapElement = keymap.element.querySelector("#searchByKey") as HTMLInputElement;
|
|
|
|
|
|
searchElement.addEventListener("compositionend", () => {
|
2024-05-23 17:14:52 +08:00
|
|
|
|
keymap.search(searchElement.value, searchKeymapElement.dataset.value);
|
2022-06-11 21:46:06 +08:00
|
|
|
|
});
|
|
|
|
|
|
searchElement.addEventListener("input", (event: InputEvent) => {
|
|
|
|
|
|
if (event.isComposing) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2024-05-23 17:14:52 +08:00
|
|
|
|
keymap.search(searchElement.value, searchKeymapElement.dataset.value);
|
2022-09-24 11:12:56 +08:00
|
|
|
|
});
|
2023-10-22 17:23:22 +08:00
|
|
|
|
/// #if !BROWSER
|
|
|
|
|
|
searchKeymapElement.addEventListener("focus", () => {
|
|
|
|
|
|
ipcRenderer.send(Constants.SIYUAN_CMD, {
|
2024-03-26 21:04:06 +08:00
|
|
|
|
cmd: "unregisterGlobalShortcut",
|
|
|
|
|
|
accelerator: window.siyuan.config.keymap.general.toggleWin.custom
|
2023-10-22 17:23:22 +08:00
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
/// #endif
|
|
|
|
|
|
searchKeymapElement.addEventListener("blur", () => {
|
|
|
|
|
|
sendGlobalShortcut(app);
|
|
|
|
|
|
});
|
2022-09-24 11:12:56 +08:00
|
|
|
|
searchKeymapElement.addEventListener("keydown", function (event: KeyboardEvent) {
|
|
|
|
|
|
event.stopPropagation();
|
|
|
|
|
|
event.preventDefault();
|
2023-10-22 12:03:09 +08:00
|
|
|
|
const keymapStr = keymap._getKeymapString(event);
|
|
|
|
|
|
// Mac 中文下会直接输入
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
this.value = updateHotkeyTip(keymapStr);
|
|
|
|
|
|
});
|
2024-05-23 17:14:52 +08:00
|
|
|
|
this.dataset.keymap = keymapStr;
|
2023-04-19 10:46:24 +08:00
|
|
|
|
keymap.search(searchElement.value, keymapStr);
|
2022-09-24 11:12:56 +08:00
|
|
|
|
});
|
|
|
|
|
|
keymap.element.querySelector("#clearSearchBtn").addEventListener("click", () => {
|
2022-09-24 20:01:52 +08:00
|
|
|
|
searchElement.value = "";
|
2022-09-24 11:12:56 +08:00
|
|
|
|
searchKeymapElement.value = "";
|
2023-04-19 10:46:24 +08:00
|
|
|
|
keymap.search("", "");
|
2022-06-11 21:46:06 +08:00
|
|
|
|
});
|
2022-05-26 15:18:53 +08:00
|
|
|
|
keymap.element.querySelector("#keymapResetBtn").addEventListener("click", () => {
|
2024-04-28 11:01:32 +08:00
|
|
|
|
confirmDialog("⚠️ " + window.siyuan.languages.reset, window.siyuan.languages.confirmReset, () => {
|
2022-11-05 16:36:12 +08:00
|
|
|
|
fetchPost("/api/setting/setKeymap", {
|
|
|
|
|
|
data: Constants.SIYUAN_KEYMAP,
|
|
|
|
|
|
}, () => {
|
2024-04-28 11:47:34 +08:00
|
|
|
|
ipcRenderer.send(Constants.SIYUAN_CMD, {
|
|
|
|
|
|
cmd: "writeLog",
|
|
|
|
|
|
msg: "user reset keymap"
|
|
|
|
|
|
});
|
2024-03-26 21:04:06 +08:00
|
|
|
|
if (window.siyuan.config.keymap.general.toggleWin.default !== window.siyuan.config.keymap.general.toggleWin.custom) {
|
|
|
|
|
|
ipcRenderer.send(Constants.SIYUAN_CMD, {
|
|
|
|
|
|
cmd: "unregisterGlobalShortcut",
|
|
|
|
|
|
accelerator: window.siyuan.config.keymap.general.toggleWin.custom
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2022-11-05 16:36:12 +08:00
|
|
|
|
window.location.reload();
|
2023-08-30 17:15:17 +08:00
|
|
|
|
sendGlobalShortcut(app);
|
2022-11-05 16:36:12 +08:00
|
|
|
|
});
|
2022-05-26 15:18:53 +08:00
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
const keymapListElement = keymap.element.querySelector("#keymapList");
|
|
|
|
|
|
keymapListElement.addEventListener("click", (event) => {
|
|
|
|
|
|
let target = event.target as HTMLElement;
|
|
|
|
|
|
while (target && !target.isEqualNode(keymapListElement)) {
|
2023-03-15 23:34:47 +08:00
|
|
|
|
const type = target.getAttribute("data-type");
|
|
|
|
|
|
if (type === "reset") {
|
2022-05-26 15:18:53 +08:00
|
|
|
|
const inputElement = target.parentElement.querySelector(".b3-text-field") as HTMLInputElement;
|
2023-03-15 23:34:47 +08:00
|
|
|
|
inputElement.value = updateHotkeyTip(inputElement.getAttribute("data-default"));
|
|
|
|
|
|
inputElement.setAttribute("data-value", inputElement.getAttribute("data-default"));
|
|
|
|
|
|
inputElement.previousElementSibling.textContent = inputElement.value;
|
2023-05-31 15:54:44 +08:00
|
|
|
|
keymap._setkeymap(app);
|
2022-05-26 15:18:53 +08:00
|
|
|
|
event.preventDefault();
|
|
|
|
|
|
event.stopPropagation();
|
|
|
|
|
|
break;
|
2023-03-15 23:34:47 +08:00
|
|
|
|
} else if (type === "clear") {
|
|
|
|
|
|
const inputElement = target.parentElement.querySelector(".b3-text-field") as HTMLInputElement;
|
|
|
|
|
|
inputElement.value = "";
|
|
|
|
|
|
inputElement.previousElementSibling.textContent = "";
|
|
|
|
|
|
inputElement.setAttribute("data-value", "");
|
2023-05-31 15:54:44 +08:00
|
|
|
|
keymap._setkeymap(app);
|
2023-03-15 23:34:47 +08:00
|
|
|
|
event.preventDefault();
|
|
|
|
|
|
event.stopPropagation();
|
|
|
|
|
|
break;
|
|
|
|
|
|
} else if (type === "update") {
|
|
|
|
|
|
target.classList.add("fn__none");
|
|
|
|
|
|
const inputElement = target.nextElementSibling as HTMLInputElement;
|
|
|
|
|
|
inputElement.classList.remove("fn__none");
|
|
|
|
|
|
inputElement.focus();
|
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
|
event.stopPropagation();
|
|
|
|
|
|
break;
|
|
|
|
|
|
} else if (target.classList.contains("b3-list-item--hide-action")) {
|
|
|
|
|
|
const inputElement = target.querySelector(".b3-text-field") as HTMLInputElement;
|
|
|
|
|
|
inputElement.classList.remove("fn__none");
|
|
|
|
|
|
inputElement.focus();
|
|
|
|
|
|
inputElement.previousElementSibling.classList.add("fn__none");
|
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
|
event.stopPropagation();
|
|
|
|
|
|
break;
|
2022-05-26 15:18:53 +08:00
|
|
|
|
} else if (target.classList.contains("toggle")) {
|
|
|
|
|
|
if (target.nextElementSibling.classList.contains("fn__none")) {
|
|
|
|
|
|
target.firstElementChild.firstElementChild.classList.add("b3-list-item__arrow--open");
|
|
|
|
|
|
target.nextElementSibling.classList.remove("fn__none");
|
|
|
|
|
|
} else {
|
|
|
|
|
|
target.firstElementChild.firstElementChild.classList.remove("b3-list-item__arrow--open");
|
|
|
|
|
|
target.nextElementSibling.classList.add("fn__none");
|
|
|
|
|
|
}
|
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
|
event.stopPropagation();
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
target = target.parentElement;
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
let timeout: number;
|
2023-03-15 23:34:47 +08:00
|
|
|
|
keymapListElement.querySelectorAll("label.b3-list-item input").forEach((item: HTMLInputElement) => {
|
2022-06-11 21:46:06 +08:00
|
|
|
|
item.addEventListener("keydown", function (event: KeyboardEvent) {
|
2022-05-26 15:18:53 +08:00
|
|
|
|
event.stopPropagation();
|
|
|
|
|
|
event.preventDefault();
|
2023-10-22 12:03:09 +08:00
|
|
|
|
const keymapStr = keymap._getKeymapString(event);
|
2023-10-22 12:11:05 +08:00
|
|
|
|
const adoptKeymapStr = updateHotkeyTip(keymapStr);
|
2022-05-26 15:18:53 +08:00
|
|
|
|
clearTimeout(timeout);
|
|
|
|
|
|
timeout = window.setTimeout(() => {
|
|
|
|
|
|
const keys = this.getAttribute("data-key").split(Constants.ZWSP);
|
|
|
|
|
|
if (keys[1] === "list") {
|
|
|
|
|
|
keys[1] = "list1";
|
|
|
|
|
|
}
|
|
|
|
|
|
if (keys[1] === "heading") {
|
|
|
|
|
|
keys[1] = "headings";
|
|
|
|
|
|
}
|
2023-10-24 10:42:04 +08:00
|
|
|
|
let hasConflict = false;
|
2024-06-15 11:20:34 +08:00
|
|
|
|
const isAssistKey = ["⌘", "⇧", "⌥", "⌃"].includes(keymapStr.substr(keymapStr.length - 1, 1))
|
|
|
|
|
|
if (isAssistKey ||
|
2024-01-16 17:27:49 +08:00
|
|
|
|
["⌘A", "⌘X", "⌘C", "⌘V", "⌘-", "⌘=", "⌘0", "⇧⌘V", "⌘/", "⇧↑", "⇧↓", "⇧→", "⇧←", "⇧⇥", "⌃D", "⇧⌘→", "⇧⌘←", "⌘Home", "⌘End", "⇧↩", "↩", "PageUp", "PageDown", "⌫", "⌦", "Escape"].includes(keymapStr) ||
|
2023-11-16 10:39:42 +08:00
|
|
|
|
// 跳转到下/上一个编辑页签不能包含 ctrl, 否则不能监听到 keyup
|
2023-11-16 11:22:37 +08:00
|
|
|
|
(isMac() && keys[0] === "general" && ["goToEditTabNext", "goToEditTabPrev"].includes(keys[1]) && keymapStr.includes("⌘"))
|
2023-11-16 10:39:42 +08:00
|
|
|
|
) {
|
2024-06-15 11:20:34 +08:00
|
|
|
|
if (!isAssistKey) {
|
|
|
|
|
|
showMessage(`${window.siyuan.languages.invalid} [${adoptKeymapStr}]`);
|
|
|
|
|
|
}
|
2023-10-22 12:03:09 +08:00
|
|
|
|
hasConflict = true;
|
2022-05-26 15:18:53 +08:00
|
|
|
|
}
|
2023-10-22 17:23:22 +08:00
|
|
|
|
Array.from(keymap.element.querySelectorAll("label.b3-list-item input")).find((inputItem: HTMLElement) => {
|
2023-10-22 12:13:46 +08:00
|
|
|
|
if (!inputItem.isSameNode(this) && inputItem.getAttribute("data-value") === keymapStr) {
|
2022-05-26 15:18:53 +08:00
|
|
|
|
const inputValueList = inputItem.getAttribute("data-key").split(Constants.ZWSP);
|
|
|
|
|
|
if (inputValueList[1] === "list") {
|
|
|
|
|
|
inputValueList[1] = "list1";
|
|
|
|
|
|
}
|
|
|
|
|
|
if (inputValueList[1] === "heading") {
|
|
|
|
|
|
inputValueList[1] = "headings";
|
|
|
|
|
|
}
|
2023-10-22 12:11:05 +08:00
|
|
|
|
showMessage(`${window.siyuan.languages.conflict} [${keymap._getTip(inputItem)} ${adoptKeymapStr}]`);
|
2023-10-22 12:03:09 +08:00
|
|
|
|
hasConflict = true;
|
2022-05-26 15:18:53 +08:00
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
if (hasConflict) {
|
2023-10-22 12:13:46 +08:00
|
|
|
|
this.value = updateHotkeyTip(this.getAttribute("data-value"));
|
2022-05-26 15:18:53 +08:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
2023-10-22 17:23:22 +08:00
|
|
|
|
hideMessage();
|
2023-10-22 12:13:46 +08:00
|
|
|
|
this.setAttribute("data-value", keymapStr);
|
2023-10-22 12:11:05 +08:00
|
|
|
|
this.value = adoptKeymapStr;
|
2023-05-31 15:54:44 +08:00
|
|
|
|
keymap._setkeymap(app);
|
2023-10-22 17:23:22 +08:00
|
|
|
|
}, Constants.TIMEOUT_TRANSITION);
|
2022-05-26 15:18:53 +08:00
|
|
|
|
});
|
2023-03-15 23:34:47 +08:00
|
|
|
|
item.addEventListener("blur", function () {
|
2023-10-22 17:23:22 +08:00
|
|
|
|
sendGlobalShortcut(app);
|
2023-03-15 23:34:47 +08:00
|
|
|
|
setTimeout(() => {
|
2023-03-16 11:19:46 +08:00
|
|
|
|
this.classList.add("fn__none");
|
|
|
|
|
|
this.previousElementSibling.textContent = this.value;
|
|
|
|
|
|
this.previousElementSibling.classList.remove("fn__none");
|
2023-03-15 23:34:47 +08:00
|
|
|
|
}, Constants.TIMEOUT_INPUT); // 隐藏的话点击删除无法 target 会为 li
|
|
|
|
|
|
});
|
2023-10-22 17:23:22 +08:00
|
|
|
|
/// #if !BROWSER
|
|
|
|
|
|
item.addEventListener("focus", () => {
|
|
|
|
|
|
ipcRenderer.send(Constants.SIYUAN_CMD, {
|
2024-03-26 21:04:06 +08:00
|
|
|
|
cmd: "unregisterGlobalShortcut",
|
|
|
|
|
|
accelerator: window.siyuan.config.keymap.general.toggleWin.custom
|
2023-10-22 17:23:22 +08:00
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
/// #endif
|
2022-05-26 15:18:53 +08:00
|
|
|
|
});
|
|
|
|
|
|
},
|
2023-10-22 12:03:09 +08:00
|
|
|
|
_getKeymapString(event: KeyboardEvent) {
|
2022-09-24 11:12:56 +08:00
|
|
|
|
let keymapStr = "";
|
2023-11-12 12:28:20 +08:00
|
|
|
|
if (event.ctrlKey && isMac()) {
|
2022-09-24 11:12:56 +08:00
|
|
|
|
keymapStr += "⌃";
|
|
|
|
|
|
}
|
|
|
|
|
|
if (event.altKey) {
|
|
|
|
|
|
keymapStr += "⌥";
|
|
|
|
|
|
}
|
|
|
|
|
|
if (event.shiftKey) {
|
|
|
|
|
|
keymapStr += "⇧";
|
|
|
|
|
|
}
|
2023-11-12 12:28:20 +08:00
|
|
|
|
if (event.metaKey || (!isMac() && event.ctrlKey)) {
|
2022-09-24 11:12:56 +08:00
|
|
|
|
keymapStr += "⌘";
|
|
|
|
|
|
}
|
2023-06-17 16:56:05 +08:00
|
|
|
|
if (event.key !== "Shift" && event.key !== "Alt" && event.key !== "Meta" && event.key !== "Control" && event.key !== "Unidentified") {
|
|
|
|
|
|
if (event.keyCode === 229) {
|
|
|
|
|
|
// windows 中文输入法下 shift + - 等
|
|
|
|
|
|
if (event.code === "Minus") {
|
|
|
|
|
|
keymapStr += "-";
|
|
|
|
|
|
} else if (event.code === "Semicolon") {
|
|
|
|
|
|
keymapStr += ";";
|
|
|
|
|
|
} else if (event.code === "Quote") {
|
|
|
|
|
|
keymapStr += "'";
|
|
|
|
|
|
} else if (event.code === "Comma") {
|
|
|
|
|
|
keymapStr += ",";
|
|
|
|
|
|
} else if (event.code === "Period") {
|
|
|
|
|
|
keymapStr += ".";
|
|
|
|
|
|
} else if (event.code === "Slash") {
|
|
|
|
|
|
keymapStr += "/";
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
keymapStr += Constants.KEYCODELIST[event.keyCode] || (event.key.length > 1 ? event.key : event.key.toUpperCase());
|
|
|
|
|
|
}
|
2022-09-24 11:12:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
return keymapStr;
|
|
|
|
|
|
}
|
2022-05-26 15:18:53 +08:00
|
|
|
|
};
|