mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
many small fixes from Intellij analysis
This commit is contained in:
parent
0af6f91d21
commit
6dfc72c065
@ -92,6 +92,7 @@ module.exports = {
|
||||
renderMathInElement: true,
|
||||
// \src\public\app\widgets\type_widgets\editable_text.js
|
||||
BalloonEditor: true,
|
||||
FancytreeNode: true,
|
||||
CKEditorInspector: true,
|
||||
// \src\public\app\widgets\type_widgets\editable_code.js
|
||||
CodeMirror: true,
|
||||
|
@ -189,7 +189,7 @@ class AbstractBeccaEntity {
|
||||
* We're using the unencrypted blob for the hash calculation, because otherwise the random IV would
|
||||
* cause every content blob to be unique which would balloon the database size (esp. with revisioning).
|
||||
* This has minor security implications (it's easy to infer that given content is shared between different
|
||||
* notes/attachments, but the trade-off comes out clearly positive.
|
||||
* notes/attachments, but the trade-off comes out clearly positive).
|
||||
*/
|
||||
newBlobId = utils.hashedBlobId(unencryptedContentForHashCalculation);
|
||||
blobNeedsInsert = !sql.getValue('SELECT 1 FROM blobs WHERE blobId = ?', [newBlobId]);
|
||||
@ -228,7 +228,10 @@ class AbstractBeccaEntity {
|
||||
return newBlobId;
|
||||
}
|
||||
|
||||
/** @protected */
|
||||
/**
|
||||
* @protected
|
||||
* @returns {string|Buffer}
|
||||
*/
|
||||
_getContent() {
|
||||
const row = sql.getRow(`SELECT content FROM blobs WHERE blobId = ?`, [this.blobId]);
|
||||
|
||||
|
@ -86,7 +86,7 @@ class BAttachment extends AbstractBeccaEntity {
|
||||
|| protectedSessionService.isProtectedSessionAvailable()
|
||||
}
|
||||
|
||||
/** @returns {*} */
|
||||
/** @returns {string|Buffer} */
|
||||
getContent() {
|
||||
return this._getContent();
|
||||
}
|
||||
|
@ -207,7 +207,7 @@ class BNote extends AbstractBeccaEntity {
|
||||
* - but to the user note content and title changes are one and the same - single dateModified (so all changes must go through Note and content is not a separate entity)
|
||||
*/
|
||||
|
||||
/** @returns {*} */
|
||||
/** @returns {string|Buffer} */
|
||||
getContent() {
|
||||
return this._getContent();
|
||||
}
|
||||
@ -965,7 +965,7 @@ class BNote extends AbstractBeccaEntity {
|
||||
};
|
||||
}
|
||||
|
||||
/** @returns {String[]} - includes the subtree root note as well */
|
||||
/** @returns {string[]} - includes the subtree root note as well */
|
||||
getSubtreeNoteIds({includeArchived = true, includeHidden = false, resolveSearch = false} = {}) {
|
||||
return this.getSubtree({includeArchived, includeHidden, resolveSearch})
|
||||
.notes
|
||||
@ -1157,13 +1157,10 @@ class BNote extends AbstractBeccaEntity {
|
||||
}
|
||||
|
||||
const parentNotes = this.getParentNotes();
|
||||
let notePaths = [];
|
||||
|
||||
if (parentNotes.length === 1) { // optimization for most common case
|
||||
notePaths = parentNotes[0].getAllNotePaths();
|
||||
} else {
|
||||
notePaths = parentNotes.flatMap(parentNote => parentNote.getAllNotePaths());
|
||||
}
|
||||
const notePaths = parentNotes.length === 1
|
||||
? parentNotes[0].getAllNotePaths() // optimization for most common case
|
||||
: parentNotes.flatMap(parentNote => parentNote.getAllNotePaths());
|
||||
|
||||
for (const notePath of notePaths) {
|
||||
notePath.push(this.noteId);
|
||||
@ -1514,10 +1511,10 @@ class BNote extends AbstractBeccaEntity {
|
||||
/**
|
||||
* (Soft) delete a note and all its descendants.
|
||||
*
|
||||
* @param {string} [deleteId] - optional delete identified
|
||||
* @param {string} [deleteId=null] - optional delete identified
|
||||
* @param {TaskContext} [taskContext]
|
||||
*/
|
||||
deleteNote(deleteId, taskContext) {
|
||||
deleteNote(deleteId = null, taskContext = null) {
|
||||
if (this.isDeleted) {
|
||||
return;
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ class BNoteRevision extends AbstractBeccaEntity {
|
||||
* This is the same approach as is used for Note's content.
|
||||
*/
|
||||
|
||||
/** @returns {*} */
|
||||
/** @returns {string|Buffer} */
|
||||
getContent() {
|
||||
return this._getContent();
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ export default class MainTreeExecutors extends Component {
|
||||
}
|
||||
|
||||
const parentNotePath = treeService.getNotePath(node.getParent());
|
||||
const isProtected = await treeService.getParentProtectedStatus(node);
|
||||
const isProtected = treeService.getParentProtectedStatus(node);
|
||||
|
||||
if (node.data.noteId === 'root' || node.data.noteId === hoistedNoteService.getHoistedNoteId()) {
|
||||
return;
|
||||
|
@ -152,7 +152,7 @@ class NoteContext extends Component {
|
||||
return resolvedNotePath;
|
||||
}
|
||||
|
||||
/** @property {FNote} */
|
||||
/** @returns {FNote} */
|
||||
get note() {
|
||||
if (!this.noteId || !(this.noteId in froca.notes)) {
|
||||
return null;
|
||||
@ -161,7 +161,7 @@ class NoteContext extends Component {
|
||||
return froca.notes[this.noteId];
|
||||
}
|
||||
|
||||
/** @property {string[]} */
|
||||
/** @returns {string[]} */
|
||||
get notePathArray() {
|
||||
return this.notePath ? this.notePath.split('/') : [];
|
||||
}
|
||||
|
@ -14,6 +14,8 @@ export default class TabManager extends Component {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
/** @property {NoteContext[]} */
|
||||
this.children = [];
|
||||
this.mutex = new Mutex();
|
||||
|
||||
this.activeNtxId = null;
|
||||
@ -38,7 +40,7 @@ export default class TabManager extends Component {
|
||||
appContext.addBeforeUnloadListener(this);
|
||||
}
|
||||
|
||||
/** @type {NoteContext[]} */
|
||||
/** @returns {NoteContext[]} */
|
||||
get noteContexts() {
|
||||
return this.children;
|
||||
}
|
||||
|
@ -358,13 +358,10 @@ class FNote {
|
||||
}
|
||||
|
||||
const parentNotes = this.getParentNotes();
|
||||
let notePaths = [];
|
||||
|
||||
if (parentNotes.length === 1) { // optimization for most common case
|
||||
notePaths = parentNotes[0].getAllNotePaths();
|
||||
} else {
|
||||
notePaths = parentNotes.flatMap(parentNote => parentNote.getAllNotePaths());
|
||||
}
|
||||
const notePaths = parentNotes.length === 1
|
||||
? parentNotes[0].getAllNotePaths() // optimization for most common case
|
||||
: parentNotes.flatMap(parentNote => parentNote.getAllNotePaths());
|
||||
|
||||
for (const notePath of notePaths) {
|
||||
notePath.push(this.noteId);
|
||||
|
@ -108,7 +108,7 @@ export default class TreeContextMenu {
|
||||
}
|
||||
else if (command === "insertNoteAfter") {
|
||||
const parentNotePath = treeService.getNotePath(this.node.getParent());
|
||||
const isProtected = await treeService.getParentProtectedStatus(this.node);
|
||||
const isProtected = treeService.getParentProtectedStatus(this.node);
|
||||
|
||||
noteCreateService.createNote(parentNotePath, {
|
||||
target: 'after',
|
||||
|
@ -41,7 +41,7 @@ class WidgetsByParent {
|
||||
|
||||
add(widget) {
|
||||
if (!widget.parentWidget) {
|
||||
console.log(`Custom widget does not have mandatory 'getParent()' method defined`);
|
||||
console.log(`Custom widget does not have mandatory 'parentWidget' property defined`);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -9,15 +9,15 @@
|
||||
* @see http://unscriptable.com/2009/03/20/debouncing-javascript-methods/
|
||||
* @param {Function} func to wrap
|
||||
* @param {Number} waitMs in ms (`100`)
|
||||
* @param {Boolean} immediate whether to execute at the beginning (`false`)
|
||||
* @param {Boolean} [immediate=false] whether to execute at the beginning (`false`)
|
||||
* @api public
|
||||
*/
|
||||
function debounce(func, waitMs, immediate) {
|
||||
var timeout, args, context, timestamp, result;
|
||||
function debounce(func, waitMs, immediate = false) {
|
||||
let timeout, args, context, timestamp, result;
|
||||
if (null == waitMs) waitMs = 100;
|
||||
|
||||
function later() {
|
||||
var last = Date.now() - timestamp;
|
||||
const last = Date.now() - timestamp;
|
||||
|
||||
if (last < waitMs && last >= 0) {
|
||||
timeout = setTimeout(later, waitMs - last);
|
||||
@ -30,11 +30,11 @@ function debounce(func, waitMs, immediate) {
|
||||
}
|
||||
}
|
||||
|
||||
var debounced = function(){
|
||||
const debounced = function () {
|
||||
context = this;
|
||||
args = arguments;
|
||||
timestamp = Date.now();
|
||||
var callNow = immediate && !timeout;
|
||||
const callNow = immediate && !timeout;
|
||||
if (!timeout) timeout = setTimeout(later, waitMs);
|
||||
if (callNow) {
|
||||
result = func.apply(context, args);
|
||||
|
@ -5,6 +5,7 @@ import options from "./options.js";
|
||||
import noteAttributeCache from "./note_attribute_cache.js";
|
||||
import FBranch from "../entities/fbranch.js";
|
||||
import FAttribute from "../entities/fattribute.js";
|
||||
import FAttachment from "../entities/fattachment.js";
|
||||
|
||||
async function processEntityChanges(entityChanges) {
|
||||
const loadResults = new LoadResults(entityChanges);
|
||||
|
@ -322,7 +322,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
|
||||
* See https://ckeditor.com/docs/ckeditor5/latest/api/module_core_editor_editor-Editor.html for a documentation on the returned instance.
|
||||
*
|
||||
* @method
|
||||
* @returns {Promise<CKEditor>} instance of CKEditor
|
||||
* @returns {Promise<BalloonEditor>} instance of CKEditor
|
||||
*/
|
||||
this.getActiveContextTextEditor = () => appContext.tabManager.getActiveContext()?.getTextEditor();
|
||||
|
||||
|
@ -79,7 +79,7 @@ async function openExternally(type, entityId, mime) {
|
||||
|
||||
if (res) {
|
||||
// fallback in case there's no default application for this file
|
||||
window.open(getFileUrl(type, entityId), { url: true });
|
||||
window.open(getFileUrl(type, entityId));
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -18,7 +18,7 @@ async function resolveNotePath(notePath, hoistedNoteId = 'root') {
|
||||
* notePath as possible. Part of the path might not be valid because of note moving (which causes
|
||||
* path change) or other corruption, in that case this will try to get some other valid path to the correct note.
|
||||
*
|
||||
* @returns {string[]}
|
||||
* @returns {Promise<string[]>}
|
||||
*/
|
||||
async function resolveNotePathToSegments(notePath, hoistedNoteId = 'root', logErrors = true) {
|
||||
utils.assertArguments(notePath);
|
||||
@ -129,7 +129,7 @@ ws.subscribeToMessages(message => {
|
||||
});
|
||||
|
||||
function getParentProtectedStatus(node) {
|
||||
return hoistedNoteService.isHoistedNode(node) ? 0 : node.getParent().data.isProtected;
|
||||
return hoistedNoteService.isHoistedNode(node) ? false : node.getParent().data.isProtected;
|
||||
}
|
||||
|
||||
function getNoteIdFromNotePath(notePath) {
|
||||
|
@ -399,10 +399,10 @@ function escapeRegExp(str) {
|
||||
}
|
||||
|
||||
function areObjectsEqual () {
|
||||
var i, l, leftChain, rightChain;
|
||||
let i, l, leftChain, rightChain;
|
||||
|
||||
function compare2Objects (x, y) {
|
||||
var p;
|
||||
let p;
|
||||
|
||||
// remember that NaN === NaN returns false
|
||||
// and isNaN(undefined) returns true
|
||||
|
@ -321,9 +321,7 @@ export default class AttributeEditorWidget extends NoteContextAwareWidget {
|
||||
|
||||
parseAttributes() {
|
||||
try {
|
||||
const attrs = attributesParser.lexAndParse(this.getPreprocessedData());
|
||||
|
||||
return attrs;
|
||||
return attributesParser.lexAndParse(this.getPreprocessedData());
|
||||
}
|
||||
catch (e) {
|
||||
this.$errors.text(e.message).slideDown();
|
||||
|
@ -27,7 +27,7 @@ export default class BookmarkSwitchWidget extends SwitchWidget {
|
||||
}
|
||||
}
|
||||
|
||||
refreshWithNote(note) {
|
||||
async refreshWithNote(note) {
|
||||
const isBookmarked = !!note.getParentBranches().find(b => b.parentNoteId === '_lbBookmarks');
|
||||
|
||||
this.$switchOn.toggle(!isBookmarked);
|
||||
|
@ -90,7 +90,7 @@ export default class NoteActionsWidget extends NoteContextAwareWidget {
|
||||
});
|
||||
}
|
||||
|
||||
refreshWithNote(note) {
|
||||
async refreshWithNote(note) {
|
||||
this.$convertNoteIntoAttachmentButton.toggle(note.isEligibleForConversionToAttachment());
|
||||
|
||||
this.toggleDisabled(this.$findInTextButton, ['text', 'code', 'book', 'search'].includes(note.type));
|
||||
|
@ -34,7 +34,7 @@ export default class ConfirmDialog extends BasicWidget {
|
||||
super();
|
||||
|
||||
this.resolve = null;
|
||||
this.$originallyFocused = null; // element focused before the dialog was opened, so we can return to it afterwards
|
||||
this.$originallyFocused = null; // element focused before the dialog was opened, so we can return to it afterward
|
||||
}
|
||||
|
||||
doRender() {
|
||||
|
@ -27,7 +27,7 @@ export default class InfoDialog extends BasicWidget {
|
||||
super();
|
||||
|
||||
this.resolve = null;
|
||||
this.$originallyFocused = null; // element focused before the dialog was opened, so we can return to it afterwards
|
||||
this.$originallyFocused = null; // element focused before the dialog was opened, so we can return to it afterward
|
||||
}
|
||||
|
||||
doRender() {
|
||||
|
@ -46,7 +46,7 @@ export default class NoteTypeChooserDialog extends BasicWidget {
|
||||
super(props);
|
||||
|
||||
this.resolve = null;
|
||||
this.$originalFocused = null; // element focused before the dialog was opened, so we can return to it afterwards
|
||||
this.$originalFocused = null; // element focused before the dialog was opened, so we can return to it afterward
|
||||
this.$originalDialog = null;
|
||||
}
|
||||
|
||||
|
@ -68,7 +68,7 @@ export default class CodeButtonsWidget extends NoteContextAwareWidget {
|
||||
super.doRender();
|
||||
}
|
||||
|
||||
refreshWithNote(note) {
|
||||
async refreshWithNote(note) {
|
||||
this.$executeButton.toggle(
|
||||
note.mime.startsWith('application/javascript')
|
||||
|| note.mime === 'text/x-sqlite;schema=trilium'
|
||||
|
@ -1,6 +1,5 @@
|
||||
import libraryLoader from "../services/library_loader.js";
|
||||
import NoteContextAwareWidget from "./note_context_aware_widget.js";
|
||||
import froca from "../services/froca.js";
|
||||
|
||||
const TPL = `<div class="mermaid-widget">
|
||||
<style>
|
||||
|
@ -78,7 +78,7 @@ export default class NoteMapWidget extends NoteContextAwareWidget {
|
||||
.width($parent.width());
|
||||
}
|
||||
|
||||
async refreshWithNote() {
|
||||
async refreshWithNote(note) {
|
||||
this.$widget.show();
|
||||
|
||||
this.css = {
|
||||
|
@ -1424,11 +1424,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
|
||||
const parentNote = froca.getNoteFromCache(node.getParent().data.noteId);
|
||||
|
||||
if (parentNote && parentNote.hasLabel('sorted')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return !parentNote?.hasLabel('sorted');
|
||||
}
|
||||
|
||||
moveNoteUpCommand({node}) {
|
||||
|
@ -20,7 +20,7 @@ export default class ProtectedNoteSwitchWidget extends SwitchWidget {
|
||||
protectedSessionService.protectNote(this.noteId, false, false)
|
||||
}
|
||||
|
||||
refreshWithNote(note) {
|
||||
async refreshWithNote(note) {
|
||||
this.$switchOn.toggle(!note.isProtected);
|
||||
this.$switchOff.toggle(!!note.isProtected);
|
||||
}
|
||||
|
@ -75,14 +75,6 @@ export default class OwnedAttributeListWidget extends NoteContextAwareWidget {
|
||||
await this.attributeEditorWidget.updateAttributeList(attributes);
|
||||
}
|
||||
|
||||
entitiesReloadedEvent({loadResults}) {
|
||||
if (loadResults.getAttributes(this.componentId).find(attr => attributeService.isAffecting(attr, this.note))) {
|
||||
this.refreshWithNote(this.note, true);
|
||||
|
||||
this.getTitle(this.note);
|
||||
}
|
||||
}
|
||||
|
||||
focus() {
|
||||
this.attributeEditorWidget.focus();
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ export default class SimilarNotesWidget extends NoteContextAwareWidget {
|
||||
this.$similarNotesWrapper = this.$widget.find(".similar-notes-wrapper");
|
||||
}
|
||||
|
||||
async refreshWithNote() {
|
||||
async refreshWithNote(note) {
|
||||
// remember which title was when we found the similar notes
|
||||
this.title = this.note.title;
|
||||
|
||||
|
@ -517,7 +517,7 @@ export default class TabRowWidget extends BasicWidget {
|
||||
|
||||
draggabilly.on('dragEnd', _ => {
|
||||
this.isDragging = false;
|
||||
const finalTranslateX = parseFloat(tabEl.style.left, 10);
|
||||
const finalTranslateX = parseFloat(tabEl.style.left);
|
||||
tabEl.style.transform = `translate3d(0, 0, 0)`;
|
||||
|
||||
// Animate dragged tab back into its place
|
||||
@ -617,7 +617,10 @@ export default class TabRowWidget extends BasicWidget {
|
||||
this.updateTab($tab, noteContext);
|
||||
}
|
||||
|
||||
/** @param {NoteContext} noteContext */
|
||||
/**
|
||||
* @param {jQuery} $tab
|
||||
* @param {NoteContext} noteContext
|
||||
*/
|
||||
async updateTab($tab, noteContext) {
|
||||
if (!$tab.length) {
|
||||
return;
|
||||
|
@ -106,7 +106,7 @@ export default class TocWidget extends RightPanelWidget {
|
||||
/**
|
||||
* Builds a jquery table of contents.
|
||||
*
|
||||
* @param {String} html Note's html content
|
||||
* @param {string} html Note's html content
|
||||
* @returns {$toc: jQuery, headingCount: integer} ordered list table of headings, nested by heading level
|
||||
* with an onclick event that will cause the document to scroll to
|
||||
* the desired position.
|
||||
|
@ -1,7 +1,6 @@
|
||||
import libraryLoader from "../../services/library_loader.js";
|
||||
import TypeWidget from "./type_widget.js";
|
||||
import utils from '../../services/utils.js';
|
||||
import froca from "../../services/froca.js";
|
||||
import debounce from "../../services/debounce.js";
|
||||
|
||||
const {sleep} = utils;
|
||||
|
@ -1,4 +1,3 @@
|
||||
import froca from "../../services/froca.js";
|
||||
import AbstractTextTypeWidget from "./abstract_text_type_widget.js";
|
||||
import treeService from "../../services/tree.js";
|
||||
import libraryLoader from "../../services/library_loader.js";
|
||||
|
@ -24,8 +24,6 @@ export default class WatchedFileUpdateStatusWidget extends NoteContextAwareWidge
|
||||
isEnabled() {
|
||||
const { entityType, entityId } = this.getEntity();
|
||||
|
||||
console.log(entityType, entityId);
|
||||
|
||||
return super.isEnabled() && !!fileWatcher.getFileModificationStatus(entityType, entityId);
|
||||
}
|
||||
|
||||
@ -56,7 +54,7 @@ export default class WatchedFileUpdateStatusWidget extends NoteContextAwareWidge
|
||||
});
|
||||
}
|
||||
|
||||
refreshWithNote(note) {
|
||||
async refreshWithNote(note) {
|
||||
const { entityType, entityId } = this.getEntity();
|
||||
const status = fileWatcher.getFileModificationStatus(entityType, entityId);
|
||||
|
||||
|
@ -26,7 +26,6 @@ function getNoteRevisions(req) {
|
||||
}
|
||||
|
||||
function getNoteRevision(req) {
|
||||
// FIXME
|
||||
const noteRevision = becca.getNoteRevision(req.params.noteRevisionId);
|
||||
|
||||
if (noteRevision.type === 'file') {
|
||||
|
@ -51,13 +51,16 @@ function encrypt(key, plainText) {
|
||||
return encryptedDataWithIv.toString('base64');
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Buffer|false|null}
|
||||
*/
|
||||
function decrypt(key, cipherText) {
|
||||
if (cipherText === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!key) {
|
||||
return "[protected]";
|
||||
return Buffer.from("[protected]");
|
||||
}
|
||||
|
||||
try {
|
||||
@ -103,17 +106,13 @@ function decryptString(dataKey, cipherText) {
|
||||
|
||||
if (buffer === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const str = buffer.toString('utf-8');
|
||||
|
||||
if (str === 'false') {
|
||||
} else if (buffer === false) {
|
||||
log.error(`Could not decrypt string. Buffer: ${buffer}`);
|
||||
|
||||
throw new Error("Could not decrypt string.");
|
||||
}
|
||||
|
||||
return str;
|
||||
return buffer.toString('UTF-8');
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
@ -65,7 +65,7 @@ function importCodeNote(taskContext, file, parentNote) {
|
||||
const detectedMime = mimeService.getMime(file.originalname) || file.mimetype;
|
||||
const mime = mimeService.normalizeMimeType(detectedMime);
|
||||
|
||||
const {note} = noteService.createNewNote({
|
||||
const { note } = noteService.createNewNote({
|
||||
parentNoteId: parentNote.noteId,
|
||||
title,
|
||||
content,
|
||||
|
@ -369,6 +369,10 @@ async function importZip(taskContext, fileBuffer, importRootNote) {
|
||||
return content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} filePath
|
||||
* @param {Buffer} content
|
||||
*/
|
||||
function saveNote(filePath, content) {
|
||||
const {parentNoteMeta, noteMeta, attachmentMeta} = getMeta(filePath);
|
||||
|
||||
@ -566,6 +570,7 @@ function streamToBuffer(stream) {
|
||||
return new Promise((res, rej) => stream.on('end', () => res(Buffer.concat(chunks))));
|
||||
}
|
||||
|
||||
/** @returns {Buffer} */
|
||||
function readContent(zipfile, entry) {
|
||||
return new Promise((res, rej) => {
|
||||
zipfile.openReadStream(entry, function(err, readStream) {
|
||||
|
@ -1,6 +1,7 @@
|
||||
const becca = require('../becca/becca');
|
||||
const sql = require("./sql");
|
||||
|
||||
/** @returns {string|null} */
|
||||
function getOptionOrNull(name) {
|
||||
let option;
|
||||
|
||||
@ -14,11 +15,12 @@ function getOptionOrNull(name) {
|
||||
return option ? option.value : null;
|
||||
}
|
||||
|
||||
/** @returns {string} */
|
||||
function getOption(name) {
|
||||
const val = getOptionOrNull(name);
|
||||
|
||||
if (val === null) {
|
||||
throw new Error(`Option "${name}" doesn't exist`);
|
||||
throw new Error(`Option '${name}' doesn't exist`);
|
||||
}
|
||||
|
||||
return val;
|
||||
|
@ -177,7 +177,7 @@ function register(router) {
|
||||
res.send(note.getContent());
|
||||
});
|
||||
|
||||
// :filename is not used by trilium, but instead used for "save as" to assign a human readable filename
|
||||
// :filename is not used by trilium, but instead used for "save as" to assign a human-readable filename
|
||||
router.get('/share/api/images/:noteId/:filename', (req, res, next) => {
|
||||
shacaLoader.ensureLoad();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user