Merge branch 'master' into dev

# Conflicts:
#	src/routes/api/sender.js
#	src/services/import/enex.js
This commit is contained in:
zadam 2023-01-09 23:02:19 +01:00
commit 87636f27ba
9 changed files with 47 additions and 23 deletions

View file

@ -13,10 +13,10 @@
"url": "https://github.com/zadam/trilium.git"
},
"scripts": {
"start-server": "cross-env TRILIUM_DATA_DIR=./data TRILIUM_ENV=dev node ./src/www",
"start-server-no-dir": "cross-env TRILIUM_ENV=dev node ./src/www",
"start-electron": "cross-env TRILIUM_DATA_DIR=./data TRILIUM_ENV=dev electron --inspect=5858 .",
"start-electron-no-dir": "cross-env TRILIUM_ENV=dev electron --inspect=5858 .",
"start-server": "cross-env TRILIUM_DATA_DIR=./data TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 node ./src/www",
"start-server-no-dir": "cross-env TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 node ./src/www",
"start-electron": "cross-env TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev electron --inspect=5858 .",
"start-electron-no-dir": "cross-env TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 electron --inspect=5858 .",
"switch-server": "rm -rf ./node_modules/better-sqlite3 && npm install",
"switch-electron": "rm -rf ./node_modules/better-sqlite3 && npm install && ./node_modules/.bin/electron-rebuild",
"build-api-docs": "./bin/build-api-docs.sh",

View file

@ -477,13 +477,13 @@ export default class TabManager extends Component {
this.openAndActivateEmptyTab();
}
async removeAllTabsCommand() {
async closeAllTabsCommand() {
for (const ntxIdToRemove of this.mainNoteContexts.map(nc => nc.ntxId)) {
await this.removeNoteContext(ntxIdToRemove);
}
}
async removeAllTabsExceptForThisCommand({ntxId}) {
async closeOtherTabsCommand({ntxId}) {
for (const ntxIdToRemove of this.mainNoteContexts.map(nc => nc.ntxId)) {
if (ntxIdToRemove !== ntxId) {
await this.removeNoteContext(ntxIdToRemove);
@ -491,6 +491,10 @@ export default class TabManager extends Component {
}
}
async closeTabCommand({ntxId}) {
await this.removeNoteContext(ntxId);
}
async moveTabToNewWindowCommand({ntxId}) {
const {notePath, hoistedNoteId} = this.getNoteContextById(ntxId);

View file

@ -7,6 +7,7 @@ import openService from "./open.js";
import froca from "./froca.js";
import utils from "./utils.js";
import linkService from "./link.js";
import treeService from "./tree.js";
let idCounter = 1;
@ -31,6 +32,17 @@ async function getRenderedContent(note, options = {}) {
renderMathInElement($renderedContent[0], {trust: true});
}
const getNoteIdFromLink = el => treeService.getNoteIdFromNotePath($(el).attr('href'));
const referenceLinks = $renderedContent.find("a.reference-link");
const noteIdsToPrefetch = referenceLinks.map(el => getNoteIdFromLink(el));
await froca.getNotes(noteIdsToPrefetch);
for (const el of referenceLinks) {
const noteId = getNoteIdFromLink(el);
await linkService.loadReferenceLinkTitle(noteId, $(el));
}
}
else {
await renderChildrenList($renderedContent, note);

View file

@ -460,7 +460,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
if (dataTransfer && dataTransfer.files && dataTransfer.files.length > 0) {
const files = [...dataTransfer.files]; // chrome has issue that dataTransfer.files empties after async operation
const importService = await import('../services/import');
const importService = await import('../services/import.js');
importService.uploadFiles(node.data.noteId, files, {
safeImport: true,

View file

@ -262,9 +262,10 @@ export default class TabRowWidget extends BasicWidget {
x: e.pageX,
y: e.pageY,
items: [
{title: "Move this tab to a new window", command: "moveTabToNewWindow", uiIcon: "bx bx-window-open"},
{title: "Close all tabs", command: "removeAllTabs", uiIcon: "bx bx-x"},
{title: "Close all tabs except for this", command: "removeAllTabsExceptForThis", uiIcon: "bx bx-x"},
{title: "Close", command: "closeTab", uiIcon: "bx bx-x"},
{title: "Close other tabs", command: "closeOtherTabs", uiIcon: "bx bx-x"},
{title: "Close all tabs", command: "closeAllTabs", uiIcon: "bx bx-x"},
{title: "Move this tab to a new window", command: "moveTabToNewWindow", uiIcon: "bx bx-window-open"}
],
selectMenuItemHandler: ({command}) => {
this.triggerCommand(command, {ntxId});

View file

@ -172,7 +172,7 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget {
this.watchdog.editor.model.document.on('change:data', () => this.spacedUpdate.scheduleUpdate());
if (glob.isDev && ENABLE_INSPECTOR) {
await import(/* webpackIgnore: true */'../../../libraries/ckeditor/inspector');
await import(/* webpackIgnore: true */'../../../libraries/ckeditor/inspector.js');
CKEditorInspector.attach(this.watchdog.editor);
}
}

View file

@ -2,10 +2,9 @@
const imageType = require('image-type');
const imageService = require('../../services/image');
const dateNoteService = require('../../services/date_notes');
const noteService = require('../../services/notes');
const attributeService = require('../../services/attributes');
const {sanitizeAttributeName} = require("../../services/sanitize_attribute_name");
const {sanitizeAttributeName} = require("../../services/sanitize_attribute_name.js");
const specialNotesService = require("../../services/special_notes.js");
function uploadImage(req) {
const file = req.file;
@ -16,7 +15,7 @@ function uploadImage(req) {
const originalName = `Sender image.${imageType(file.buffer).ext}`;
const parentNote = dateNoteService.getDayNote(req.headers['x-local-date']);
const parentNote = specialNotesService.getInboxNote(req.headers['x-local-date']);
const {note, noteId} = imageService.saveImage(parentNote.noteId, file.buffer, originalName, true);
@ -38,7 +37,7 @@ function uploadImage(req) {
}
function saveNote(req) {
const parentNote = dateNoteService.getDayNote(req.headers['x-local-date']);
const parentNote = specialNotesService.getInboxNote(req.headers['x-local-date']);
const {note, branch} = noteService.createNewNote({
parentNoteId: parentNote.noteId,

View file

@ -8,13 +8,19 @@ const noteService = require("../notes");
const imageService = require("../image");
const protectedSessionService = require('../protected_session');
const htmlSanitizer = require("../html_sanitizer");
const attributeService = require("../attributes");
const {sanitizeAttributeName} = require("../sanitize_attribute_name");
const {sanitizeAttributeName} = require("../sanitize_attribute_name.js");
// date format is e.g. 20181121T193703Z
/**
* date format is e.g. 20181121T193703Z or 2013-04-14T16:19:00.000Z (Mac evernote, see #3496)
* @returns trilium date format, e.g. 2013-04-14 16:19:00.000Z
*/
function parseDate(text) {
// insert - and : to make it ISO format
text = `${text.substr(0, 4)}-${text.substr(4, 2)}-${text.substr(6, 2)} ${text.substr(9, 2)}:${text.substr(11, 2)}:${text.substr(13, 2)}.000Z`;
// convert ISO format to the "20181121T193703Z" format
text = text.replace(/[-:]/g, "");
// insert - and : to convert it to trilium format
text = text.substr(0, 4) + "-" + text.substr(4, 2) + "-" + text.substr(6, 2)
+ " " + text.substr(9, 2) + ":" + text.substr(11, 2) + ":" + text.substr(13, 2) + ".000Z";
return text;
}
@ -263,7 +269,7 @@ function importEnex(taskContext, file, parentNote) {
continue;
}
const mediaRegex = new RegExp(`<en-media hash="${hash}"[^>]*>`, 'g');
const mediaRegex = new RegExp(`<en-media [^>]*hash="${hash}"[^>]*>`, 'g');
resource.mime = resource.mime || "application/octet-stream";

View file

@ -15,7 +15,9 @@ function get(name) {
}
module.exports = {
getSyncServerHost: () => get('syncServerHost'),
// env variable is the easiest way to guarantee we won't overwrite prod data during development
// after copying prod document/data directory
getSyncServerHost: () => process.env.TRILIUM_SYNC_SERVER_HOST || get('syncServerHost'),
isSyncSetup: () => {
const syncServerHost = get('syncServerHost');