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:
zadam 2022-12-09 16:48:00 +01:00
parent dfb462cf35
commit 5ac332960e
6 changed files with 80 additions and 19 deletions

View file

@ -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
) {

View file

@ -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,

View file

@ -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() {

View file

@ -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;
}
}

View file

@ -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',

View file

@ -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.`);
}