Merge branch 'feature/typescript_backend_3' into feature/typescript_backend_4

This commit is contained in:
Elian Doran
2024-04-02 23:57:01 +03:00
49 changed files with 2356 additions and 5814 deletions

View File

@@ -20,7 +20,7 @@ function getBlobPojo(entityName: string, entityId: string) {
if (!entity.hasStringContent()) {
pojo.content = null;
} else {
pojo.content = processContent(pojo.content, entity.isProtected, true);
pojo.content = processContent(pojo.content, !!entity.isProtected, true);
}
return pojo;

View File

@@ -1 +1 @@
export = { buildDate:"2024-01-21T23:49:23+01:00", buildRevision: "4f8073daa7cff1b8b6737ae45792b2e87c2adf33" };
export = { buildDate:"2024-03-28T07:11:39+01:00", buildRevision: "399458b52f250b22be22d980a78de0b3390d7521" };

View File

@@ -20,6 +20,6 @@ export interface EntityRow {
}
export interface EntityChangeRecord {
entityChange: EntityChange;
entity?: EntityRow;
entityChange: EntityChange;
entity?: EntityRow;
}

View File

@@ -1,15 +1,15 @@
interface DefinitionObject {
isPromoted: boolean;
labelType: string;
multiplicity: string;
numberPrecision: number;
promotedAlias: string;
inverseRelation: string;
isPromoted?: boolean;
labelType?: string;
multiplicity?: string;
numberPrecision?: number;
promotedAlias?: string;
inverseRelation?: string;
}
function parse(value: string): DefinitionObject {
const tokens = value.split(',').map(t => t.trim());
const defObj: Partial<DefinitionObject> = {};
const defObj: DefinitionObject = {};
for (const token of tokens) {
if (token === 'promoted') {
@@ -41,7 +41,7 @@ function parse(value: string): DefinitionObject {
}
}
return defObj as DefinitionObject;
return defObj;
}
export = {

View File

@@ -128,11 +128,7 @@ class NoteContentFulltextExp extends Expression {
if (type === 'text' && mime === 'text/html') {
if (!this.raw && content.length < 20000) { // striptags is slow for very large notes
// allow link to preserve URLs: https://github.com/zadam/trilium/issues/2412
content = striptags(content, ['a'], ' ');
// at least the closing tag can be easily stripped
content = content.replace(/<\/a>/ig, "");
content = this.stripTags(content);
}
content = content.replace(/&nbsp;/g, ' ');
@@ -140,6 +136,23 @@ class NoteContentFulltextExp extends Expression {
return content.trim();
}
stripTags(content: string) {
// we want to allow link to preserve URLs: https://github.com/zadam/trilium/issues/2412
// we want to insert space in place of block tags (because they imply text separation)
// but we don't want to insert text for typical formatting inline tags which can occur within one word
const linkTag = 'a';
const inlineFormattingTags = ['b', 'strong', 'em', 'i', 'span', 'big', 'small', 'font', 'sub', 'sup'];
// replace tags which imply text separation with a space
content = striptags(content, [linkTag, ...inlineFormattingTags], ' ');
// replace the inline formatting tags (but not links) without a space
content = striptags(content, [linkTag], '');
// at least the closing link tag can be easily stripped
return content.replace(/<\/a>/ig, "");
}
}
export = NoteContentFulltextExp;

View File

@@ -25,7 +25,7 @@ class OrderByAndLimitExp extends Expression {
constructor(orderDefinitions: Pick<OrderDefinition, "direction" | "valueExtractor">[], limit?: number) {
super();
this.orderDefinitions = orderDefinitions as unknown as OrderDefinition[];
this.orderDefinitions = orderDefinitions as OrderDefinition[];
for (const od of this.orderDefinitions) {
od.smaller = od.direction === "asc" ? -1 : 1;

View File

@@ -51,9 +51,7 @@ class SearchResult {
addScoreForStrings(tokens: string[], str: string, factor: number) {
const chunks = str.toLowerCase().split(" ");
if (!this.score) {
this.score = 0;
}
this.score = 0;
for (const chunk of chunks) {
for (const token of tokens) {

View File

@@ -113,7 +113,7 @@ class ValueExtractor {
i++;
const attr = cursor.getAttributeCaseInsensitive('relation', cur());
cursor = (attr ? attr.targetNote || null : null);
cursor = attr?.targetNote || null;
}
else if (cur() === 'parents') {
cursor = cursor.parents[0];

View File

@@ -57,7 +57,7 @@ class TaskContext {
type: 'taskProgressCount',
taskId: this.taskId,
taskType: this.taskType,
data: this.data || undefined,
data: this.data,
progressCount: this.progressCount
});
}
@@ -68,7 +68,7 @@ class TaskContext {
type: 'taskError',
taskId: this.taskId,
taskType: this.taskType,
data: this.data || undefined,
data: this.data,
message: message
});
}
@@ -78,7 +78,7 @@ class TaskContext {
type: 'taskSucceeded',
taskId: this.taskId,
taskType: this.taskType,
data: this.data || undefined,
data: this.data,
result: result
});
}

View File

@@ -3,11 +3,7 @@ import path = require('path');
import windowService = require('./window');
import optionService = require('./options');
const UPDATE_TRAY_EVENTS = [
'minimize', 'maximize', 'show', 'hide'
] as const;
let tray: Tray | null = null;
let tray: Tray;
// `mainWindow.isVisible` doesn't work with `mainWindow.show` and `mainWindow.hide` - it returns `false` when the window
// is minimized
let isVisible = true;
@@ -42,14 +38,15 @@ const registerVisibilityListener = () => {
// They need to be registered before the tray updater is registered
mainWindow.on('show', () => {
isVisible = true;
updateTrayMenu();
});
mainWindow.on('hide', () => {
isVisible = false;
updateTrayMenu();
});
UPDATE_TRAY_EVENTS.forEach((eventName) => {
mainWindow.on(eventName as any, updateTrayMenu)
});
mainWindow.on("minimize", updateTrayMenu);
mainWindow.on("maximize", updateTrayMenu);
}
const updateTrayMenu = () => {

View File

@@ -17,7 +17,7 @@ let setupWindow: BrowserWindow | null;
async function createExtraWindow(extraWindowHash: string) {
const spellcheckEnabled = optionService.getOptionBool('spellCheckEnabled');
const {BrowserWindow} = require('electron');
const { BrowserWindow } = require('electron');
const win = new BrowserWindow({
width: 1000,
@@ -53,7 +53,7 @@ async function createMainWindow(app: App) {
const spellcheckEnabled = optionService.getOptionBool('spellCheckEnabled');
const {BrowserWindow} = require('electron'); // should not be statically imported
const { BrowserWindow } = require('electron'); // should not be statically imported
mainWindow = new BrowserWindow({
x: mainWindowState.x,
@@ -128,7 +128,7 @@ function getIcon() {
}
async function createSetupWindow() {
const {BrowserWindow} = require('electron'); // should not be statically imported
const { BrowserWindow } = require('electron'); // should not be statically imported
setupWindow = new BrowserWindow({
width: 800,
height: 800,
@@ -152,7 +152,7 @@ function closeSetupWindow() {
}
async function registerGlobalShortcuts() {
const {globalShortcut} = require('electron');
const { globalShortcut } = require('electron');
await sqlInit.dbReady;

View File

@@ -29,11 +29,11 @@ let lastSyncedPush: number | null = null;
interface Message {
type: string;
data?: {
lastSyncedPush?: number,
lastSyncedPush?: number | null,
entityChanges?: any[],
safeImport?: boolean
},
lastSyncedPush?: number,
lastSyncedPush?: number | null,
progressCount?: number;
taskId?: string;
@@ -143,7 +143,7 @@ function fillInAdditionalProperties(entityChange: EntityChange) {
if (!entityChange.entity) {
entityChange.entity = sql.getRow(`SELECT * FROM notes WHERE noteId = ?`, [entityChange.entityId]);
if (entityChange.entity && entityChange.entity.isProtected) {
if (entityChange.entity?.isProtected) {
entityChange.entity.title = protectedSessionService.decryptString(entityChange.entity.title || "");
}
}
@@ -158,7 +158,7 @@ function fillInAdditionalProperties(entityChange: EntityChange) {
if (parentNote) {
for (const childBranch of parentNote.getChildBranches()) {
if (childBranch && childBranch.branchId) {
if (childBranch?.branchId) {
entityChange.positions[childBranch.branchId] = childBranch.notePosition;
}
}
@@ -223,7 +223,7 @@ function sendPing(client: WebSocket, entityChangeIds = []) {
sendMessage(client, {
type: 'frontend-update',
data: {
lastSyncedPush: lastSyncedPush || undefined,
lastSyncedPush,
entityChanges
}
});
@@ -238,19 +238,19 @@ function sendTransactionEntityChangesToAllClients() {
}
function syncPullInProgress() {
sendMessageToAllClients({ type: 'sync-pull-in-progress', lastSyncedPush: lastSyncedPush || undefined });
sendMessageToAllClients({ type: 'sync-pull-in-progress', lastSyncedPush });
}
function syncPushInProgress() {
sendMessageToAllClients({ type: 'sync-push-in-progress', lastSyncedPush: lastSyncedPush || undefined });
sendMessageToAllClients({ type: 'sync-push-in-progress', lastSyncedPush });
}
function syncFinished() {
sendMessageToAllClients({ type: 'sync-finished', lastSyncedPush: lastSyncedPush || undefined });
sendMessageToAllClients({ type: 'sync-finished', lastSyncedPush });
}
function syncFailed() {
sendMessageToAllClients({ type: 'sync-failed', lastSyncedPush: lastSyncedPush || undefined });
sendMessageToAllClients({ type: 'sync-failed', lastSyncedPush });
}
function reloadFrontend(reason: string) {