many small fixes from Intellij analysis

This commit is contained in:
zadam 2023-05-05 23:17:23 +02:00
parent 0af6f91d21
commit 6dfc72c065
41 changed files with 73 additions and 83 deletions

View File

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

View File

@ -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]);

View File

@ -86,7 +86,7 @@ class BAttachment extends AbstractBeccaEntity {
|| protectedSessionService.isProtectedSessionAvailable()
}
/** @returns {*} */
/** @returns {string|Buffer} */
getContent() {
return this._getContent();
}

View File

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

View File

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

View File

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

View File

@ -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('/') : [];
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -78,7 +78,7 @@ export default class NoteMapWidget extends NoteContextAwareWidget {
.width($parent.width());
}
async refreshWithNote() {
async refreshWithNote(note) {
this.$widget.show();
this.css = {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -26,7 +26,6 @@ function getNoteRevisions(req) {
}
function getNoteRevision(req) {
// FIXME
const noteRevision = becca.getNoteRevision(req.params.noteRevisionId);
if (noteRevision.type === 'file') {

View 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 = {

View File

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

View File

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

View File

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

View File

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