mirror of
				https://github.com/TriliumNext/Notes.git
				synced 2025-11-04 15:11:31 +08:00 
			
		
		
		
	refactored keyboard actions into commands
This commit is contained in:
		
							parent
							
								
									880f4ad711
								
							
						
					
					
						commit
						a679fedb58
					
				@ -42,14 +42,12 @@ class AppContext extends Component {
 | 
				
			|||||||
            this.triggerEvent(eventName);
 | 
					            this.triggerEvent(eventName);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.children = [
 | 
					        this.children = [ rootWidget ];
 | 
				
			||||||
            this.tabManager,
 | 
					 | 
				
			||||||
            rootWidget,
 | 
					 | 
				
			||||||
            new Entrypoints(this)
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.executors = [
 | 
					        this.executors = [
 | 
				
			||||||
            new DialogCommandExecutor(this)
 | 
					            this.tabManager,
 | 
				
			||||||
 | 
					            new DialogCommandExecutor(this),
 | 
				
			||||||
 | 
					            new Entrypoints(this)
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (utils.isElectron()) {
 | 
					        if (utils.isElectron()) {
 | 
				
			||||||
@ -67,9 +65,7 @@ class AppContext extends Component {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    async triggerCommand(name, data = {}) {
 | 
					    async triggerCommand(name, data = {}) {
 | 
				
			||||||
        for (const executor of this.executors) {
 | 
					        for (const executor of this.executors) {
 | 
				
			||||||
            const fun = executor[name + 'Command'];
 | 
					            const called = await executor.handleCommand(name, data);
 | 
				
			||||||
 | 
					 | 
				
			||||||
            const called = await this.callMethod(executor, fun, data);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (called) {
 | 
					            if (called) {
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
 | 
				
			|||||||
@ -51,4 +51,20 @@ export default class DialogCommandExecutor extends Component {
 | 
				
			|||||||
        const d = await import("../dialogs/move_to.js");
 | 
					        const d = await import("../dialogs/move_to.js");
 | 
				
			||||||
        d.showDialog(branchIds);
 | 
					        d.showDialog(branchIds);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    showOptionsCommand() {
 | 
				
			||||||
 | 
					        import("../dialogs/options.js").then(d => d.showDialog())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    showHelpCommand() {
 | 
				
			||||||
 | 
					        import("../dialogs/help.js").then(d => d.showDialog())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    showSQLConsoleCommand() {
 | 
				
			||||||
 | 
					        import("../dialogs/sql_console.js").then(d => d.showDialog())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    showBackendLogCommand() {
 | 
				
			||||||
 | 
					        import("../dialogs/backend_log.js").then(d => d.showDialog())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -8,8 +8,8 @@ import appContext from "./app_context.js";
 | 
				
			|||||||
import Component from "../widgets/component.js";
 | 
					import Component from "../widgets/component.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class Entrypoints extends Component {
 | 
					export default class Entrypoints extends Component {
 | 
				
			||||||
    constructor(appContext, parent) {
 | 
					    constructor(parent) {
 | 
				
			||||||
        super(appContext, parent);
 | 
					        super(parent);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // hot keys are active also inside inputs and content editables
 | 
					        // hot keys are active also inside inputs and content editables
 | 
				
			||||||
        jQuery.hotkeys.options.filterInputAcceptingElements = false;
 | 
					        jQuery.hotkeys.options.filterInputAcceptingElements = false;
 | 
				
			||||||
@ -29,13 +29,13 @@ export default class Entrypoints extends Component {
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    openDevToolsEvent() {
 | 
					    openDevToolsCommand() {
 | 
				
			||||||
        if (utils.isElectron()) {
 | 
					        if (utils.isElectron()) {
 | 
				
			||||||
            require('electron').remote.getCurrentWindow().toggleDevTools();
 | 
					            require('electron').remote.getCurrentWindow().toggleDevTools();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    findInTextEvent() {
 | 
					    findInTextCommand() {
 | 
				
			||||||
        if (!utils.isElectron()) {
 | 
					        if (!utils.isElectron()) {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -56,9 +56,7 @@ export default class Entrypoints extends Component {
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async createNoteIntoDayNoteCommand() {
 | 
				
			||||||
 | 
					 | 
				
			||||||
    async createNoteIntoDayNoteEvent() {
 | 
					 | 
				
			||||||
        const todayNote = await dateNoteService.getTodayNote();
 | 
					        const todayNote = await dateNoteService.getTodayNote();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const {note} = await server.post(`notes/${todayNote.noteId}/children?target=into`, {
 | 
					        const {note} = await server.post(`notes/${todayNote.noteId}/children?target=into`, {
 | 
				
			||||||
@ -74,10 +72,10 @@ export default class Entrypoints extends Component {
 | 
				
			|||||||
        appContext.tabManager.activateTab(tabContext.tabId);
 | 
					        appContext.tabManager.activateTab(tabContext.tabId);
 | 
				
			||||||
        await tabContext.setNote(note.noteId);
 | 
					        await tabContext.setNote(note.noteId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        appContext.triggerEvent('focusAndSelectTitle');
 | 
					        appContext.triggerCommand('focusAndSelectTitle');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async toggleNoteHoistingEvent() {
 | 
					    async toggleNoteHoistingCommand() {
 | 
				
			||||||
        const note = appContext.tabManager.getActiveTabNote();
 | 
					        const note = appContext.tabManager.getActiveTabNote();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const hoistedNoteId = hoistedNoteService.getHoistedNoteId();
 | 
					        const hoistedNoteId = hoistedNoteService.getHoistedNoteId();
 | 
				
			||||||
@ -93,11 +91,11 @@ export default class Entrypoints extends Component {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    copyWithoutFormattingEvent() {
 | 
					    copyWithoutFormattingCommand() {
 | 
				
			||||||
        utils.copySelectionToClipboard();
 | 
					        utils.copySelectionToClipboard();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    toggleFullscreenEvent() {
 | 
					    toggleFullscreenCommand() {
 | 
				
			||||||
        if (utils.isElectron()) {
 | 
					        if (utils.isElectron()) {
 | 
				
			||||||
            const win = require('electron').remote.getCurrentWindow();
 | 
					            const win = require('electron').remote.getCurrentWindow();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -111,7 +109,7 @@ export default class Entrypoints extends Component {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    toggleZenModeEvent() {
 | 
					    toggleZenModeCommand() {
 | 
				
			||||||
        if (!this.zenModeActive) {
 | 
					        if (!this.zenModeActive) {
 | 
				
			||||||
            $(".hide-in-zen-mode,.gutter").addClass("hidden-by-zen-mode");
 | 
					            $(".hide-in-zen-mode,.gutter").addClass("hidden-by-zen-mode");
 | 
				
			||||||
            $("#container").addClass("zen-mode");
 | 
					            $("#container").addClass("zen-mode");
 | 
				
			||||||
@ -125,11 +123,11 @@ export default class Entrypoints extends Component {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    reloadFrontendAppEvent() {
 | 
					    reloadFrontendAppCommand() {
 | 
				
			||||||
        utils.reloadApp();
 | 
					        utils.reloadApp();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    logoutEvent() {
 | 
					    logoutCommand() {
 | 
				
			||||||
        const $logoutForm = $('<form action="logout" method="POST">')
 | 
					        const $logoutForm = $('<form action="logout" method="POST">')
 | 
				
			||||||
            .append($(`<input type="hidden" name="_csrf" value="${glob.csrfToken}"/>`));
 | 
					            .append($(`<input type="hidden" name="_csrf" value="${glob.csrfToken}"/>`));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -137,27 +135,11 @@ export default class Entrypoints extends Component {
 | 
				
			|||||||
        $logoutForm.trigger('submit');
 | 
					        $logoutForm.trigger('submit');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    showOptionsEvent() {
 | 
					    backInNoteHistoryCommand() {
 | 
				
			||||||
        import("../dialogs/options.js").then(d => d.showDialog())
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    showHelpEvent() {
 | 
					 | 
				
			||||||
        import("../dialogs/help.js").then(d => d.showDialog())
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    showSQLConsoleEvent() {
 | 
					 | 
				
			||||||
        import("../dialogs/sql_console.js").then(d => d.showDialog())
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    showBackendLogEvent() {
 | 
					 | 
				
			||||||
        import("../dialogs/backend_log.js").then(d => d.showDialog())
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    backInNoteHistoryEvent() {
 | 
					 | 
				
			||||||
        window.history.back();
 | 
					        window.history.back();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    forwardInNoteHistoryEvent() {
 | 
					    forwardInNoteHistoryCommand() {
 | 
				
			||||||
        window.history.forward();
 | 
					        window.history.forward();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -95,8 +95,8 @@ async function getAction(actionName, silent = false) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function updateDisplayedShortcuts($container) {
 | 
					function updateDisplayedShortcuts($container) {
 | 
				
			||||||
	$container.find('kbd[data-kb-action]').each(async (i, el) => {
 | 
						$container.find('kbd[data-kb-command]').each(async (i, el) => {
 | 
				
			||||||
		const actionName = $(el).attr('data-kb-action');
 | 
							const actionName = $(el).attr('data-kb-command');
 | 
				
			||||||
		const action = await getAction(actionName, true);
 | 
							const action = await getAction(actionName, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (action) {
 | 
							if (action) {
 | 
				
			||||||
@ -104,8 +104,8 @@ function updateDisplayedShortcuts($container) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	$container.find('button[data-kb-action],a.icon-action[data-kb-action],.kb-in-title').each(async (i, el) => {
 | 
						$container.find('button[data-kb-command],a.icon-action[data-kb-command],.kb-in-title').each(async (i, el) => {
 | 
				
			||||||
		const actionName = $(el).attr('data-kb-action');
 | 
							const actionName = $(el).attr('data-kb-command');
 | 
				
			||||||
		const action = await getAction(actionName, true);
 | 
							const action = await getAction(actionName, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (action) {
 | 
							if (action) {
 | 
				
			||||||
 | 
				
			|||||||
@ -41,7 +41,7 @@ export async function initSpellCheck() {
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    new ContextMenuEvent(async (info) => {
 | 
					    new ContextMenuListener(async (info) => {
 | 
				
			||||||
        await contextMenuBuilder.showPopupMenu(info);
 | 
					        await contextMenuBuilder.showPopupMenu(info);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -250,21 +250,21 @@ export default class TabManager extends Component {
 | 
				
			|||||||
        this.tabsUpdate.scheduleUpdate();
 | 
					        this.tabsUpdate.scheduleUpdate();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    activateNextTabEvent() {
 | 
					    activateNextTabCommand() {
 | 
				
			||||||
        const oldIdx = this.tabContexts.findIndex(tc => tc.tabId === this.activeTabId);
 | 
					        const oldIdx = this.tabContexts.findIndex(tc => tc.tabId === this.activeTabId);
 | 
				
			||||||
        const newActiveTabId = this.tabContexts[oldIdx === this.tabContexts.length - 1 ? 0 : oldIdx + 1].tabId;
 | 
					        const newActiveTabId = this.tabContexts[oldIdx === this.tabContexts.length - 1 ? 0 : oldIdx + 1].tabId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.activateTab(newActiveTabId);
 | 
					        this.activateTab(newActiveTabId);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    activatePreviousTabEvent() {
 | 
					    activatePreviousTabCommand() {
 | 
				
			||||||
        const oldIdx = this.tabContexts.findIndex(tc => tc.tabId === this.activeTabId);
 | 
					        const oldIdx = this.tabContexts.findIndex(tc => tc.tabId === this.activeTabId);
 | 
				
			||||||
        const newActiveTabId = this.tabContexts[oldIdx === 0 ? this.tabContexts.length - 1 : oldIdx - 1].tabId;
 | 
					        const newActiveTabId = this.tabContexts[oldIdx === 0 ? this.tabContexts.length - 1 : oldIdx - 1].tabId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.activateTab(newActiveTabId);
 | 
					        this.activateTab(newActiveTabId);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    closeActiveTabEvent() {
 | 
					    closeActiveTabCommand() {
 | 
				
			||||||
        this.removeTab(this.activeTabId);
 | 
					        this.removeTab(this.activeTabId);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -272,17 +272,17 @@ export default class TabManager extends Component {
 | 
				
			|||||||
        this.tabsUpdate.updateNowIfNecessary();
 | 
					        this.tabsUpdate.updateNowIfNecessary();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    openNewTabEvent() {
 | 
					    openNewTabCommand() {
 | 
				
			||||||
        this.openAndActivateEmptyTab();
 | 
					        this.openAndActivateEmptyTab();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async removeAllTabsEvent() {
 | 
					    async removeAllTabsCommand() {
 | 
				
			||||||
        for (const tabIdToRemove of this.tabContexts.map(tc => tc.tabId)) {
 | 
					        for (const tabIdToRemove of this.tabContexts.map(tc => tc.tabId)) {
 | 
				
			||||||
            await this.removeTab(tabIdToRemove);
 | 
					            await this.removeTab(tabIdToRemove);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async removeAllTabsExceptForThisEvent({tabId}) {
 | 
					    async removeAllTabsExceptForThisCommand({tabId}) {
 | 
				
			||||||
        for (const tabIdToRemove of this.tabContexts.map(tc => tc.tabId)) {
 | 
					        for (const tabIdToRemove of this.tabContexts.map(tc => tc.tabId)) {
 | 
				
			||||||
            if (tabIdToRemove !== tabId) {
 | 
					            if (tabIdToRemove !== tabId) {
 | 
				
			||||||
                await this.removeTab(tabIdToRemove);
 | 
					                await this.removeTab(tabIdToRemove);
 | 
				
			||||||
 | 
				
			|||||||
@ -51,39 +51,39 @@ class TreeContextMenu {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        return [
 | 
					        return [
 | 
				
			||||||
            { title: 'Open in new tab', cmd: "openInTab", uiIcon: "empty", enabled: noSelectedNotes },
 | 
					            { title: 'Open in new tab', cmd: "openInTab", uiIcon: "empty", enabled: noSelectedNotes },
 | 
				
			||||||
            { title: 'Insert note after <kbd data-kb-action="createNoteAfter"></kbd>', cmd: "insertNoteAfter", uiIcon: "plus",
 | 
					            { title: 'Insert note after <kbd data-kb-command="createNoteAfter"></kbd>', cmd: "insertNoteAfter", uiIcon: "plus",
 | 
				
			||||||
                items: insertNoteAfterEnabled ? this.getNoteTypeItems("insertNoteAfter") : null,
 | 
					                items: insertNoteAfterEnabled ? this.getNoteTypeItems("insertNoteAfter") : null,
 | 
				
			||||||
                enabled: insertNoteAfterEnabled && noSelectedNotes },
 | 
					                enabled: insertNoteAfterEnabled && noSelectedNotes },
 | 
				
			||||||
            { title: 'Insert child note <kbd data-kb-action="createNoteInto"></kbd>', cmd: "insertChildNote", uiIcon: "plus",
 | 
					            { title: 'Insert child note <kbd data-kb-command="createNoteInto"></kbd>', cmd: "insertChildNote", uiIcon: "plus",
 | 
				
			||||||
                items: notSearch ? this.getNoteTypeItems("insertChildNote") : null,
 | 
					                items: notSearch ? this.getNoteTypeItems("insertChildNote") : null,
 | 
				
			||||||
                enabled: notSearch && noSelectedNotes },
 | 
					                enabled: notSearch && noSelectedNotes },
 | 
				
			||||||
            { title: 'Delete <kbd data-kb-action="deleteNotes"></kbd>', cmd: "delete", uiIcon: "trash",
 | 
					            { title: 'Delete <kbd data-kb-command="deleteNotes"></kbd>', cmd: "delete", uiIcon: "trash",
 | 
				
			||||||
                enabled: isNotRoot && !isHoisted && parentNotSearch },
 | 
					                enabled: isNotRoot && !isHoisted && parentNotSearch },
 | 
				
			||||||
            { title: "----" },
 | 
					            { title: "----" },
 | 
				
			||||||
            { title: 'Search in subtree <kbd data-kb-action="searchInSubtree"></kbd>', cmd: "searchInSubtree", uiIcon: "search",
 | 
					            { title: 'Search in subtree <kbd data-kb-command="searchInSubtree"></kbd>', cmd: "searchInSubtree", uiIcon: "search",
 | 
				
			||||||
                enabled: notSearch && noSelectedNotes },
 | 
					                enabled: notSearch && noSelectedNotes },
 | 
				
			||||||
            isHoisted ? null : { title: 'Hoist note <kbd data-kb-action="toggleNoteHoisting"></kbd>', cmd: "hoist", uiIcon: "empty", enabled: noSelectedNotes && notSearch },
 | 
					            isHoisted ? null : { title: 'Hoist note <kbd data-kb-command="toggleNoteHoisting"></kbd>', cmd: "hoist", uiIcon: "empty", enabled: noSelectedNotes && notSearch },
 | 
				
			||||||
            !isHoisted || !isNotRoot ? null : { title: 'Unhoist note <kbd data-kb-action="ToggleNoteHoisting"></kbd>', cmd: "unhoist", uiIcon: "arrow-up" },
 | 
					            !isHoisted || !isNotRoot ? null : { title: 'Unhoist note <kbd data-kb-command="ToggleNoteHoisting"></kbd>', cmd: "unhoist", uiIcon: "arrow-up" },
 | 
				
			||||||
            { title: 'Edit branch prefix <kbd data-kb-action="editBranchPrefix"></kbd>', cmd: "editBranchPrefix", uiIcon: "empty",
 | 
					            { title: 'Edit branch prefix <kbd data-kb-command="editBranchPrefix"></kbd>', cmd: "editBranchPrefix", uiIcon: "empty",
 | 
				
			||||||
                enabled: isNotRoot && parentNotSearch && noSelectedNotes},
 | 
					                enabled: isNotRoot && parentNotSearch && noSelectedNotes},
 | 
				
			||||||
            { title: "Advanced", uiIcon: "empty", enabled: true, items: [
 | 
					            { title: "Advanced", uiIcon: "empty", enabled: true, items: [
 | 
				
			||||||
                    { title: 'Collapse subtree <kbd data-kb-action="collapseSubtree"></kbd>', cmd: "collapseSubtree", uiIcon: "align-justify", enabled: noSelectedNotes },
 | 
					                    { title: 'Collapse subtree <kbd data-kb-command="collapseSubtree"></kbd>', cmd: "collapseSubtree", uiIcon: "align-justify", enabled: noSelectedNotes },
 | 
				
			||||||
                    { title: "Force note sync", cmd: "forceNoteSync", uiIcon: "refresh", enabled: noSelectedNotes },
 | 
					                    { title: "Force note sync", cmd: "forceNoteSync", uiIcon: "refresh", enabled: noSelectedNotes },
 | 
				
			||||||
                    { title: 'Sort alphabetically <kbd data-kb-action="sortChildNotes"></kbd>', cmd: "sortAlphabetically", uiIcon: "empty", enabled: noSelectedNotes && notSearch }
 | 
					                    { title: 'Sort alphabetically <kbd data-kb-command="sortChildNotes"></kbd>', cmd: "sortAlphabetically", uiIcon: "empty", enabled: noSelectedNotes && notSearch }
 | 
				
			||||||
                ] },
 | 
					                ] },
 | 
				
			||||||
            { title: "----" },
 | 
					            { title: "----" },
 | 
				
			||||||
            { title: "Protect subtree", cmd: "protectSubtree", uiIcon: "check-shield", enabled: noSelectedNotes },
 | 
					            { title: "Protect subtree", cmd: "protectSubtree", uiIcon: "check-shield", enabled: noSelectedNotes },
 | 
				
			||||||
            { title: "Unprotect subtree", cmd: "unprotectSubtree", uiIcon: "shield", enabled: noSelectedNotes },
 | 
					            { title: "Unprotect subtree", cmd: "unprotectSubtree", uiIcon: "shield", enabled: noSelectedNotes },
 | 
				
			||||||
            { title: "----" },
 | 
					            { title: "----" },
 | 
				
			||||||
            { title: 'Copy / clone <kbd data-kb-action="copyNotesToClipboard"></kbd>', cmd: "copy", uiIcon: "copy",
 | 
					            { title: 'Copy / clone <kbd data-kb-command="copyNotesToClipboard"></kbd>', cmd: "copy", uiIcon: "copy",
 | 
				
			||||||
                enabled: isNotRoot && !isHoisted },
 | 
					                enabled: isNotRoot && !isHoisted },
 | 
				
			||||||
            { title: 'Clone to ... <kbd data-kb-action="cloneNotesTo"></kbd>', cmd: "cloneTo", uiIcon: "empty",
 | 
					            { title: 'Clone to ... <kbd data-kb-command="cloneNotesTo"></kbd>', cmd: "cloneTo", uiIcon: "empty",
 | 
				
			||||||
                enabled: isNotRoot && !isHoisted },
 | 
					                enabled: isNotRoot && !isHoisted },
 | 
				
			||||||
            { title: 'Cut <kbd data-kb-action="cutNotesToClipboard"></kbd>', cmd: "cut", uiIcon: "cut",
 | 
					            { title: 'Cut <kbd data-kb-command="cutNotesToClipboard"></kbd>', cmd: "cut", uiIcon: "cut",
 | 
				
			||||||
                enabled: isNotRoot && !isHoisted && parentNotSearch },
 | 
					                enabled: isNotRoot && !isHoisted && parentNotSearch },
 | 
				
			||||||
            { title: 'Move to ... <kbd data-kb-action="moveNotesTo"></kbd>', cmd: "moveTo", uiIcon: "empty",
 | 
					            { title: 'Move to ... <kbd data-kb-command="moveNotesTo"></kbd>', cmd: "moveTo", uiIcon: "empty",
 | 
				
			||||||
                enabled: isNotRoot && !isHoisted && parentNotSearch },
 | 
					                enabled: isNotRoot && !isHoisted && parentNotSearch },
 | 
				
			||||||
            { title: 'Paste into <kbd data-kb-action="pasteNotesFromClipboard"></kbd>', cmd: "pasteInto", uiIcon: "paste",
 | 
					            { title: 'Paste into <kbd data-kb-command="pasteNotesFromClipboard"></kbd>', cmd: "pasteInto", uiIcon: "paste",
 | 
				
			||||||
                enabled: !clipboard.isClipboardEmpty() && notSearch && noSelectedNotes },
 | 
					                enabled: !clipboard.isClipboardEmpty() && notSearch && noSelectedNotes },
 | 
				
			||||||
            { title: 'Paste after', cmd: "pasteAfter", uiIcon: "paste",
 | 
					            { title: 'Paste after', cmd: "pasteAfter", uiIcon: "paste",
 | 
				
			||||||
                enabled: !clipboard.isClipboardEmpty() && isNotRoot && !isHoisted && parentNotSearch && noSelectedNotes },
 | 
					                enabled: !clipboard.isClipboardEmpty() && isNotRoot && !isHoisted && parentNotSearch && noSelectedNotes },
 | 
				
			||||||
 | 
				
			|||||||
@ -18,7 +18,7 @@ export default class Component {
 | 
				
			|||||||
    async handleEvent(name, data) {
 | 
					    async handleEvent(name, data) {
 | 
				
			||||||
        await this.initialized;
 | 
					        await this.initialized;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const fun = this[name + 'Listener'];
 | 
					        const fun = this[name + 'Event'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const start = Date.now();
 | 
					        const start = Date.now();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -48,15 +48,19 @@ export default class Component {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async triggerCommand(name, data = {}) {
 | 
					    async triggerCommand(name, data = {}) {
 | 
				
			||||||
        const fun = this[name + 'Command'];
 | 
					        const called = await this.handleCommand(name, data);
 | 
				
			||||||
 | 
					 | 
				
			||||||
        const called = await this.callMethod(fun, data);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!called) {
 | 
					        if (!called) {
 | 
				
			||||||
            await this.parent.triggerCommand(name, data);
 | 
					            await this.parent.triggerCommand(name, data);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async handleCommand(name, data) {
 | 
				
			||||||
 | 
					        const fun = this[name + 'Command'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return await this.callMethod(fun, data);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async callMethod(fun, data) {
 | 
					    async callMethod(fun, data) {
 | 
				
			||||||
        if (typeof fun !== 'function') {
 | 
					        if (typeof fun !== 'function') {
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
 | 
				
			|||||||
@ -19,17 +19,17 @@ const WIDGET_TPL = `
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    <a data-trigger-event="collapseTree"
 | 
					    <a data-trigger-event="collapseTree"
 | 
				
			||||||
       title="Collapse note tree" 
 | 
					       title="Collapse note tree" 
 | 
				
			||||||
       data-kb-action="collapseTree" 
 | 
					       data-kb-command="collapseTree" 
 | 
				
			||||||
       class="icon-action bx bx-layer-minus"></a>
 | 
					       class="icon-action bx bx-layer-minus"></a>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <a data-trigger-event="scrollToActiveNote"
 | 
					    <a data-trigger-event="scrollToActiveNote"
 | 
				
			||||||
       title="Scroll to active note" 
 | 
					       title="Scroll to active note" 
 | 
				
			||||||
       data-kb-action="scrollToActiveNote" 
 | 
					       data-kb-command="scrollToActiveNote" 
 | 
				
			||||||
       class="icon-action bx bx-crosshair"></a>
 | 
					       class="icon-action bx bx-crosshair"></a>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <a data-trigger-event="searchNotes"
 | 
					    <a data-trigger-event="searchNotes"
 | 
				
			||||||
       title="Search in notes"
 | 
					       title="Search in notes"
 | 
				
			||||||
       data-kb-action="searchNotes"
 | 
					       data-kb-command="searchNotes"
 | 
				
			||||||
       class="icon-action bx bx-search"></a>
 | 
					       class="icon-action bx bx-search"></a>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
`;
 | 
					`;
 | 
				
			||||||
 | 
				
			|||||||
@ -42,44 +42,44 @@ const TPL = `
 | 
				
			|||||||
            <a class="dropdown-item open-dev-tools-button" data-trigger-event="openDevTools">
 | 
					            <a class="dropdown-item open-dev-tools-button" data-trigger-event="openDevTools">
 | 
				
			||||||
                <span class="bx bx-terminal"></span>
 | 
					                <span class="bx bx-terminal"></span>
 | 
				
			||||||
                Open Dev Tools
 | 
					                Open Dev Tools
 | 
				
			||||||
                <kbd data-kb-action="openDevTools"></kbd>
 | 
					                <kbd data-kb-command="openDevTools"></kbd>
 | 
				
			||||||
            </a>
 | 
					            </a>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <a class="dropdown-item" data-trigger-event="showSQLConsole">
 | 
					            <a class="dropdown-item" data-trigger-event="showSQLConsole">
 | 
				
			||||||
                <span class="bx bx-data"></span>
 | 
					                <span class="bx bx-data"></span>
 | 
				
			||||||
                Open SQL Console
 | 
					                Open SQL Console
 | 
				
			||||||
                <kbd data-kb-action="showSQLConsole"></kbd>
 | 
					                <kbd data-kb-command="showSQLConsole"></kbd>
 | 
				
			||||||
            </a>
 | 
					            </a>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <a class="dropdown-item" data-trigger-event="showBackendLog">
 | 
					            <a class="dropdown-item" data-trigger-event="showBackendLog">
 | 
				
			||||||
                <span class="bx bx-empty"></span>
 | 
					                <span class="bx bx-empty"></span>
 | 
				
			||||||
                Show backend log
 | 
					                Show backend log
 | 
				
			||||||
                <kbd data-kb-action="showBackendLog"></kbd>
 | 
					                <kbd data-kb-command="showBackendLog"></kbd>
 | 
				
			||||||
            </a>
 | 
					            </a>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <a class="dropdown-item" data-trigger-event="reloadFrontendApp" 
 | 
					            <a class="dropdown-item" data-trigger-event="reloadFrontendApp" 
 | 
				
			||||||
                title="Reload can help with some visual glitches without restarting the whole app.">
 | 
					                title="Reload can help with some visual glitches without restarting the whole app.">
 | 
				
			||||||
                <span class="bx bx-empty"></span>
 | 
					                <span class="bx bx-empty"></span>
 | 
				
			||||||
                Reload frontend
 | 
					                Reload frontend
 | 
				
			||||||
                <kbd data-kb-action="reloadFrontendApp"></kbd>
 | 
					                <kbd data-kb-command="reloadFrontendApp"></kbd>
 | 
				
			||||||
            </a>
 | 
					            </a>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <a class="dropdown-item" data-trigger-event="toggleZenMode">
 | 
					            <a class="dropdown-item" data-trigger-event="toggleZenMode">
 | 
				
			||||||
                <span class="bx bx-empty"></span>
 | 
					                <span class="bx bx-empty"></span>
 | 
				
			||||||
                Toggle Zen mode
 | 
					                Toggle Zen mode
 | 
				
			||||||
                <kbd data-kb-action="toggleZenMode"></kbd>
 | 
					                <kbd data-kb-command="toggleZenMode"></kbd>
 | 
				
			||||||
            </a>
 | 
					            </a>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <a class="dropdown-item" data-trigger-event="toggleFullscreen">
 | 
					            <a class="dropdown-item" data-trigger-event="toggleFullscreen">
 | 
				
			||||||
                <span class="bx bx-empty"></span>
 | 
					                <span class="bx bx-empty"></span>
 | 
				
			||||||
                Toggle fullscreen
 | 
					                Toggle fullscreen
 | 
				
			||||||
                <kbd data-kb-action="toggleFullscreen"></kbd>
 | 
					                <kbd data-kb-command="toggleFullscreen"></kbd>
 | 
				
			||||||
            </a>
 | 
					            </a>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <a class="dropdown-item" data-trigger-event="showHelp">
 | 
					            <a class="dropdown-item" data-trigger-event="showHelp">
 | 
				
			||||||
                <span class="bx bx-info-circle"></span>
 | 
					                <span class="bx bx-info-circle"></span>
 | 
				
			||||||
                Show Help
 | 
					                Show Help
 | 
				
			||||||
                <kbd data-kb-action="showHelp"></kbd>
 | 
					                <kbd data-kb-command="showHelp"></kbd>
 | 
				
			||||||
            </a>
 | 
					            </a>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <a class="dropdown-item show-about-dialog-button">
 | 
					            <a class="dropdown-item show-about-dialog-button">
 | 
				
			||||||
 | 
				
			|||||||
@ -8,13 +8,13 @@ const TPL = `
 | 
				
			|||||||
    </button>
 | 
					    </button>
 | 
				
			||||||
    <div class="dropdown-menu dropdown-menu-right">
 | 
					    <div class="dropdown-menu dropdown-menu-right">
 | 
				
			||||||
        <a data-trigger-event="showNoteRevisions" class="dropdown-item show-note-revisions-button">Revisions</a>
 | 
					        <a data-trigger-event="showNoteRevisions" class="dropdown-item show-note-revisions-button">Revisions</a>
 | 
				
			||||||
        <a data-trigger-event="showAttributes" class="dropdown-item show-attributes-button"><kbd data-kb-action="showAttributes"></kbd> Attributes</a>
 | 
					        <a data-trigger-event="showAttributes" class="dropdown-item show-attributes-button"><kbd data-kb-command="showAttributes"></kbd> Attributes</a>
 | 
				
			||||||
        <a data-trigger-event="showLinkMap" class="dropdown-item show-link-map-button"><kbd data-kb-action="showLinkMap"></kbd> Link map</a>
 | 
					        <a data-trigger-event="showLinkMap" class="dropdown-item show-link-map-button"><kbd data-kb-command="showLinkMap"></kbd> Link map</a>
 | 
				
			||||||
        <a data-trigger-event="showNoteSource" class="dropdown-item show-source-button"><kbd data-kb-action="showNoteSource"></kbd> Note source</a>
 | 
					        <a data-trigger-event="showNoteSource" class="dropdown-item show-source-button"><kbd data-kb-command="showNoteSource"></kbd> Note source</a>
 | 
				
			||||||
        <a class="dropdown-item import-files-button">Import files</a>
 | 
					        <a class="dropdown-item import-files-button">Import files</a>
 | 
				
			||||||
        <a class="dropdown-item export-note-button">Export note</a>
 | 
					        <a class="dropdown-item export-note-button">Export note</a>
 | 
				
			||||||
        <a data-trigger-event="printActiveNote" class="dropdown-item print-note-button"><kbd data-kb-action="printActiveNote"></kbd> Print note</a>
 | 
					        <a data-trigger-event="printActiveNote" class="dropdown-item print-note-button"><kbd data-kb-command="printActiveNote"></kbd> Print note</a>
 | 
				
			||||||
        <a data-trigger-event="showNoteInfo" class="dropdown-item show-note-info-button"><kbd data-kb-action="showNoteInfo"></kbd> Note info</a>
 | 
					        <a data-trigger-event="showNoteInfo" class="dropdown-item show-note-info-button"><kbd data-kb-command="showNoteInfo"></kbd> Note info</a>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
</div>`;
 | 
					</div>`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -32,12 +32,12 @@ const TPL = `
 | 
				
			|||||||
    </style>
 | 
					    </style>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <div style="flex-grow: 100; display: flex;">
 | 
					    <div style="flex-grow: 100; display: flex;">
 | 
				
			||||||
        <button class="btn btn-sm jump-to-note-dialog-button" data-kb-action="jumpToNote">
 | 
					        <button class="btn btn-sm jump-to-note-dialog-button" data-kb-command="jumpToNote">
 | 
				
			||||||
            <span class="bx bx-crosshair"></span>
 | 
					            <span class="bx bx-crosshair"></span>
 | 
				
			||||||
            Jump to note
 | 
					            Jump to note
 | 
				
			||||||
        </button>
 | 
					        </button>
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
        <button class="btn btn-sm recent-changes-button" data-kb-action="showRecentChanges">
 | 
					        <button class="btn btn-sm recent-changes-button" data-kb-command="showRecentChanges">
 | 
				
			||||||
            <span class="bx bx-history"></span>
 | 
					            <span class="bx bx-history"></span>
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
            Recent changes
 | 
					            Recent changes
 | 
				
			||||||
 | 
				
			|||||||
@ -29,11 +29,11 @@ const TAB_TPL = `
 | 
				
			|||||||
  <div class="note-tab-wrapper">
 | 
					  <div class="note-tab-wrapper">
 | 
				
			||||||
    <div class="note-tab-title"></div>
 | 
					    <div class="note-tab-title"></div>
 | 
				
			||||||
    <div class="note-tab-drag-handle"></div>
 | 
					    <div class="note-tab-drag-handle"></div>
 | 
				
			||||||
    <div class="note-tab-close kb-in-title" title="Close tab" data-kb-action="closeActiveTab"><span>×</span></div>
 | 
					    <div class="note-tab-close kb-in-title" title="Close tab" data-kb-command="closeActiveTab"><span>×</span></div>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
</div>`;
 | 
					</div>`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const NEW_TAB_BUTTON_TPL = `<div class="note-new-tab kb-in-title" data-kb-action="openNewTab" title="Add new tab">+</div>`;
 | 
					const NEW_TAB_BUTTON_TPL = `<div class="note-new-tab kb-in-title" data-kb-command="openNewTab" title="Add new tab">+</div>`;
 | 
				
			||||||
const FILLER_TPL = `<div class="tab-row-filler">
 | 
					const FILLER_TPL = `<div class="tab-row-filler">
 | 
				
			||||||
    <div class="tab-row-border"></div>
 | 
					    <div class="tab-row-border"></div>
 | 
				
			||||||
</div>`;
 | 
					</div>`;
 | 
				
			||||||
@ -262,7 +262,7 @@ export default class TabRowWidget extends BasicWidget {
 | 
				
			|||||||
                    ];
 | 
					                    ];
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                selectContextMenuItem: (e, cmd) => {
 | 
					                selectContextMenuItem: (e, cmd) => {
 | 
				
			||||||
                    this.triggerEvent(cmd, {tabId});
 | 
					                    this.triggerCommand(cmd, {tabId});
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
@ -290,7 +290,7 @@ export default class TabRowWidget extends BasicWidget {
 | 
				
			|||||||
            window.addEventEvent('resize', resizeListener);
 | 
					            window.addEventEvent('resize', resizeListener);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.tabEls.forEach((tabEl) => this.setTabCloseEventEvent(tabEl));
 | 
					        this.tabEls.forEach((tabEl) => this.setTabCloseEvent(tabEl));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    setVisibility() {
 | 
					    setVisibility() {
 | 
				
			||||||
@ -386,14 +386,14 @@ export default class TabRowWidget extends BasicWidget {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        this.$newTab.before($tab);
 | 
					        this.$newTab.before($tab);
 | 
				
			||||||
        this.setVisibility();
 | 
					        this.setVisibility();
 | 
				
			||||||
        this.setTabCloseEventEvent($tab);
 | 
					        this.setTabCloseEvent($tab);
 | 
				
			||||||
        this.updateTitle($tab, 'New tab');
 | 
					        this.updateTitle($tab, 'New tab');
 | 
				
			||||||
        this.cleanUpPreviouslyDraggedTabs();
 | 
					        this.cleanUpPreviouslyDraggedTabs();
 | 
				
			||||||
        this.layoutTabs();
 | 
					        this.layoutTabs();
 | 
				
			||||||
        this.setupDraggabilly();
 | 
					        this.setupDraggabilly();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    setTabCloseEventEvent($tab) {
 | 
					    setTabCloseEvent($tab) {
 | 
				
			||||||
        $tab.find('.note-tab-close')
 | 
					        $tab.find('.note-tab-close')
 | 
				
			||||||
            .on('click', _ => appContext.tabManager.removeTab($tab.attr('data-tab-id')));
 | 
					            .on('click', _ => appContext.tabManager.removeTab($tab.attr('data-tab-id')));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -552,7 +552,7 @@ export default class TabRowWidget extends BasicWidget {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        this.$tabContainer.append(this.$newTab);
 | 
					        this.$tabContainer.append(this.$newTab);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.$newTab.on('click', _ => this.triggerEvent('openNewTab'));
 | 
					        this.$newTab.on('click', _ => this.triggerCommand('openNewTab'));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    setupFiller() {
 | 
					    setupFiller() {
 | 
				
			||||||
 | 
				
			|||||||
@ -18,12 +18,12 @@
 | 
				
			|||||||
                                <ul>
 | 
					                                <ul>
 | 
				
			||||||
                                    <li><kbd>UP</kbd>, <kbd>DOWN</kbd> - go up/down in the list of notes</li>
 | 
					                                    <li><kbd>UP</kbd>, <kbd>DOWN</kbd> - go up/down in the list of notes</li>
 | 
				
			||||||
                                    <li><kbd>LEFT</kbd>, <kbd>RIGHT</kbd> - collapse/expand node</li>
 | 
					                                    <li><kbd>LEFT</kbd>, <kbd>RIGHT</kbd> - collapse/expand node</li>
 | 
				
			||||||
                                    <li><kbd data-kb-action="backInNoteHistory"></kbd>, <kbd data-kb-action="BackInNoteHistory"></kbd> - go back / forwards in the history</li>
 | 
					                                    <li><kbd data-kb-command="backInNoteHistory"></kbd>, <kbd data-kb-command="BackInNoteHistory"></kbd> - go back / forwards in the history</li>
 | 
				
			||||||
                                    <li><kbd data-kb-action="jumpToNote"></kbd> - show <a class="external" href="https://github.com/zadam/trilium/wiki/Note-navigation#jump-to-note">"Jump to" dialog</a></li>
 | 
					                                    <li><kbd data-kb-command="jumpToNote"></kbd> - show <a class="external" href="https://github.com/zadam/trilium/wiki/Note-navigation#jump-to-note">"Jump to" dialog</a></li>
 | 
				
			||||||
                                    <li><kbd data-kb-action="scrollToActiveNote"></kbd> - scroll to active note</li>
 | 
					                                    <li><kbd data-kb-command="scrollToActiveNote"></kbd> - scroll to active note</li>
 | 
				
			||||||
                                    <li><kbd data-kb-action="activateParentNote"></kbd> - jumps to parent note</li>
 | 
					                                    <li><kbd data-kb-command="activateParentNote"></kbd> - jumps to parent note</li>
 | 
				
			||||||
                                    <li><kbd data-kb-action="collapseTree"></kbd> - collapse whole note tree</li>
 | 
					                                    <li><kbd data-kb-command="collapseTree"></kbd> - collapse whole note tree</li>
 | 
				
			||||||
                                    <li><kbd data-kb-action="collapseSubtree"></kbd> - collapse sub-tree</li>
 | 
					                                    <li><kbd data-kb-command="collapseSubtree"></kbd> - collapse sub-tree</li>
 | 
				
			||||||
                                </ul>
 | 
					                                </ul>
 | 
				
			||||||
                            </p>
 | 
					                            </p>
 | 
				
			||||||
                        </div>
 | 
					                        </div>
 | 
				
			||||||
@ -40,10 +40,10 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                            Only in desktop (electron build):
 | 
					                            Only in desktop (electron build):
 | 
				
			||||||
                            <ul>
 | 
					                            <ul>
 | 
				
			||||||
                                <li><kbd data-kb-action="openNewTab"></kbd> opens empty tab</li>
 | 
					                                <li><kbd data-kb-command="openNewTab"></kbd> opens empty tab</li>
 | 
				
			||||||
                                <li><kbd data-kb-action="closeActiveTab"></kbd> closes active tab</li>
 | 
					                                <li><kbd data-kb-command="closeActiveTab"></kbd> closes active tab</li>
 | 
				
			||||||
                                <li><kbd data-kb-action="activateNextTab"></kbd> activates next tab</li>
 | 
					                                <li><kbd data-kb-command="activateNextTab"></kbd> activates next tab</li>
 | 
				
			||||||
                                <li><kbd data-kb-action="activatePreviousTab"></kbd> activates previous tab</li>
 | 
					                                <li><kbd data-kb-command="activatePreviousTab"></kbd> activates previous tab</li>
 | 
				
			||||||
                            </ul>
 | 
					                            </ul>
 | 
				
			||||||
                            </p>
 | 
					                            </p>
 | 
				
			||||||
                        </div>
 | 
					                        </div>
 | 
				
			||||||
@ -55,9 +55,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                            <p class="card-text">
 | 
					                            <p class="card-text">
 | 
				
			||||||
                                <ul>
 | 
					                                <ul>
 | 
				
			||||||
                                    <li><kbd data-kb-action="createNoteAfter"></kbd> - creates new note after the active note</li>
 | 
					                                    <li><kbd data-kb-command="createNoteAfter"></kbd> - creates new note after the active note</li>
 | 
				
			||||||
                                    <li><kbd data-kb-action="createNoteInto"></kbd> - creates new sub-note into active note</li>
 | 
					                                    <li><kbd data-kb-command="createNoteInto"></kbd> - creates new sub-note into active note</li>
 | 
				
			||||||
                                    <li><kbd data-kb-action="editBranchPrefix"></kbd> - edit <a class="external" href="https://github.com/zadam/trilium/wiki/Tree concepts#prefix">prefix</a> of active note clone</li>
 | 
					                                    <li><kbd data-kb-command="editBranchPrefix"></kbd> - edit <a class="external" href="https://github.com/zadam/trilium/wiki/Tree concepts#prefix">prefix</a> of active note clone</li>
 | 
				
			||||||
                                </ul>
 | 
					                                </ul>
 | 
				
			||||||
                            </p>
 | 
					                            </p>
 | 
				
			||||||
                        </div>
 | 
					                        </div>
 | 
				
			||||||
@ -69,15 +69,15 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                            <p class="card-text">
 | 
					                            <p class="card-text">
 | 
				
			||||||
                                <ul>
 | 
					                                <ul>
 | 
				
			||||||
                                    <li><kbd data-kb-action="moveNoteUp"></kbd>, <kbd data-kb-action="MoveNoteDown"></kbd> - move note up/down in the note list</li>
 | 
					                                    <li><kbd data-kb-command="moveNoteUp"></kbd>, <kbd data-kb-command="MoveNoteDown"></kbd> - move note up/down in the note list</li>
 | 
				
			||||||
                                    <li><kbd data-kb-action="moveNoteUpInHierarchy"></kbd>, <kbd data-kb-action="MoveNoteDownInHierarchy"></kbd> - move note up in the hierarchy</li>
 | 
					                                    <li><kbd data-kb-command="moveNoteUpInHierarchy"></kbd>, <kbd data-kb-command="MoveNoteDownInHierarchy"></kbd> - move note up in the hierarchy</li>
 | 
				
			||||||
                                    <li><kbd data-kb-action="addNoteAboveToSelection"></kbd>, <kbd data-kb-action="AddNoteBelowToSelection"></kbd> - multi-select note above/below</li>
 | 
					                                    <li><kbd data-kb-command="addNoteAboveToSelection"></kbd>, <kbd data-kb-command="AddNoteBelowToSelection"></kbd> - multi-select note above/below</li>
 | 
				
			||||||
                                    <li><kbd data-kb-action="selectAllNotesInParent"></kbd> - select all notes in the current level</li>
 | 
					                                    <li><kbd data-kb-command="selectAllNotesInParent"></kbd> - select all notes in the current level</li>
 | 
				
			||||||
                                    <li><kbd>Shift+click</kbd> - select note</li>
 | 
					                                    <li><kbd>Shift+click</kbd> - select note</li>
 | 
				
			||||||
                                    <li><kbd data-kb-action="copyNotesToClipboard"></kbd> - copies active note (or current selection) into clipboard (used for <a class="external" href="https://github.com/zadam/trilium/wiki/Cloning notes">cloning</a>)</li>
 | 
					                                    <li><kbd data-kb-command="copyNotesToClipboard"></kbd> - copies active note (or current selection) into clipboard (used for <a class="external" href="https://github.com/zadam/trilium/wiki/Cloning notes">cloning</a>)</li>
 | 
				
			||||||
                                    <li><kbd data-kb-action="cutNotesToClipboard"></kbd> - cuts current (or current selection) note into clipboard (used for moving notes)</li>
 | 
					                                    <li><kbd data-kb-command="cutNotesToClipboard"></kbd> - cuts current (or current selection) note into clipboard (used for moving notes)</li>
 | 
				
			||||||
                                    <li><kbd data-kb-action="pasteNotesFromClipboard"></kbd> - pastes note(s) as sub-note into active note (which is either move or clone depending on whether it was copied or cut into clipboard)</li>
 | 
					                                    <li><kbd data-kb-command="pasteNotesFromClipboard"></kbd> - pastes note(s) as sub-note into active note (which is either move or clone depending on whether it was copied or cut into clipboard)</li>
 | 
				
			||||||
                                    <li><kbd data-kb-action="deleteNotes"></kbd> - delete note / sub-tree</li>
 | 
					                                    <li><kbd data-kb-command="deleteNotes"></kbd> - delete note / sub-tree</li>
 | 
				
			||||||
                                </ul>
 | 
					                                </ul>
 | 
				
			||||||
                            </p>
 | 
					                            </p>
 | 
				
			||||||
                        </div>
 | 
					                        </div>
 | 
				
			||||||
@ -89,12 +89,12 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                            <p class="card-text">
 | 
					                            <p class="card-text">
 | 
				
			||||||
                                <ul>
 | 
					                                <ul>
 | 
				
			||||||
                                    <li><kbd data-kb-action="editNoteTitle"></kbd> in tree pane switches from tree pane into note title. Enter from note title switches focus to text editor.
 | 
					                                    <li><kbd data-kb-command="editNoteTitle"></kbd> in tree pane switches from tree pane into note title. Enter from note title switches focus to text editor.
 | 
				
			||||||
                                        <kbd data-kb-action="scrollToActiveNote"></kbd> switches back from editor to tree pane.</li>
 | 
					                                        <kbd data-kb-command="scrollToActiveNote"></kbd> switches back from editor to tree pane.</li>
 | 
				
			||||||
                                    <li><kbd>Ctrl+K</kbd> - create / edit external link</li>
 | 
					                                    <li><kbd>Ctrl+K</kbd> - create / edit external link</li>
 | 
				
			||||||
                                    <li><kbd data-kb-action="addLinkToText"></kbd> - create internal link</li>
 | 
					                                    <li><kbd data-kb-command="addLinkToText"></kbd> - create internal link</li>
 | 
				
			||||||
                                    <li><kbd data-kb-action="insertDateTimeToText"></kbd> - inserts current date and time at caret position</li>
 | 
					                                    <li><kbd data-kb-command="insertDateTimeToText"></kbd> - inserts current date and time at caret position</li>
 | 
				
			||||||
                                    <li><kbd data-kb-action="scrollToActiveNote"></kbd> - jump away to the tree pane and scroll to active note</li>
 | 
					                                    <li><kbd data-kb-command="scrollToActiveNote"></kbd> - jump away to the tree pane and scroll to active note</li>
 | 
				
			||||||
                                </ul>
 | 
					                                </ul>
 | 
				
			||||||
                            </p>
 | 
					                            </p>
 | 
				
			||||||
                        </div>
 | 
					                        </div>
 | 
				
			||||||
@ -121,9 +121,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                            <p class="card-text">
 | 
					                            <p class="card-text">
 | 
				
			||||||
                                <ul>
 | 
					                                <ul>
 | 
				
			||||||
                                    <li><kbd data-kb-action="reloadFrontendApp"></kbd> - reloads Trilium frontend</li>
 | 
					                                    <li><kbd data-kb-command="reloadFrontendApp"></kbd> - reloads Trilium frontend</li>
 | 
				
			||||||
                                    <li><kbd data-kb-action="openDevTools"></kbd> - show developer tools</li>
 | 
					                                    <li><kbd data-kb-command="openDevTools"></kbd> - show developer tools</li>
 | 
				
			||||||
                                    <li><kbd data-kb-action="showSQLConsole"></kbd> - show SQL console</li>
 | 
					                                    <li><kbd data-kb-command="showSQLConsole"></kbd> - show SQL console</li>
 | 
				
			||||||
                                </ul>
 | 
					                                </ul>
 | 
				
			||||||
                            </p>
 | 
					                            </p>
 | 
				
			||||||
                        </div>
 | 
					                        </div>
 | 
				
			||||||
@ -135,10 +135,10 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                            <p class="card-text">
 | 
					                            <p class="card-text">
 | 
				
			||||||
                                <ul>
 | 
					                                <ul>
 | 
				
			||||||
                                    <li><kbd data-kb-action="toggleZenMode"></kbd> - Zen mode - display only note editor, everything else is hidden</li>
 | 
					                                    <li><kbd data-kb-command="toggleZenMode"></kbd> - Zen mode - display only note editor, everything else is hidden</li>
 | 
				
			||||||
                                    <li><kbd data-kb-action="searchNotes"></kbd> - toggle search form in tree pane</li>
 | 
					                                    <li><kbd data-kb-command="searchNotes"></kbd> - toggle search form in tree pane</li>
 | 
				
			||||||
                                    <li><kbd data-kb-action="findInText"></kbd> - in page search</li>
 | 
					                                    <li><kbd data-kb-command="findInText"></kbd> - in page search</li>
 | 
				
			||||||
                                    <li><kbd data-kb-action="showAttributes"></kbd> - show note attributes dialog</li>
 | 
					                                    <li><kbd data-kb-command="showAttributes"></kbd> - show note attributes dialog</li>
 | 
				
			||||||
                                </ul>
 | 
					                                </ul>
 | 
				
			||||||
                            </p>
 | 
					                            </p>
 | 
				
			||||||
                        </div>
 | 
					                        </div>
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user