Compare commits

..

27 Commits

Author SHA1 Message Date
zadam
a98fd509c6 release 0.58.7 2023-01-17 23:14:58 +01:00
zadam
a3149aecf4 fix migration for DBs which did not have _hidden tree created, closes #3536 2023-01-17 23:13:21 +01:00
zadam
ef825371cf fix "root" note in autocomplete when hoisted into another subtree 2023-01-17 21:15:05 +01:00
zadam
b567775129 small fixes of steel blue theme 2023-01-17 21:06:30 +01:00
zadam
58d71bf8e3 release 0.58.6 2023-01-16 22:39:28 +01:00
zadam
9fd0b85ff2 doc note for the back/forward launchers 2023-01-16 22:37:21 +01:00
zadam
98620887d4 fix demo steel blue main menu icon 2023-01-16 22:19:36 +01:00
zadam
9eff08144c extra check that hidden tree is not created until migration is completed 2023-01-16 08:06:19 +01:00
zadam
4ba72bc8d3 fixed standalone anonymize script 2023-01-15 21:05:03 +01:00
zadam
743979266a fix history navigation buttons in server, #3527 2023-01-15 19:46:32 +01:00
zadam
4f98c960ec fix note revision for images 2023-01-15 19:23:28 +01:00
zadam
424b624ea9 small mermaid fixes 2023-01-15 13:48:01 +01:00
zadam
a004a8b092 fix loading custom themes in Options, closes #3528 2023-01-15 12:54:38 +01:00
zadam
df0f52aff9 clarified comment 2023-01-14 23:16:57 +01:00
zadam
f7bd72ba2f release 0.58.5 2023-01-14 23:02:39 +01:00
zadam
038c0e78a6 fix options check in froca 2023-01-14 23:01:02 +01:00
zadam
2a2cbcd68b fix duplicate unique key in migration, #3526 2023-01-14 22:57:39 +01:00
zadam
14da697a4e put firing of the runOnNoteContentChange on entity level instead of service level, #3436 2023-01-14 12:57:50 +01:00
zadam
2525857c20 fix null content when protecting notes, closes #3523 2023-01-14 00:01:24 +01:00
zadam
8eaef3e1d8 add runOnNoteContentChange into the autocomplete 2023-01-13 14:28:41 +01:00
zadam
082caf98e8 restore all "named" notes quickly after their deletion, #3517 2023-01-13 11:53:25 +01:00
zadam
60602a2264 fix creating notes into options, #3517 2023-01-13 11:34:35 +01:00
zadam
9479f1c1a1 toggling archived notes caused appearance of hidden subtree, fixes #3519 2023-01-13 11:25:58 +01:00
zadam
88bc7402a2 hidden notes should not appear in the global search unless hoisted into it, #3516 2023-01-13 10:09:41 +01:00
zadam
e7b3c3239b fix migration of bookmarks to also migrate bookmarkFolder #3514 2023-01-13 08:43:18 +01:00
zadam
4f4c3ef3f3 fix enex checkboxes for mac, closes #3511 2023-01-12 16:45:11 +01:00
zadam
decfeb366c zoom factor should be rounded to 1 floating point digit 2023-01-12 08:27:08 +01:00
36 changed files with 189 additions and 55 deletions

Binary file not shown.

View File

@@ -1,6 +1,6 @@
UPDATE branches SET branchId = '_hidden__search' WHERE parentNoteId = 'hidden' AND noteId = 'search';
UPDATE branches SET branchId = 'root__globalNoteMap' WHERE parentNoteId = 'singles' AND noteId = 'globalnotemap';
UPDATE branches SET branchId = '_hidden__sqlConsole' WHERE parentNoteId = 'hidden' AND noteId = 'sqlconsole';
UPDATE branches SET branchId = 'root__hidden' WHERE parentNoteId = 'root' AND noteId = 'hidden';
UPDATE branches SET branchId = '_hidden__bulkAction' WHERE parentNoteId = 'hidden' AND noteId = 'bulkaction';
UPDATE branches SET branchId = '_hidden__share' WHERE parentNoteId = 'root' AND noteId = 'share';
UPDATE branches SET branchId = '_hidden__search' WHERE parentNoteId = 'hidden' AND noteId = 'search' AND isDeleted = 0;
UPDATE branches SET branchId = 'root__globalNoteMap' WHERE parentNoteId = 'singles' AND noteId = 'globalnotemap' AND isDeleted = 0;
UPDATE branches SET branchId = '_hidden__sqlConsole' WHERE parentNoteId = 'hidden' AND noteId = 'sqlconsole' AND isDeleted = 0;
UPDATE branches SET branchId = 'root__hidden' WHERE parentNoteId = 'root' AND noteId = 'hidden' AND isDeleted = 0;
UPDATE branches SET branchId = '_hidden__bulkAction' WHERE parentNoteId = 'hidden' AND noteId = 'bulkaction' AND isDeleted = 0;
UPDATE branches SET branchId = '_hidden__share' WHERE parentNoteId = 'root' AND noteId = 'share' AND isDeleted = 0;

