shortcuts use templates

This commit is contained in:
zadam 2022-11-28 23:39:23 +01:00
parent a459230aa9
commit eecfce3cc9
8 changed files with 198 additions and 97 deletions

View File

@ -22,7 +22,7 @@ const NOTE_TYPE_ICONS = {
"canvas": "bx bx-pen", "canvas": "bx bx-pen",
"web-view": "bx bx-globe-alt", "web-view": "bx bx-globe-alt",
"shortcut": "bx bx-up-arrow-circle", "shortcut": "bx bx-up-arrow-circle",
"doc": "bx bx-file-doc" "doc": "bx bxs-file-doc"
}; };
/** /**

View File

@ -55,7 +55,7 @@ async function createNoteLink(noteId) {
} }
return $("<a>", { return $("<a>", {
href: '#' + noteId, href: '#root/' + noteId,
class: 'reference-link', class: 'reference-link',
'data-note-path': noteId 'data-note-path': noteId
}) })

View File

@ -5,7 +5,7 @@ import froca from "./froca.js";
import utils from "./utils.js"; import utils from "./utils.js";
function getNotePathFromUrl(url) { function getNotePathFromUrl(url) {
const notePathMatch = /#(root[A-Za-z0-9/]*)$/.exec(url); const notePathMatch = /#(root[A-Za-z0-9_/]*)$/.exec(url);
return notePathMatch === null ? null : notePathMatch[1]; return notePathMatch === null ? null : notePathMatch[1];
} }

View File

@ -333,7 +333,7 @@ export default class AttributeEditorWidget extends NoteContextAwareWidget {
getPreprocessedData() { getPreprocessedData() {
const str = this.textEditor.getData() const str = this.textEditor.getData()
.replace(/<a[^>]+href="(#[A-Za-z0-9/]*)"[^>]*>[^<]*<\/a>/g, "$1") .replace(/<a[^>]+href="(#[A-Za-z0-9_/]*)"[^>]*>[^<]*<\/a>/g, "$1")
.replace(/&nbsp;/g, " "); // otherwise .text() below outputs non-breaking space in unicode .replace(/&nbsp;/g, " "); // otherwise .text() below outputs non-breaking space in unicode
return $("<div>").html(str).text(); return $("<div>").html(str).text();

View File

@ -32,15 +32,10 @@ export default class ShortcutContainer extends FlexContainer {
return; return;
} }
for (const shortcut of await visibleShortcutsRoot.getChildNotes()) { await Promise.allSettled(
try { (await visibleShortcutsRoot.getChildNotes())
await this.initShortcut(shortcut); .map(shortcut => this.initShortcut(shortcut))
} );
catch (e) {
console.error(`Initialization of shortcut '${shortcut.noteId}' with title '${shortcut.title}' failed with error: ${e.message} ${e.stack}`);
continue;
}
}
this.$widget.empty(); this.$widget.empty();
this.renderChildren(); this.renderChildren();
@ -49,16 +44,22 @@ export default class ShortcutContainer extends FlexContainer {
const activeContext = appContext.tabManager.getActiveContext(); const activeContext = appContext.tabManager.getActiveContext();
if (activeContext) {
await this.handleEvent('setNoteContext', { await this.handleEvent('setNoteContext', {
noteContext: activeContext noteContext: activeContext
}); });
if (activeContext.notePath) {
await this.handleEvent('noteSwitched', { await this.handleEvent('noteSwitched', {
noteContext: activeContext, noteContext: activeContext,
notePath: activeContext.notePath notePath: activeContext.notePath
}); });
} }
}
}
async initShortcut(shortcut) { async initShortcut(shortcut) {
try {
if (shortcut.type !== 'shortcut') { if (shortcut.type !== 'shortcut') {
console.warn(`Note ${shortcut.noteId} is not a shortcut even though it's in shortcut subtree`); console.warn(`Note ${shortcut.noteId} is not a shortcut even though it's in shortcut subtree`);
return; return;
@ -121,6 +122,10 @@ export default class ShortcutContainer extends FlexContainer {
} }
} }
} }
catch (e) {
console.error(`Initialization of shortcut '${shortcut.noteId}' with title '${shortcut.title}' failed with error: ${e.message} ${e.stack}`);
}
}
entitiesReloadedEvent({loadResults}) { entitiesReloadedEvent({loadResults}) {
if (loadResults.getNoteIds().find(noteId => froca.notes[noteId]?.isLaunchBarConfig()) if (loadResults.getNoteIds().find(noteId => froca.notes[noteId]?.isLaunchBarConfig())

View File

@ -41,7 +41,7 @@ export default class AbstractTextTypeWidget extends TypeWidget {
} }
getNoteIdFromImage(imgSrc) { getNoteIdFromImage(imgSrc) {
const match = imgSrc.match(/\/api\/images\/([A-Za-z0-9]+)\//); const match = imgSrc.match(/\/api\/images\/([A-Za-z0-9_]+)\//);
return match ? match[1] : null; return match ? match[1] : null;
} }

View File

@ -114,7 +114,7 @@ function getAndValidateParent(params) {
throw new Error(`Shortcuts should not have child notes.`); throw new Error(`Shortcuts should not have child notes.`);
} }
if (['hidden', 'lb_root'].includes(parentNote.noteId)) { if (!params.ignoreForbiddenParents && ['lb_root'].includes(parentNote.noteId)) {
throw new Error(`Creating child notes into '${parentNote.noteId}' is not allowed.`); throw new Error(`Creating child notes into '${parentNote.noteId}' is not allowed.`);
} }
@ -300,7 +300,7 @@ function protectNote(note, protect) {
} }
function findImageLinks(content, foundLinks) { function findImageLinks(content, foundLinks) {
const re = /src="[^"]*api\/images\/([a-zA-Z0-9]+)\//g; const re = /src="[^"]*api\/images\/([a-zA-Z0-9_]+)\//g;
let match; let match;
while (match = re.exec(content)) { while (match = re.exec(content)) {
@ -316,7 +316,7 @@ function findImageLinks(content, foundLinks) {
} }
function findInternalLinks(content, foundLinks) { function findInternalLinks(content, foundLinks) {
const re = /href="[^"]*#root[a-zA-Z0-9\/]*\/([a-zA-Z0-9]+)\/?"/g; const re = /href="[^"]*#root[a-zA-Z0-9_\/]*\/([a-zA-Z0-9_]+)\/?"/g;
let match; let match;
while (match = re.exec(content)) { while (match = re.exec(content)) {
@ -331,7 +331,7 @@ function findInternalLinks(content, foundLinks) {
} }
function findIncludeNoteLinks(content, foundLinks) { function findIncludeNoteLinks(content, foundLinks) {
const re = /<section class="include-note[^>]+data-note-id="([a-zA-Z0-9]+)"[^>]*>/g; const re = /<section class="include-note[^>]+data-note-id="([a-zA-Z0-9_]+)"[^>]*>/g;
let match; let match;
while (match = re.exec(content)) { while (match = re.exec(content)) {

View File

@ -5,6 +5,13 @@ const noteService = require("./notes");
const cls = require("./cls"); const cls = require("./cls");
const dateUtils = require("./date_utils"); const dateUtils = require("./date_utils");
const LBTPL_ROOT = "lbtpl_root";
const LBTPL_NOTE_SHORTCUT = "lbtpl_noteshortcut";
const LBTPL_SCRIPT = "lbtpl_script";
const LBTPL_BUILTIN_WIDGET = "lbtpl_builtinwidget";
const LBTPL_SPACER = "lbtpl_spacer";
const LBTPL_CUSTOM_WIDGET = "lbtpl_customwidget";
function getInboxNote(date) { function getInboxNote(date) {
const hoistedNote = getHoistedNote(); const hoistedNote = getHoistedNote();
@ -277,7 +284,8 @@ function getLaunchBarAvailableShortcutsRoot() {
title: 'Available shortcuts', title: 'Available shortcuts',
type: 'doc', type: 'doc',
content: '', content: '',
parentNoteId: getLaunchBarRoot().noteId parentNoteId: getLaunchBarRoot().noteId,
ignoreForbiddenParents: true
}).note; }).note;
note.addLabel("iconClass", "bx bx-hide"); note.addLabel("iconClass", "bx bx-hide");
@ -303,7 +311,8 @@ function getLaunchBarVisibleShortcutsRoot() {
title: 'Visible shortcuts', title: 'Visible shortcuts',
type: 'doc', type: 'doc',
content: '', content: '',
parentNoteId: getLaunchBarRoot().noteId parentNoteId: getLaunchBarRoot().noteId,
ignoreForbiddenParents: true
}).note; }).note;
note.addLabel("iconClass", "bx bx-show"); note.addLabel("iconClass", "bx bx-show");
@ -326,16 +335,10 @@ const shortcuts = [
{ id: 'lb_jumpto', command: 'jumpToNote', title: 'Jump to note', icon: 'bx bx-send', isVisible: true }, { id: 'lb_jumpto', command: 'jumpToNote', title: 'Jump to note', icon: 'bx bx-send', isVisible: true },
{ id: 'lb_notemap', targetNoteId: 'globalnotemap', title: 'Note map', icon: 'bx bx-map-alt', isVisible: true }, { id: 'lb_notemap', targetNoteId: 'globalnotemap', title: 'Note map', icon: 'bx bx-map-alt', isVisible: true },
{ id: 'lb_calendar', builtinWidget: 'calendar', title: 'Calendar', icon: 'bx bx-calendar', isVisible: true }, { id: 'lb_calendar', builtinWidget: 'calendar', title: 'Calendar', icon: 'bx bx-calendar', isVisible: true },
{ id: 'lb_spacer1', builtinWidget: 'spacer', title: 'Spacer', icon: 'bx bx-move-vertical', isVisible: true, labels: [ { id: 'lb_spacer1', builtinWidget: 'spacer', title: 'Spacer', isVisible: true },
{ type: "number", name: "baseSize", value: "40" },
{ type: "number", name: "growthFactor", value: "100" },
] },
{ id: 'lb_pluginbuttons', builtinWidget: 'pluginButtons', title: 'Plugin buttons', icon: 'bx bx-extension', isVisible: true }, { id: 'lb_pluginbuttons', builtinWidget: 'pluginButtons', title: 'Plugin buttons', icon: 'bx bx-extension', isVisible: true },
{ id: 'lb_bookmarks', builtinWidget: 'bookmarks', title: 'Bookmarks', icon: 'bx bx-bookmark', isVisible: true }, { id: 'lb_bookmarks', builtinWidget: 'bookmarks', title: 'Bookmarks', icon: 'bx bx-bookmark', isVisible: true },
{ id: 'lb_spacer2', builtinWidget: 'spacer', title: 'Spacer', icon: 'bx bx-move-vertical', isVisible: true, labels: [ { id: 'lb_spacer2', builtinWidget: 'spacer', title: 'Spacer', isVisible: true },
{ type: "number", name: "baseSize", value: "40" },
{ type: "number", name: "growthFactor", value: "100" },
] },
{ id: 'lb_protectedsession', builtinWidget: 'protectedSession', title: 'Protected session', icon: 'bx bx bx-shield-quarter', isVisible: true }, { id: 'lb_protectedsession', builtinWidget: 'protectedSession', title: 'Protected session', icon: 'bx bx bx-shield-quarter', isVisible: true },
{ id: 'lb_syncstatus', builtinWidget: 'syncStatus', title: 'Sync status', icon: 'bx bx-wifi', isVisible: true }, { id: 'lb_syncstatus', builtinWidget: 'syncStatus', title: 'Sync status', icon: 'bx bx-wifi', isVisible: true },
@ -349,6 +352,7 @@ function createMissingSpecialNotes() {
getSqlConsoleRoot(); getSqlConsoleRoot();
getGlobalNoteMap(); getGlobalNoteMap();
getBulkActionNote(); getBulkActionNote();
createShortcutTemplates();
getLaunchBarRoot(); getLaunchBarRoot();
getLaunchBarAvailableShortcutsRoot(); getLaunchBarAvailableShortcutsRoot();
getLaunchBarVisibleShortcutsRoot(); getLaunchBarVisibleShortcutsRoot();
@ -373,23 +377,27 @@ function createMissingSpecialNotes() {
parentNoteId: parentNoteId parentNoteId: parentNoteId
}).note; }).note;
note.addLabel('builtinShortcut'); if (shortcut.icon) {
note.addLabel('iconClass', shortcut.icon); note.addLabel('iconClass', shortcut.icon);
}
if (shortcut.command) { if (shortcut.command) {
note.addRelation('template', LBTPL_NOTE_SHORTCUT);
note.addLabel('command', shortcut.command); note.addLabel('command', shortcut.command);
} else if (shortcut.builtinWidget) { } else if (shortcut.builtinWidget) {
if (shortcut.builtinWidget === 'spacer') {
note.addRelation('template', LBTPL_SPACER);
} else {
note.addRelation('template', LBTPL_BUILTIN_WIDGET);
}
note.addLabel('builtinWidget', shortcut.builtinWidget); note.addLabel('builtinWidget', shortcut.builtinWidget);
} else if (shortcut.targetNoteId) { } else if (shortcut.targetNoteId) {
note.addRelation('template', LBTPL_NOTE_SHORTCUT);
note.addRelation('targetNote', shortcut.targetNoteId); note.addRelation('targetNote', shortcut.targetNoteId);
} else { } else {
throw new Error(`No action defined for shortcut ${JSON.stringify(shortcut)}`); throw new Error(`No action defined for shortcut ${JSON.stringify(shortcut)}`);
} }
for (const label of shortcut.labels || []) {
note.addLabel('label:' + label.name, "promoted," + label.type);
note.addLabel(label.name, label.value);
}
} }
// share root is not automatically created since it's visible in the tree and many won't need it/use it // share root is not automatically created since it's visible in the tree and many won't need it/use it
@ -411,9 +419,6 @@ function createShortcut(parentNoteId, type) {
content: '', content: '',
parentNoteId: parentNoteId parentNoteId: parentNoteId
}).note; }).note;
note.addLabel('relation:targetNote', 'promoted');
note.addLabel('docName', 'launchbar_note_shortcut');
} else if (type === 'script') { } else if (type === 'script') {
note = noteService.createNewNote({ note = noteService.createNewNote({
title: "Script shortcut", title: "Script shortcut",
@ -459,6 +464,97 @@ function createShortcut(parentNoteId, type) {
}; };
} }
function createShortcutTemplates() {
if (!(LBTPL_ROOT in becca.notes)) {
noteService.createNewNote({
branchId: LBTPL_ROOT,
noteId: LBTPL_ROOT,
title: 'Launch bar templates',
type: 'doc',
content: '',
parentNoteId: getHiddenRoot().noteId
});
}
if (!(LBTPL_NOTE_SHORTCUT in becca.notes)) {
const tpl = noteService.createNewNote({
branchId: LBTPL_NOTE_SHORTCUT,
noteId: LBTPL_NOTE_SHORTCUT,
title: 'Note shortcut',
type: 'doc',
content: '',
parentNoteId: LBTPL_ROOT
}).note;
tpl.addLabel('shortcutType', 'note');
tpl.addLabel('relation:targetNote', 'promoted');
tpl.addLabel('docName', 'launchbar_note_shortcut');
}
if (!(LBTPL_SCRIPT in becca.notes)) {
const tpl = noteService.createNewNote({
branchId: LBTPL_SCRIPT,
noteId: LBTPL_SCRIPT,
title: 'Script',
type: 'doc',
content: '',
parentNoteId: LBTPL_ROOT
}).note;
tpl.addLabel('shortcutType', 'script');
tpl.addLabel('relation:script', 'promoted');
tpl.addLabel('docName', 'launchbar_script_shortcut');
}
if (!(LBTPL_BUILTIN_WIDGET in becca.notes)) {
const tpl = noteService.createNewNote({
branchId: LBTPL_BUILTIN_WIDGET,
noteId: LBTPL_BUILTIN_WIDGET,
title: 'Builtin widget',
type: 'doc',
content: '',
parentNoteId: LBTPL_ROOT
}).note;
tpl.addLabel('shortcutType', 'builtinWidget');
}
if (!(LBTPL_SPACER in becca.notes)) {
const tpl = noteService.createNewNote({
branchId: LBTPL_SPACER,
noteId: LBTPL_SPACER,
title: 'Spacer',
type: 'doc',
content: '',
parentNoteId: LBTPL_ROOT
}).note;
tpl.addRelation('template', LBTPL_BUILTIN_WIDGET);
tpl.addLabel('builtinWidget', 'spacer');
tpl.addLabel('iconClass', 'bx bx-move-vertical');
tpl.addLabel('label:baseSize', 'promoted,number');
tpl.addLabel('baseSize', '40');
tpl.addLabel('label:growthFactor', 'promoted,number');
tpl.addLabel('growthFactor', '0');
tpl.addLabel('docName', 'launchbar_spacer');
}
if (!(LBTPL_CUSTOM_WIDGET in becca.notes)) {
const tpl = noteService.createNewNote({
branchId: LBTPL_CUSTOM_WIDGET,
noteId: LBTPL_CUSTOM_WIDGET,
title: 'Custom widget',
type: 'doc',
content: '',
parentNoteId: LBTPL_ROOT
}).note;
tpl.addLabel('shortcutType', 'builtinWidget');
tpl.addLabel('relation:widget', 'promoted');
tpl.addLabel('docName', 'launchbar_widget_shortcut');
}
}
function resetShortcut(noteId) { function resetShortcut(noteId) {
if (noteId.startsWith('lb_')) { if (noteId.startsWith('lb_')) {
const note = becca.getNote(noteId); const note = becca.getNote(noteId);