trilium/src/public/javascripts/services/keyboard_actions.js

129 lines
3.4 KiB
JavaScript
Raw Normal View History

import server from "./server.js";
import utils from "./utils.js";
2020-01-20 05:05:45 +08:00
import appContext from "./app_context.js";
const keyboardActionRepo = {};
const keyboardActionsLoaded = server.get('keyboard-actions').then(actions => {
actions = actions.filter(a => !!a.actionName); // filter out separators
for (const action of actions) {
action.effectiveShortcuts = action.effectiveShortcuts.filter(shortcut => !shortcut.startsWith("global:"));
action.actionName = action.actionName.charAt(0).toLowerCase() + action.actionName.slice(1);
keyboardActionRepo[action.actionName] = action;
}
2020-01-20 05:05:45 +08:00
return actions;
});
2020-01-20 05:05:45 +08:00
async function getActionsForScope(scope) {
const actions = await keyboardActionsLoaded;
return actions.filter(action => action.scope === scope);
}
async function setupActionsForElement(scope, $el, component) {
const actions = await getActionsForScope(scope);
for (const action of actions) {
for (const shortcut of action.effectiveShortcuts) {
utils.bindElShortcut($el, shortcut, () => component.triggerCommand(action.actionName));
}
}
}
getActionsForScope("window").then(actions => {
for (const action of actions) {
for (const shortcut of action.effectiveShortcuts) {
// empty object param so that destructuring with optional params work
utils.bindGlobalShortcut(shortcut, () => appContext.trigger(action.actionName, {}));
2020-01-20 05:05:45 +08:00
}
}
});
server.get('keyboard-shortcuts-for-notes').then(shortcutForNotes => {
for (const shortcut in shortcutForNotes) {
utils.bindGlobalShortcut(shortcut, async () => {
appContext.tabManager.getActiveTabContext().setNote(shortcutForNotes[shortcut]);
});
}
});
function setElementActionHandler($el, actionName, handler) {
keyboardActionsLoaded.then(() => {
const action = keyboardActionRepo[actionName];
if (!action) {
throw new Error(`Cannot find keyboard action '${actionName}'`);
}
// not setting action.handler since this is not global
for (const shortcut of action.effectiveShortcuts) {
if (shortcut) {
utils.bindElShortcut($el, shortcut, handler);
}
}
});
}
async function triggerAction(actionName) {
const action = await getAction(actionName);
2019-11-22 05:24:07 +08:00
if (!action.handler) {
throw new Error(`Action ${actionName} has no handler`);
}
await action.handler();
}
async function getAction(actionName, silent = false) {
await keyboardActionsLoaded;
const action = keyboardActionRepo[actionName];
if (!action) {
if (silent) {
console.log(`Cannot find action ${actionName}`);
}
else {
throw new Error(`Cannot find action ${actionName}`);
}
}
2019-11-22 05:24:07 +08:00
return action;
}
function updateDisplayedShortcuts($container) {
$container.find('kbd[data-kb-action]').each(async (i, el) => {
const actionName = $(el).attr('data-kb-action');
const action = await getAction(actionName, true);
if (action) {
$(el).text(action.effectiveShortcuts.join(', '));
}
});
2020-01-21 05:35:52 +08:00
$container.find('button[data-kb-action],a.icon-action[data-kb-action],.kb-in-title').each(async (i, el) => {
const actionName = $(el).attr('data-kb-action');
const action = await getAction(actionName, true);
if (action) {
const title = $(el).attr('title');
const shortcuts = action.effectiveShortcuts.join(', ');
const newTitle = !title || !title.trim() ? shortcuts : `${title} (${shortcuts})`;
$(el).attr('title', newTitle);
}
});
}
export default {
setElementActionHandler,
2019-11-22 05:24:07 +08:00
triggerAction,
getAction,
updateDisplayedShortcuts,
getActionsForScope,
setupActionsForElement
};