mirror of
https://github.com/zadam/trilium.git
synced 2025-06-06 18:08:33 +02: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
@ -90,27 +90,27 @@ function getNotePathFromLink($link) {
|
|||||||
return url ? getNotePathFromUrl(url) : null;
|
return url ? getNotePathFromUrl(url) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function goToLink(e) {
|
function goToLink(evt) {
|
||||||
const $link = $(e.target).closest("a,.block-link");
|
const $link = $(evt.target).closest("a,.block-link");
|
||||||
const address = $link.attr('href');
|
const address = $link.attr('href');
|
||||||
|
|
||||||
if (address?.startsWith("data:")) {
|
if (address?.startsWith("data:")) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
e.preventDefault();
|
evt.preventDefault();
|
||||||
e.stopPropagation();
|
evt.stopPropagation();
|
||||||
|
|
||||||
const notePath = getNotePathFromLink($link);
|
const notePath = getNotePathFromLink($link);
|
||||||
|
|
||||||
const ctrlKey = (!utils.isMac() && e.ctrlKey) || (utils.isMac() && e.metaKey);
|
const ctrlKey = utils.isCtrlKey(evt);
|
||||||
|
|
||||||
if (notePath) {
|
if (notePath) {
|
||||||
if ((e.which === 1 && ctrlKey) || e.which === 2) {
|
if ((evt.which === 1 && ctrlKey) || evt.which === 2) {
|
||||||
appContext.tabManager.openTabWithNoteWithHoisting(notePath);
|
appContext.tabManager.openTabWithNoteWithHoisting(notePath);
|
||||||
}
|
}
|
||||||
else if (e.which === 1) {
|
else if (evt.which === 1) {
|
||||||
const ntxId = $(e.target).closest("[data-ntx-id]").attr("data-ntx-id");
|
const ntxId = $(evt.target).closest("[data-ntx-id]").attr("data-ntx-id");
|
||||||
|
|
||||||
const noteContext = ntxId
|
const noteContext = ntxId
|
||||||
? appContext.tabManager.getNoteContextById(ntxId)
|
? appContext.tabManager.getNoteContextById(ntxId)
|
||||||
@ -124,7 +124,7 @@ function goToLink(e) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
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.hasClass("ck-link-actions__preview") // within edit link dialog single click suffices
|
||||||
|| $link.closest("[contenteditable]").length === 0 // outside of CKEditor 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;
|
return navigator.platform.indexOf('Mac') > -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isCtrlKey(evt) {
|
||||||
|
return (!isMac() && evt.ctrlKey)
|
||||||
|
|| (isMac() && evt.metaKey);
|
||||||
|
}
|
||||||
|
|
||||||
function assertArguments() {
|
function assertArguments() {
|
||||||
for (const i in arguments) {
|
for (const i in arguments) {
|
||||||
if (!arguments[i]) {
|
if (!arguments[i]) {
|
||||||
@ -362,6 +367,7 @@ export default {
|
|||||||
now,
|
now,
|
||||||
isElectron,
|
isElectron,
|
||||||
isMac,
|
isMac,
|
||||||
|
isCtrlKey,
|
||||||
assertArguments,
|
assertArguments,
|
||||||
escapeHtml,
|
escapeHtml,
|
||||||
stopWatch,
|
stopWatch,
|
||||||
|
@ -1,23 +1,55 @@
|
|||||||
import AbstractLauncher from "./abstract_launcher.js";
|
import AbstractLauncher from "./abstract_launcher.js";
|
||||||
import dialogService from "../../../services/dialog.js";
|
import dialogService from "../../../services/dialog.js";
|
||||||
import appContext from "../../../components/app_context.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 {
|
export default class NoteLauncher extends AbstractLauncher {
|
||||||
constructor(launcherNote) {
|
constructor(launcherNote) {
|
||||||
super(launcherNote);
|
super(launcherNote);
|
||||||
|
|
||||||
this.title(this.launcherNote.title)
|
this.title(this.launcherNote.title)
|
||||||
.icon(this.launcherNote.getIcon())
|
.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;
|
||||||
}
|
}
|
||||||
|
|
||||||
launch() {
|
linkContextMenuService.openContextMenu(targetNoteId, evt);
|
||||||
// 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
|
launch(evt) {
|
||||||
// another reason is the discrepancy between what user sees on the launchpad and in the config (esp. icons).
|
const targetNoteId = this.getTargetNoteId();
|
||||||
// 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.
|
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');
|
const targetNoteId = this.launcherNote.getRelationValue('targetNote');
|
||||||
|
|
||||||
if (!targetNoteId) {
|
if (!targetNoteId) {
|
||||||
@ -25,7 +57,7 @@ export default class NoteLauncher extends AbstractLauncher {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
appContext.tabManager.openTabWithNoteWithHoisting(targetNoteId, true);
|
return targetNoteId;
|
||||||
}
|
}
|
||||||
|
|
||||||
getTitle() {
|
getTitle() {
|
||||||
|
@ -13,10 +13,23 @@ export default class OnClickButtonWidget extends AbstractButtonWidget {
|
|||||||
} else {
|
} else {
|
||||||
console.warn(`Button widget '${this.componentId}' has no defined click handler`, this.settings);
|
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) {
|
onClick(handler) {
|
||||||
this.settings.onClick = handler;
|
this.settings.onClick = handler;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onAuxClick(handler) {
|
||||||
|
this.settings.onAuxClick = handler;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,12 @@ const HIDDEN_SUBTREE_DEFINITION = {
|
|||||||
title: 'Bulk action',
|
title: 'Bulk action',
|
||||||
type: 'doc',
|
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,
|
id: LBTPL_ROOT,
|
||||||
title: 'Launch Bar Templates',
|
title: 'Launch Bar Templates',
|
||||||
|
@ -111,7 +111,11 @@ function getAndValidateParent(params) {
|
|||||||
throw new ValidationError(`Parent note "${params.parentNoteId}" not found.`);
|
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.`);
|
throw new ValidationError(`Creating child notes into '${parentNote.noteId}' is not allowed.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user