mirror of
https://github.com/zadam/trilium.git
synced 2025-01-31 03:19:11 +08:00
note launchers by default open in the active note context but follow the same logic with ctrl/middle click as links
This commit is contained in:
parent
dfb462cf35
commit
5ac332960e
6 changed files with 80 additions and 19 deletions
|
@ -90,27 +90,27 @@ function getNotePathFromLink($link) {
|
|||
return url ? getNotePathFromUrl(url) : null;
|
||||
}
|
||||
|
||||
function goToLink(e) {
|
||||
const $link = $(e.target).closest("a,.block-link");
|
||||
function goToLink(evt) {
|
||||
const $link = $(evt.target).closest("a,.block-link");
|
||||
const address = $link.attr('href');
|
||||
|
||||
if (address?.startsWith("data:")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
evt.preventDefault();
|
||||
evt.stopPropagation();
|
||||
|
||||
const notePath = getNotePathFromLink($link);
|
||||
|
||||
const ctrlKey = (!utils.isMac() && e.ctrlKey) || (utils.isMac() && e.metaKey);
|
||||
const ctrlKey = utils.isCtrlKey(evt);
|
||||
|
||||
if (notePath) {
|
||||
if ((e.which === 1 && ctrlKey) || e.which === 2) {
|
||||
if ((evt.which === 1 && ctrlKey) || evt.which === 2) {
|
||||
appContext.tabManager.openTabWithNoteWithHoisting(notePath);
|
||||
}
|
||||
else if (e.which === 1) {
|
||||
const ntxId = $(e.target).closest("[data-ntx-id]").attr("data-ntx-id");
|
||||
else if (evt.which === 1) {
|
||||
const ntxId = $(evt.target).closest("[data-ntx-id]").attr("data-ntx-id");
|
||||
|
||||
const noteContext = ntxId
|
||||
? appContext.tabManager.getNoteContextById(ntxId)
|
||||
|
@ -124,7 +124,7 @@ function goToLink(e) {
|
|||
}
|
||||
}
|
||||
else {
|
||||
if ((e.which === 1 && ctrlKey) || e.which === 2
|
||||
if ((evt.which === 1 && ctrlKey) || evt.which === 2
|
||||
|| $link.hasClass("ck-link-actions__preview") // within edit link dialog single click suffices
|
||||
|| $link.closest("[contenteditable]").length === 0 // outside of CKEditor single click suffices
|
||||
) {
|
||||
|
|
|
@ -60,6 +60,11 @@ function isMac() {
|
|||
return navigator.platform.indexOf('Mac') > -1;
|
||||
}
|
||||
|
||||
function isCtrlKey(evt) {
|
||||
return (!isMac() && evt.ctrlKey)
|
||||
|| (isMac() && evt.metaKey);
|
||||
}
|
||||
|
||||
function assertArguments() {
|
||||
for (const i in arguments) {
|
||||
if (!arguments[i]) {
|
||||
|
@ -362,6 +367,7 @@ export default {
|
|||
now,
|
||||
isElectron,
|
||||
isMac,
|
||||
isCtrlKey,
|
||||
assertArguments,
|
||||
escapeHtml,
|
||||
stopWatch,
|
||||
|
|
|
@ -1,23 +1,55 @@
|
|||
import AbstractLauncher from "./abstract_launcher.js";
|
||||
import dialogService from "../../../services/dialog.js";
|
||||
import appContext from "../../../components/app_context.js";
|
||||
import utils from "../../../services/utils.js";
|
||||
import linkContextMenuService from "../../../menus/link_context_menu.js";
|
||||
|
||||
// we're intentionally displaying the launcher title and icon instead of the target
|
||||
// e.g. you want to make launchers to 2 mermaid diagrams which both have mermaid icon (ok),
|
||||
// but on the launchpad you want them distinguishable.
|
||||
// for titles, the note titles may follow a different scheme than maybe desirable on the launchpad
|
||||
// another reason is the discrepancy between what user sees on the launchpad and in the config (esp. icons).
|
||||
// The only downside is more work in setting up the typical case
|
||||
// where you actually want to have both title and icon in sync, but for those cases there are bookmarks
|
||||
export default class NoteLauncher extends AbstractLauncher {
|
||||
constructor(launcherNote) {
|
||||
super(launcherNote);
|
||||
|
||||
this.title(this.launcherNote.title)
|
||||
.icon(this.launcherNote.getIcon())
|
||||
.onClick(() => this.launch());
|
||||
.onClick((widget, evt) => this.launch(evt))
|
||||
.onAuxClick((widget, evt) => this.launch(evt))
|
||||
.onContextMenu(evt => {
|
||||
const targetNoteId = this.getTargetNoteId();
|
||||
if (!targetNoteId) {
|
||||
return;
|
||||
}
|
||||
|
||||
linkContextMenuService.openContextMenu(targetNoteId, evt);
|
||||
});
|
||||
}
|
||||
|
||||
launch() {
|
||||
// we're intentionally displaying the launcher title and icon instead of the target
|
||||
// e.g. you want to make launchers to 2 mermaid diagrams which both have mermaid icon (ok),
|
||||
// but on the launchpad you want them distinguishable.
|
||||
// for titles, the note titles may follow a different scheme than maybe desirable on the launchpad
|
||||
// another reason is the discrepancy between what user sees on the launchpad and in the config (esp. icons).
|
||||
// The only (but major) downside is more work in setting up the typical case where you actually want to have both title and icon in sync.
|
||||
launch(evt) {
|
||||
const targetNoteId = this.getTargetNoteId();
|
||||
if (!targetNoteId) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!evt) {
|
||||
// keyboard shortcut
|
||||
appContext.tabManager.getActiveContext().setNote(targetNoteId)
|
||||
return;
|
||||
}
|
||||
|
||||
const ctrlKey = utils.isCtrlKey(evt);
|
||||
if ((evt.which === 1 && ctrlKey) || evt.which === 2) {
|
||||
appContext.tabManager.openTabWithNoteWithHoisting(targetNoteId);
|
||||
} else {
|
||||
appContext.tabManager.getActiveContext().setNote(targetNoteId);
|
||||
}
|
||||
}
|
||||
|
||||
getTargetNoteId() {
|
||||
const targetNoteId = this.launcherNote.getRelationValue('targetNote');
|
||||
|
||||
if (!targetNoteId) {
|
||||
|
@ -25,7 +57,7 @@ export default class NoteLauncher extends AbstractLauncher {
|
|||
return;
|
||||
}
|
||||
|
||||
appContext.tabManager.openTabWithNoteWithHoisting(targetNoteId, true);
|
||||
return targetNoteId;
|
||||
}
|
||||
|
||||
getTitle() {
|
||||
|
|
|
@ -13,10 +13,23 @@ export default class OnClickButtonWidget extends AbstractButtonWidget {
|
|||
} else {
|
||||
console.warn(`Button widget '${this.componentId}' has no defined click handler`, this.settings);
|
||||
}
|
||||
|
||||
if (this.settings.onAuxClick) {
|
||||
this.$widget.on("auxclick", e => {
|
||||
this.$widget.tooltip("hide");
|
||||
|
||||
this.settings.onAuxClick(this, e);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
onClick(handler) {
|
||||
this.settings.onClick = handler;
|
||||
return this;
|
||||
}
|
||||
|
||||
onAuxClick(handler) {
|
||||
this.settings.onAuxClick = handler;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,6 +56,12 @@ const HIDDEN_SUBTREE_DEFINITION = {
|
|||
title: 'Bulk action',
|
||||
type: 'doc',
|
||||
},
|
||||
{
|
||||
// place for user scripts hidden stuff (scripts should not create notes directly under hidden root)
|
||||
id: 'userHidden',
|
||||
title: 'User Hidden',
|
||||
type: 'text',
|
||||
},
|
||||
{
|
||||
id: LBTPL_ROOT,
|
||||
title: 'Launch Bar Templates',
|
||||
|
|
|
@ -111,7 +111,11 @@ function getAndValidateParent(params) {
|
|||
throw new ValidationError(`Parent note "${params.parentNoteId}" not found.`);
|
||||
}
|
||||
|
||||
if (!params.ignoreForbiddenParents && (parentNote.isLaunchBarConfig() || parentNote.isOptions())) {
|
||||
if (parentNote.type === 'launcher' && parentNote.noteId !== 'lbBookmarks') {
|
||||
throw new ValidationError(`Creating child notes into launcher notes is not allowed.`);
|
||||
}
|
||||
|
||||
if (!params.ignoreForbiddenParents && (['lbRoot', 'hidden'].includes(parentNote.noteId) || parentNote.isOptions())) {
|
||||
throw new ValidationError(`Creating child notes into '${parentNote.noteId}' is not allowed.`);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue