mirror of
https://github.com/zadam/trilium.git
synced 2025-06-06 18:08:33 +02:00
converted tree_keybindings.js into proper commands
This commit is contained in:
parent
8ca9ad3497
commit
4330dc47a0
@ -123,5 +123,6 @@ export default {
|
|||||||
triggerAction,
|
triggerAction,
|
||||||
getAction,
|
getAction,
|
||||||
updateDisplayedShortcuts,
|
updateDisplayedShortcuts,
|
||||||
setupActionsForElement
|
setupActionsForElement,
|
||||||
|
getActionsForScope
|
||||||
};
|
};
|
@ -1,207 +0,0 @@
|
|||||||
import treeChangesService from "./branches.js";
|
|
||||||
import treeService from "./tree.js";
|
|
||||||
import hoistedNoteService from "./hoisted_note.js";
|
|
||||||
import clipboard from "./clipboard.js";
|
|
||||||
import utils from "./utils.js";
|
|
||||||
import keyboardActionService from "./keyboard_actions.js";
|
|
||||||
import appContext from "./app_context.js";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {NoteTreeWidget} treeWidget
|
|
||||||
*/
|
|
||||||
function getFixedKeyBindings(treeWidget) {
|
|
||||||
return {
|
|
||||||
// code below shouldn't be necessary normally, however there's some problem with interaction with context menu plugin
|
|
||||||
// after opening context menu, standard shortcuts don't work, but they are detected here
|
|
||||||
// so we essentially takeover the standard handling with our implementation.
|
|
||||||
"left": node => {
|
|
||||||
node.navigate($.ui.keyCode.LEFT, true).then(treeWidget.clearSelectedNodes);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
"right": node => {
|
|
||||||
node.navigate($.ui.keyCode.RIGHT, true).then(treeWidget.clearSelectedNodes);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
"up": node => {
|
|
||||||
node.navigate($.ui.keyCode.UP, true).then(treeWidget.clearSelectedNodes);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
"down": node => {
|
|
||||||
node.navigate($.ui.keyCode.DOWN, true).then(treeWidget.clearSelectedNodes);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {NoteTreeWidget} treeWidget
|
|
||||||
* @param {FancytreeNode} node
|
|
||||||
*/
|
|
||||||
function getSelectedOrActiveBranchIds(treeWidget, node) {
|
|
||||||
const nodes = treeWidget.getSelectedOrActiveNodes(node);
|
|
||||||
|
|
||||||
return nodes.map(node => node.data.branchId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {NoteTreeWidget} treeWidget
|
|
||||||
*/
|
|
||||||
function getTemplates(treeWidget) {
|
|
||||||
return {
|
|
||||||
"deleteNotes": node => {
|
|
||||||
const branchIds = getSelectedOrActiveBranchIds(treeWidget, node);
|
|
||||||
|
|
||||||
treeChangesService.deleteNotes(treeWidget, branchIds);
|
|
||||||
},
|
|
||||||
"moveNoteUp": node => {
|
|
||||||
const beforeNode = node.getPrevSibling();
|
|
||||||
|
|
||||||
if (beforeNode !== null) {
|
|
||||||
treeChangesService.moveBeforeBranch([node.data.branchId], beforeNode.data.branchId);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
"moveNoteDown": node => {
|
|
||||||
const afterNode = node.getNextSibling();
|
|
||||||
if (afterNode !== null) {
|
|
||||||
treeChangesService.moveAfterBranch([node.data.branchId], afterNode.data.branchId);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
"moveNoteUpInHierarchy": node => {
|
|
||||||
treeChangesService.moveNodeUpInHierarchy(node);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
"moveNoteDownInHierarchy": node => {
|
|
||||||
const toNode = node.getPrevSibling();
|
|
||||||
|
|
||||||
if (toNode !== null) {
|
|
||||||
treeChangesService.moveToParentNote([node.data.branchId], toNode.data.noteId);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
"addNoteAboveToSelection": () => {
|
|
||||||
const node = treeWidget.getFocusedNode();
|
|
||||||
|
|
||||||
if (!node) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (node.isActive()) {
|
|
||||||
node.setSelected(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
const prevSibling = node.getPrevSibling();
|
|
||||||
|
|
||||||
if (prevSibling) {
|
|
||||||
prevSibling.setActive(true, {noEvents: true});
|
|
||||||
|
|
||||||
if (prevSibling.isSelected()) {
|
|
||||||
node.setSelected(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
prevSibling.setSelected(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
"addNoteBelowToSelection": () => {
|
|
||||||
const node = treeWidget.getFocusedNode();
|
|
||||||
|
|
||||||
if (!node) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (node.isActive()) {
|
|
||||||
node.setSelected(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
const nextSibling = node.getNextSibling();
|
|
||||||
|
|
||||||
if (nextSibling) {
|
|
||||||
nextSibling.setActive(true, {noEvents: true});
|
|
||||||
|
|
||||||
if (nextSibling.isSelected()) {
|
|
||||||
node.setSelected(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
nextSibling.setSelected(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
"collapseSubtree": node => {
|
|
||||||
treeWidget.collapseTree(node);
|
|
||||||
},
|
|
||||||
"sortChildNotes": node => {
|
|
||||||
treeService.sortAlphabetically(node.data.noteId);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
"selectAllNotesInParent": node => {
|
|
||||||
for (const child of node.getParent().getChildren()) {
|
|
||||||
child.setSelected(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
"copyNotesToClipboard": node => {
|
|
||||||
clipboard.copy(getSelectedOrActiveBranchIds(treeWidget, node));
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
"cutNotesToClipboard": node => {
|
|
||||||
clipboard.cut(getSelectedOrActiveBranchIds(treeWidget, node));
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
"pasteNotesFromClipboard": node => {
|
|
||||||
clipboard.pasteInto(node.data.noteId);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
"editNoteTitle": node => {
|
|
||||||
appContext.triggerEvent('focusOnTitle');
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
"activateParentNote": node => {
|
|
||||||
if (!hoistedNoteService.isRootNode(node)) {
|
|
||||||
node.getParent().setActive().then(treeWidget.clearSelectedNodes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {NoteTreeWidget} treeWidget
|
|
||||||
*/
|
|
||||||
async function getKeyboardBindings(treeWidget) {
|
|
||||||
const bindings = Object.assign({}, getFixedKeyBindings(treeWidget));
|
|
||||||
|
|
||||||
const templates = getTemplates(treeWidget);
|
|
||||||
|
|
||||||
for (const actionName in templates) {
|
|
||||||
const action = await keyboardActionService.getAction(actionName);
|
|
||||||
|
|
||||||
for (const shortcut of action.effectiveShortcuts || []) {
|
|
||||||
const normalizedShortcut = utils.normalizeShortcut(shortcut);
|
|
||||||
|
|
||||||
bindings[normalizedShortcut] = templates[actionName];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return bindings;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
getKeyboardBindings
|
|
||||||
};
|
|
@ -91,7 +91,7 @@ export default class NoteDetailWidget extends TabAwareWidget {
|
|||||||
return this.tabContext && this.tabContext.isActive();
|
return this.tabContext && this.tabContext.isActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
async refresh() {console.log("REFRESH DETAIL");
|
async refresh() {
|
||||||
if (!this.isEnabled()) {
|
if (!this.isEnabled()) {
|
||||||
this.toggle(false);
|
this.toggle(false);
|
||||||
return;
|
return;
|
||||||
|
@ -72,7 +72,7 @@ export default class NoteTitleWidget extends TabAwareWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
focusAndSelectTitleEvent() {
|
focusAndSelectTitleCommand() {
|
||||||
if (this.tabContext && this.tabContext.isActive()) {
|
if (this.tabContext && this.tabContext.isActive()) {
|
||||||
this.$noteTitle
|
this.$noteTitle
|
||||||
.trigger('focus')
|
.trigger('focus')
|
||||||
|
@ -2,7 +2,6 @@ import hoistedNoteService from "../services/hoisted_note.js";
|
|||||||
import treeService from "../services/tree.js";
|
import treeService from "../services/tree.js";
|
||||||
import utils from "../services/utils.js";
|
import utils from "../services/utils.js";
|
||||||
import contextMenuWidget from "../services/context_menu.js";
|
import contextMenuWidget from "../services/context_menu.js";
|
||||||
import treeKeyBindingService from "../services/tree_keybindings.js";
|
|
||||||
import treeCache from "../services/tree_cache.js";
|
import treeCache from "../services/tree_cache.js";
|
||||||
import treeBuilder from "../services/tree_builder.js";
|
import treeBuilder from "../services/tree_builder.js";
|
||||||
import TreeContextMenu from "../services/tree_context_menu.js";
|
import TreeContextMenu from "../services/tree_context_menu.js";
|
||||||
@ -13,6 +12,8 @@ import server from "../services/server.js";
|
|||||||
import noteCreateService from "../services/note_create.js";
|
import noteCreateService from "../services/note_create.js";
|
||||||
import toastService from "../services/toast.js";
|
import toastService from "../services/toast.js";
|
||||||
import appContext from "../services/app_context.js";
|
import appContext from "../services/app_context.js";
|
||||||
|
import keyboardActionsService from "../services/keyboard_actions.js";
|
||||||
|
import clipboard from "../services/clipboard.js";
|
||||||
|
|
||||||
const TPL = `
|
const TPL = `
|
||||||
<div class="tree">
|
<div class="tree">
|
||||||
@ -29,7 +30,7 @@ const TPL = `
|
|||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export default class NoteTreeWidget extends TabAwareWidget {
|
export default class Notethis extends TabAwareWidget {
|
||||||
constructor(appContext, parent) {
|
constructor(appContext, parent) {
|
||||||
super(appContext, parent);
|
super(appContext, parent);
|
||||||
|
|
||||||
@ -112,7 +113,7 @@ export default class NoteTreeWidget extends TabAwareWidget {
|
|||||||
expand: (event, data) => this.setExpandedToServer(data.node.data.branchId, true),
|
expand: (event, data) => this.setExpandedToServer(data.node.data.branchId, true),
|
||||||
collapse: (event, data) => this.setExpandedToServer(data.node.data.branchId, false),
|
collapse: (event, data) => this.setExpandedToServer(data.node.data.branchId, false),
|
||||||
hotkeys: {
|
hotkeys: {
|
||||||
keydown: await treeKeyBindingService.getKeyboardBindings(this)
|
keydown: await this.getHotKeys()
|
||||||
},
|
},
|
||||||
dnd5: {
|
dnd5: {
|
||||||
autoExpandMS: 600,
|
autoExpandMS: 600,
|
||||||
@ -406,9 +407,9 @@ export default class NoteTreeWidget extends TabAwareWidget {
|
|||||||
await this.tree.reload(notes);
|
await this.tree.reload(notes);
|
||||||
}
|
}
|
||||||
|
|
||||||
createTopLevelNoteEvent() { noteCreateService.createNewTopLevelNote(); }
|
createTopLevelNoteCommand() { noteCreateService.createNewTopLevelNote(); }
|
||||||
|
|
||||||
collapseTreeEvent() { this.collapseTree(); }
|
collapseTreeCommand() { this.collapseTree(); }
|
||||||
|
|
||||||
isEnabled() {
|
isEnabled() {
|
||||||
return this.tabContext && this.tabContext.isActive();
|
return this.tabContext && this.tabContext.isActive();
|
||||||
@ -547,7 +548,7 @@ export default class NoteTreeWidget extends TabAwareWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async createNoteAfterEvent() {
|
async createNoteAfterCommand() {
|
||||||
const node = this.getActiveNode();
|
const node = this.getActiveNode();
|
||||||
const parentNoteId = node.data.parentNoteId;
|
const parentNoteId = node.data.parentNoteId;
|
||||||
const isProtected = await treeService.getParentProtectedStatus(node);
|
const isProtected = await treeService.getParentProtectedStatus(node);
|
||||||
@ -564,7 +565,7 @@ export default class NoteTreeWidget extends TabAwareWidget {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async createNoteIntoEvent() {
|
async createNoteIntoCommand() {
|
||||||
const node = this.getActiveNode();
|
const node = this.getActiveNode();
|
||||||
|
|
||||||
if (node) {
|
if (node) {
|
||||||
@ -629,4 +630,165 @@ export default class NoteTreeWidget extends TabAwareWidget {
|
|||||||
|
|
||||||
this.triggerCommand('moveBranchIdsTo', {branchIds: selectedOrActiveBranchIds});
|
this.triggerCommand('moveBranchIdsTo', {branchIds: selectedOrActiveBranchIds});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getHotKeys() {
|
||||||
|
const actions = await keyboardActionsService.getActionsForScope('note-tree');
|
||||||
|
const hotKeyMap = {
|
||||||
|
// code below shouldn't be necessary normally, however there's some problem with interaction with context menu plugin
|
||||||
|
// after opening context menu, standard shortcuts don't work, but they are detected here
|
||||||
|
// so we essentially takeover the standard handling with our implementation.
|
||||||
|
"left": node => {
|
||||||
|
node.navigate($.ui.keyCode.LEFT, true).then(this.clearSelectedNodes);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
"right": node => {
|
||||||
|
node.navigate($.ui.keyCode.RIGHT, true).then(this.clearSelectedNodes);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
"up": node => {
|
||||||
|
node.navigate($.ui.keyCode.UP, true).then(this.clearSelectedNodes);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
"down": node => {
|
||||||
|
node.navigate($.ui.keyCode.DOWN, true).then(this.clearSelectedNodes);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const action of actions) {
|
||||||
|
for (const shortcut of action.effectiveShortcuts) {
|
||||||
|
hotKeyMap[shortcut] = node => this.triggerCommand(action.actionName, {node});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {FancytreeNode} node
|
||||||
|
*/
|
||||||
|
getSelectedOrActiveBranchIds(node) {
|
||||||
|
const nodes = this.getSelectedOrActiveNodes(node);
|
||||||
|
|
||||||
|
return nodes.map(node => node.data.branchId);
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteNotesCommand({node}) {
|
||||||
|
const branchIds = this.getSelectedOrActiveBranchIds(node);
|
||||||
|
|
||||||
|
treeChangesService.deleteNotes(this, branchIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
moveNoteUpCommand({node}) {
|
||||||
|
const beforeNode = node.getPrevSibling();
|
||||||
|
|
||||||
|
if (beforeNode !== null) {
|
||||||
|
treeChangesService.moveBeforeBranch([node.data.branchId], beforeNode.data.branchId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
moveNoteDownCommand({node}) {
|
||||||
|
const afterNode = node.getNextSibling();
|
||||||
|
if (afterNode !== null) {
|
||||||
|
treeChangesService.moveAfterBranch([node.data.branchId], afterNode.data.branchId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
moveNoteUpInHierarchyCommand({node}) {
|
||||||
|
treeChangesService.moveNodeUpInHierarchy(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
moveNoteDownInHierarchyCommand({node}) {
|
||||||
|
const toNode = node.getPrevSibling();
|
||||||
|
|
||||||
|
if (toNode !== null) {
|
||||||
|
treeChangesService.moveToParentNote([node.data.branchId], toNode.data.noteId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addNoteAboveToSelectionCommand() {
|
||||||
|
const node = this.getFocusedNode();
|
||||||
|
|
||||||
|
if (!node) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node.isActive()) {
|
||||||
|
node.setSelected(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
const prevSibling = node.getPrevSibling();
|
||||||
|
|
||||||
|
if (prevSibling) {
|
||||||
|
prevSibling.setActive(true, {noEvents: true});
|
||||||
|
|
||||||
|
if (prevSibling.isSelected()) {
|
||||||
|
node.setSelected(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
prevSibling.setSelected(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addNoteBelowToSelectionCommand() {
|
||||||
|
const node = this.getFocusedNode();
|
||||||
|
|
||||||
|
if (!node) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node.isActive()) {
|
||||||
|
node.setSelected(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
const nextSibling = node.getNextSibling();
|
||||||
|
|
||||||
|
if (nextSibling) {
|
||||||
|
nextSibling.setActive(true, {noEvents: true});
|
||||||
|
|
||||||
|
if (nextSibling.isSelected()) {
|
||||||
|
node.setSelected(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
nextSibling.setSelected(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
collapseSubtreeCommand({node}) {
|
||||||
|
this.collapseTree(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
sortChildNotesCommand({node}) {
|
||||||
|
treeService.sortAlphabetically(node.data.noteId);
|
||||||
|
}
|
||||||
|
|
||||||
|
selectAllNotesInParentCommand({node}) {
|
||||||
|
for (const child of node.getParent().getChildren()) {
|
||||||
|
child.setSelected(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
copyNotesToClipboardCommand({node}) {
|
||||||
|
clipboard.copy(this.getSelectedOrActiveBranchIds(node));
|
||||||
|
}
|
||||||
|
|
||||||
|
cutNotesToClipboardCommand({node}) {
|
||||||
|
clipboard.cut(this.getSelectedOrActiveBranchIds(node));
|
||||||
|
}
|
||||||
|
|
||||||
|
pasteNotesFromClipboardCommand({node}) {
|
||||||
|
clipboard.pasteInto(node.data.noteId);
|
||||||
|
}
|
||||||
|
|
||||||
|
editNoteTitleCommand({node}) {
|
||||||
|
appContext.triggerEvent('focusOnTitle');
|
||||||
|
}
|
||||||
|
|
||||||
|
activateParentNoteCommand({node}) {
|
||||||
|
if (!hoistedNoteService.isRootNode(node)) {
|
||||||
|
node.getParent().setActive().then(this.clearSelectedNodes);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -130,8 +130,9 @@ export default class NoteTypeWidget extends TabAwareWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async confirmChangeIfContent() {
|
async confirmChangeIfContent() {
|
||||||
// FIXME
|
const noteComplement = await this.tabContext.getNoteComplement();
|
||||||
if (!this.tabContext.getComponent().getContent()) {
|
|
||||||
|
if (!noteComplement.content || !noteComplement.content.trim().length) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,7 +159,7 @@ export default class SearchBoxWidget extends BasicWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
searchNotesEvent() {
|
searchNotesCommand() {
|
||||||
this.toggleSearchEvent();
|
this.toggleSearchEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,7 +167,7 @@ export default class SearchBoxWidget extends BasicWidget {
|
|||||||
this.$searchInput.val("");
|
this.$searchInput.val("");
|
||||||
}
|
}
|
||||||
|
|
||||||
searchInSubtreeEvent({noteId}) {
|
searchInSubtreeCommand({noteId}) {
|
||||||
noteId = noteId || appContext.tabManager.getActiveTabNoteId();
|
noteId = noteId || appContext.tabManager.getActiveTabNoteId();
|
||||||
|
|
||||||
this.toggle(true);
|
this.toggle(true);
|
||||||
|
@ -248,6 +248,7 @@ function BackendScriptApi(currentNote, apiParams) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @method
|
* @method
|
||||||
|
* @deprecated please use createNote() API method instead
|
||||||
*
|
*
|
||||||
* @param {string} parentNoteId - create new note under this parent
|
* @param {string} parentNoteId - create new note under this parent
|
||||||
* @param {string} title
|
* @param {string} title
|
||||||
|
Loading…
x
Reference in New Issue
Block a user