View File

@@ -7,6 +7,6 @@ module.exports = () => {
beccaLoader.load();
// make sure the hidden subtree exists since the subsequent migrations we will move some existing notes into it (share...)
// in previous releases hidden subtree was created lazily
hiddenSubtreeService.checkHiddenSubtree();
hiddenSubtreeService.checkHiddenSubtree(true);
});
};

View File

@@ -12,5 +12,10 @@ module.exports = () => {
attr.markAsDeleted("0204__migrate_bookmarks_to_clones");
}
// bookmarkFolder used to work in 0.57 without the bookmarked label
for (const attr of becca.findAttributes('label','bookmarkFolder')) {
cloningService.toggleNoteInParent(true, attr.noteId, '_lbBookmarks');
}
});
};

10
package-lock.json generated
View File

@@ -1,11 +1,12 @@
{
"name": "trilium",
"version": "0.58.3-beta",
"version": "0.58.6",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"version": "0.58.3-beta",
"name": "trilium",
"version": "0.58.6",
"hasInstallScript": true,
"license": "AGPL-3.0-only",
"dependencies": {
@@ -29,6 +30,7 @@
"electron-debug": "3.2.0",
"electron-dl": "3.5.0",
"electron-window-state": "5.0.3",
"escape-html": "1.0.3",
"express": "4.18.2",
"express-partial-content": "1.0.2",
"express-rate-limit": "6.7.0",
@@ -4774,7 +4776,7 @@
"node_modules/escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
},
"node_modules/escape-string-regexp": {
"version": "1.0.5",
@@ -14267,7 +14269,7 @@
"escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
},
"escape-string-regexp": {
"version": "1.0.5",

View File

@@ -2,7 +2,7 @@
"name": "trilium",
"productName": "Trilium Notes",
"description": "Trilium Notes",
"version": "0.58.4",
"version": "0.58.7",
"license": "AGPL-3.0-only",
"main": "electron.js",
"bin": {
@@ -49,6 +49,7 @@
"electron-debug": "3.2.0",
"electron-dl": "3.5.0",
"electron-window-state": "5.0.3",
"escape-html": "1.0.3",
"express": "4.18.2",
"express-partial-content": "1.0.2",
"express-rate-limit": "6.7.0",

View File

@@ -1,12 +1,12 @@
const backupService = require('./services/backup');
const anonymizationService = require('./services/anonymization');
const sqlInit = require('./services/sql_init');
require('./entities/entity_constructor');
require('./becca/entity_constructor');
sqlInit.dbReady.then(async () => {
try {
console.log("Starting anonymization...");
const resp = await backupService.anonymize();
const resp = await anonymizationService.createAnonymizedCopy('full');
if (resp.success) {
console.log(`Anonymized file has been saved to: ${resp.anonymizedFilePath}`);

View File

@@ -83,10 +83,8 @@ function getNoteTitleArrayForPath(notePathArray) {
throw new Error(`${notePathArray} is not an array.`);
}
const hoistedNoteId = cls.getHoistedNoteId();
if (notePathArray.length === 1 && notePathArray[0] === hoistedNoteId) {
return [getNoteTitle(hoistedNoteId)];
if (notePathArray.length === 1) {
return [getNoteTitle(notePathArray[0])];
}
const titles = [];
@@ -95,6 +93,7 @@ function getNoteTitleArrayForPath(notePathArray) {
let hoistedNotePassed = false;
// this is a notePath from outside of hoisted subtree so full title path needs to be returned
const hoistedNoteId = cls.getHoistedNoteId();
const outsideOfHoistedSubtree = !notePathArray.includes(hoistedNoteId);
for (const noteId of notePathArray) {

View File

@@ -11,6 +11,7 @@ const NoteRevision = require("./note_revision");
const TaskContext = require("../../services/task_context");
const dayjs = require("dayjs");
const utc = require('dayjs/plugin/utc');
const eventService = require("../../services/events");
dayjs.extend(utc)
const LABEL = 'label';
@@ -314,6 +315,11 @@ class Note extends AbstractEntity {
utcDateChanged: pojo.utcDateModified,
isSynced: true
});
eventService.emit(eventService.ENTITY_CHANGED, {
entityName: 'note_contents',
entity: this
});
}
setJsonContent(content) {
@@ -1107,6 +1113,13 @@ class Note extends AbstractEntity {
return notePaths;
}
/**
* @return boolean - true if there's no non-hidden path, note is not cloned to the visible tree
*/
isHiddenCompletely() {
return !this.getAllNotePaths().find(notePathArr => !notePathArr.includes('_hidden'));
}
/**
* @param ancestorNoteId
* @return {boolean} - true if ancestorNoteId occurs in at least one of the note's paths
@@ -1351,7 +1364,7 @@ class Note extends AbstractEntity {
}
isOptions() {
return this.noteId.startsWith("options");
return this.noteId.startsWith("_options");
}
get isDeleted() {

View File

@@ -31,7 +31,7 @@ class ZoomComponent extends Component {
async setZoomFactorAndSave(zoomFactor) {
if (zoomFactor >= MIN_ZOOM && zoomFactor <= MAX_ZOOM) {
zoomFactor = Math.round(zoomFactor * 1000) / 1000;
zoomFactor = Math.round(zoomFactor * 10) / 10;
this.setZoomFactor(zoomFactor);

View File

@@ -0,0 +1,3 @@
<p>Back and Forward buttons allow you to move in the navigation history.</p>
<p>These launchers are active only in the desktop build and will be ignored in the server edition where you can use the native browser navigation buttons instead.</p>

View File

@@ -364,6 +364,13 @@ class NoteShort {
return notePaths;
}
/**
* @return boolean - true if there's no non-hidden path, note is not cloned to the visible tree
*/
isHiddenCompletely() {
return !this.getAllNotePaths().find(notePathArr => !notePathArr.includes('_hidden'));
}
__filterAttrs(attributes, type, name) {
this.__validateTypeName(type, name);
@@ -853,7 +860,7 @@ class NoteShort {
}
isOptions() {
return this.noteId.startsWith("options");
return this.noteId.startsWith("_options");
}
}

View File

@@ -230,6 +230,10 @@ function init() {
$.fn.getSelectedNoteId = function () {
const notePath = $(this).getSelectedNotePath();
if (!notePath) {
return null;
}
const chunks = notePath.split('/');
return chunks.length >= 1 ? chunks[chunks.length - 1] : null;

View File

@@ -39,7 +39,7 @@ export default class CommandButtonWidget extends AbstractButtonWidget {
/**
* @param {function|string} command
* @returns {CommandButtonWidget}
* @returns {this}
*/
command(command) {
this.settings.command = command;

View File

@@ -303,7 +303,7 @@ export default class GlobalMenuWidget extends BasicWidget {
const resp = await fetch(RELEASES_API_URL);
const data = await resp.json();
return data.tag_name.substring(1);
return data?.tag_name?.substring(1);
}
downloadLatestVersionCommand() {

View File

@@ -23,6 +23,10 @@ export default class HistoryNavigationButton extends ButtonFromNoteWidget {
doRender() {
super.doRender();
if (!utils.isElectron()) {
return;
}
this.webContents = utils.dynamicRequire('@electron/remote').getCurrentWebContents();
// without this the history is preserved across frontend reloads

View File

@@ -234,14 +234,14 @@ export default class NoteRevisionsDialog extends BasicWidget {
renderMathInElement($content[0], {trust: true});
}
}
else if (revisionItem.type === 'code') {
else if (revisionItem.type === 'code' || revisionItem.type === 'mermaid') {
this.$content.html($("<pre>").text(fullNoteRevision.content));
}
else if (revisionItem.type === 'image') {
this.$content.html($("<img>")
// reason why we put this inline as base64 is that we do not want to let user to copy this
// as a URL to be used in a note. Instead if they copy and paste it into a note, it will be a uploaded as a new note
.attr("src", `data:${note.mime};base64,${fullNoteRevision.content}`)
// as a URL to be used in a note. Instead, if they copy and paste it into a note, it will be a uploaded as a new note
.attr("src", `data:${fullNoteRevision.mime};base64,${fullNoteRevision.content}`)
.css("max-width", "100%")
.css("max-height", "100%"));
}

View File

@@ -76,7 +76,7 @@ export default class CodeButtonsWidget extends NoteContextAwareWidget {
this.$saveToNoteButton.toggle(
note.mime === 'text/x-sqlite;schema=trilium'
&& !note.getAllNotePaths().find(notePathArr => !notePathArr.includes('_hidden'))
&& note.isHiddenCompletely()
);
this.$openTriliumApiDocsButton.toggle(note.mime.startsWith('application/javascript;env='));

View File

@@ -1309,6 +1309,8 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
await this.tree.reload([rootNode]);
});
await this.filterHoistedBranch();
if (activeNotePath) {
const node = await this.getNodeFromPath(activeNotePath, true);

View File

@@ -270,7 +270,7 @@ export default class SearchDefinitionWidget extends NoteContextAwareWidget {
async refreshWithNote(note) {
this.$component.show();
this.$saveToNoteButton.toggle(!note.getAllNotePaths().find(notePathArr => !notePathArr.includes('_hidden')));
this.$saveToNoteButton.toggle(note.isHiddenCompletely());
this.$searchOptions.empty();

View File

@@ -112,7 +112,7 @@ function update(name, value) {
}
function getUserThemes() {
const notes = searchService.searchNotes("#appTheme");
const notes = searchService.searchNotes("#appTheme", {ignoreHoistedNote: true});
const ret = [];
for (const note of notes) {

View File

@@ -1 +1 @@
module.exports = { buildDate:"2023-01-11T23:44:33+01:00", buildRevision: "bdfdc0402ddb23e9af002580f368bc52e4268b3a" };
module.exports = { buildDate:"2023-01-17T23:14:58+01:00", buildRevision: "a3149aecf41bac3c559ebbd1865e916264985ac3" };

View File

@@ -71,6 +71,7 @@ module.exports = [
{ type: 'relation', name: 'runOnNoteCreation', isDangerous: true },
{ type: 'relation', name: 'runOnNoteTitleChange', isDangerous: true },
{ type: 'relation', name: 'runOnNoteChange', isDangerous: true },
{ type: 'relation', name: 'runOnNoteContentChange', isDangerous: true },
{ type: 'relation', name: 'runOnNoteDeletion', isDangerous: true },
{ type: 'relation', name: 'runOnBranchCreation', isDangerous: true },
{ type: 'relation', name: 'runOnBranchDeletion', isDangerous: true },

View File

@@ -4,6 +4,8 @@ const treeService = require('./tree');
const noteService = require('./notes');
const becca = require('../becca/becca');
const Attribute = require('../becca/entities/attribute');
const hiddenSubtreeService = require("./hidden_subtree");
const oneTimeTimer = require("./one_time_timer");
function runAttachedRelations(note, relationName, originEntity) {
if (!note) {
@@ -206,6 +208,16 @@ eventService.subscribe(eventService.ENTITY_DELETED, ({ entityName, entity }) =>
if (entityName === 'branches') {
runAttachedRelations(entity.getNote(), 'runOnBranchDeletion', entity);
}
if (entityName === 'notes' && entity.noteId.startsWith("_")) {
// "named" note has been deleted, we will probably need to rebuild the hidden subtree
// scheduling so that bulk deletes won't trigger so many checks
oneTimeTimer.scheduleExecution('hidden-subtree-check', 1000, () => {
console.log("Checking hidden subtree");
hiddenSubtreeService.checkHiddenSubtree();
});
}
});
module.exports = {

View File

@@ -1,6 +1,8 @@
const becca = require("../becca/becca");
const noteService = require("./notes");
const Attribute = require("../becca/entities/attribute.js");
const log = require("./log");
const migrationService = require("./migration");
const LBTPL_ROOT = "_lbTplRoot";
const LBTPL_BASE = "_lbTplBase";
@@ -173,8 +175,10 @@ const HIDDEN_SUBTREE_DEFINITION = {
isExpanded: true,
attributes: [ { type: 'label', name: 'docName', value: 'launchbar_intro' } ],
children: [
{ id: '_lbBackInHistory', title: 'Go to Previous Note', type: 'launcher', builtinWidget: 'backInHistoryButton', icon: 'bx bxs-left-arrow-square' },
{ id: '_lbForwardInHistory', title: 'Go to Next Note', type: 'launcher', builtinWidget: 'forwardInHistoryButton', icon: 'bx bxs-right-arrow-square' },
{ id: '_lbBackInHistory', title: 'Go to Previous Note', type: 'launcher', builtinWidget: 'backInHistoryButton', icon: 'bx bxs-left-arrow-square',
attributes: [ { type: 'label', name: 'docName', value: 'launchbar_history_navigation' } ]},
{ id: '_lbForwardInHistory', title: 'Go to Next Note', type: 'launcher', builtinWidget: 'forwardInHistoryButton', icon: 'bx bxs-right-arrow-square',
attributes: [ { type: 'label', name: 'docName', value: 'launchbar_history_navigation' } ]},
{ id: '_lbBackendLog', title: 'Backend Log', type: 'launcher', targetNoteId: '_backendLog', icon: 'bx bx-terminal' },
]
},
@@ -230,7 +234,13 @@ const HIDDEN_SUBTREE_DEFINITION = {
]
};
function checkHiddenSubtree() {
function checkHiddenSubtree(force = false) {
if (!force && !migrationService.isDbUpToDate()) {
// on-delete hook might get triggered during some future migration and cause havoc
log.info("Will not check hidden subtree until migration is finished.");
return;
}
checkHiddenSubtreeRecursively('root', HIDDEN_SUBTREE_DEFINITION);
}

View File

@@ -76,8 +76,8 @@ function importEnex(taskContext, file, parentNote) {
content = content.replace(/<\/ol>\s*<li>/g, "</ol></li><li>");
// Replace en-todo with unicode ballot box
content = content.replace(/<en-todo\s+checked="true"\/>/g, "\u2611 ");
content = content.replace(/<en-todo(\s+checked="false")?\/>/g, "\u2610 ");
content = content.replace(/<en-todo\s+checked="true"\s*\/>/g, "\u2611 ");
content = content.replace(/<en-todo(\s+checked="false")?\s*\/>/g, "\u2610 ");
// Replace OneNote converted checkboxes with unicode ballot box based
// on known hash of checkboxes for regular, p1, and p2 checkboxes

View File

@@ -119,5 +119,6 @@ async function migrateIfNecessary() {
}
module.exports = {
migrateIfNecessary
migrateIfNecessary,
isDbUpToDate
};

View File

@@ -108,9 +108,14 @@ function getAndValidateParent(params) {
throw new ValidationError(`Only 'launcher' notes can be created in parent '${params.parentNoteId}'`);
}
if (!params.ignoreForbiddenParents && (['_lbRoot', '_hidden'].includes(parentNote.noteId) || parentNote.isOptions())) {
if (!params.ignoreForbiddenParents) {
if (['_lbRoot', '_hidden'].includes(parentNote.noteId)
|| parentNote.noteId.startsWith("_lbTpl")
|| parentNote.isOptions()) {
throw new ValidationError(`Creating child notes into '${parentNote.noteId}' is not allowed.`);
}
}
return parentNote;
}
@@ -281,8 +286,12 @@ function protectNote(note, protect) {
note.isProtected = protect;
// see https://github.com/zadam/trilium/issues/3523
// IIRC a zero-sized buffer can be returned as null from the database
if (content !== null) {
// this will force de/encryption
note.setContent(content);
}
note.save();
}
@@ -590,11 +599,6 @@ function updateNoteContent(noteId, content) {
content = saveLinks(note, content);
note.setContent(content);
eventService.emit(eventService.ENTITY_CHANGED, {
entityName: 'note_contents',
entity: note
});
}
/**

View File

@@ -0,0 +1,25 @@
const scheduledExecutions = {};
/**
* Subsequent calls will not move the timer to future. The first caller determines the time of execution.
*
* The good thing about synchronous better-sqlite3 is that this cannot interrupt transaction. The execution will be called
* only outside of a transaction.
*/
function scheduleExecution(name, milliseconds, cb) {
if (name in scheduledExecutions) {
return;
}
scheduledExecutions[name] = true;
setTimeout(() => {
delete scheduledExecutions[name];
cb();
}, milliseconds);
}
module.exports = {
scheduleExecution
};

View File

@@ -0,0 +1,23 @@
"use strict";
const Expression = require('./expression');
const NoteSet = require('../note_set');
/**
* Note is hidden when all its note paths start in hidden subtree (i.e. the note is not cloned into visible tree)
*/
class IsHiddenExp extends Expression {
execute(inputNoteSet, executionContext, searchContext) {
const resultNoteSet = new NoteSet();
for (const note of inputNoteSet.notes) {
if (note.isHiddenCompletely()) {
resultNoteSet.add(note);
}
}
return resultNoteSet;
}
}
module.exports = IsHiddenExp;

View File

@@ -6,10 +6,11 @@ class SearchContext {
constructor(params = {}) {
this.fastSearch = !!params.fastSearch;
this.includeArchivedNotes = !!params.includeArchivedNotes;
this.includeHiddenNotes = !!params.includeHiddenNotes;
this.ignoreHoistedNote = !!params.ignoreHoistedNote;
this.ancestorNoteId = params.ancestorNoteId;
if (!this.ancestorNoteId && !this.ignoreHoistedNote && !hoistedNoteService.isHoistedInHiddenSubtree()) {
if (!this.ancestorNoteId && !this.ignoreHoistedNote) {
// hoisting in hidden subtree should not limit autocomplete
// since we want to link (create relations) to the normal non-hidden notes
this.ancestorNoteId = hoistedNoteService.getHoistedNoteId();

View File

@@ -18,7 +18,8 @@ const AncestorExp = require("../expressions/ancestor");
const buildComparator = require('./build_comparator');
const ValueExtractor = require('../value_extractor');
const utils = require("../../utils");
const TrueExp = require("../expressions/true.js");
const TrueExp = require("../expressions/true");
const IsHiddenExp = require("../expressions/is_hidden");
function getFulltext(tokens, searchContext) {
tokens = tokens.map(t => utils.removeDiacritic(t.token));
@@ -429,7 +430,7 @@ function parse({fulltextTokens, expressionTokens, searchContext}) {
let exp = AndExp.of([
searchContext.includeArchivedNotes ? null : new PropertyComparisonExp(searchContext, "isarchived", "=", "false"),
(searchContext.ancestorNoteId && searchContext.ancestorNoteId !== 'root') ? new AncestorExp(searchContext.ancestorNoteId, searchContext.ancestorDepth) : null,
getAncestorExp(searchContext),
getFulltext(fulltextTokens, searchContext),
expression
]);
@@ -448,4 +449,14 @@ function parse({fulltextTokens, expressionTokens, searchContext}) {
return exp;
}
function getAncestorExp({ancestorNoteId, ancestorDepth, includeHiddenNotes}) {
if (ancestorNoteId && ancestorNoteId !== 'root') {
return new AncestorExp(ancestorNoteId, ancestorDepth);
} else if (!includeHiddenNotes) {
return new NotExp(new IsHiddenExp());
} else {
return null;
}
}
module.exports = parse;

View File

@@ -11,6 +11,7 @@ const beccaService = require('../../../becca/becca_service');
const utils = require('../../utils');
const log = require('../../log');
const scriptService = require("../../script");
const hoistedNoteService = require("../../hoisted_note");
function searchFromNote(note) {
let searchResultNoteIds, highlightedTokens;
@@ -271,7 +272,11 @@ function searchNotesForAutocomplete(query) {
const searchContext = new SearchContext({
fastSearch: true,
includeArchivedNotes: false,
fuzzyAttributeSearch: true
includeHiddenNotes: true,
fuzzyAttributeSearch: true,
ancestorNoteId: hoistedNoteService.isHoistedInHiddenSubtree()
? 'root'
: hoistedNoteService.getHoistedNoteId()
});
const allSearchResults = findResultsWithQuery(query, searchContext);

View File

@@ -218,7 +218,7 @@ function resetLauncher(noteId) {
log.info(`Note ${noteId} is not a resettable launcher note.`);
}
hiddenSubtreeService.checkHiddenSubtree();
// the re-building deleted launchers will be done in handlers
}
/**

View File

@@ -2,6 +2,7 @@ const {JSDOM} = require("jsdom");
const shaca = require("./shaca/shaca");
const assetPath = require("../services/asset_path");
const shareRoot = require('./share_root');
const escapeHtml = require('escape-html');
function getContent(note) {
if (note.isProtected) {
@@ -112,17 +113,17 @@ function renderCode(result) {
function renderMermaid(result) {
result.content = `
<div class="mermaid">${result.content}</div>
<div class="mermaid">${escapeHtml(result.content)}</div>
<hr>
<details>
<summary>Chart source</summary>
<pre>${result.content}</pre>
<pre>${escapeHtml(result.content)}</pre>
</details>`
result.header += `<script src="../../${assetPath}/libraries/mermaid.min.js"></script>`;
}
function renderImage(result, note) {
result.content = `<img src="api/images/${note.noteId}/${note.title}?${note.utcDateModified}">`;
result.content = `<img src="api/images/${note.noteId}/${note.escapedTitle}?${note.utcDateModified}">`;
}
function renderFile(note, result) {