mirror of
https://github.com/zadam/trilium.git
synced 2025-10-29 09:16:45 +01:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d243880099 | ||
|
|
2e23c521c3 | ||
|
|
eb761b286f | ||
|
|
d0f6ff5f98 | ||
|
|
84feaabc52 | ||
|
|
a6036859b8 | ||
|
|
93dcce2217 | ||
|
|
686af0c6a1 | ||
|
|
d07f02b95f | ||
|
|
ad74952194 | ||
|
|
10f3df3ed4 | ||
|
|
18e2e6779b | ||
|
|
ed129c307b | ||
|
|
8742e4bfe9 |
18
package-lock.json
generated
18
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "trilium",
|
"name": "trilium",
|
||||||
"version": "0.62.1-beta",
|
"version": "0.62.3",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "trilium",
|
"name": "trilium",
|
||||||
"version": "0.62.1-beta",
|
"version": "0.62.3",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "AGPL-3.0-only",
|
"license": "AGPL-3.0-only",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -81,7 +81,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"cross-env": "7.0.3",
|
"cross-env": "7.0.3",
|
||||||
"electron": "25.9.5",
|
"electron": "25.9.8",
|
||||||
"electron-builder": "24.6.4",
|
"electron-builder": "24.6.4",
|
||||||
"electron-packager": "17.1.2",
|
"electron-packager": "17.1.2",
|
||||||
"electron-rebuild": "3.2.9",
|
"electron-rebuild": "3.2.9",
|
||||||
@@ -4366,9 +4366,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/electron": {
|
"node_modules/electron": {
|
||||||
"version": "25.9.5",
|
"version": "25.9.8",
|
||||||
"resolved": "https://registry.npmjs.org/electron/-/electron-25.9.5.tgz",
|
"resolved": "https://registry.npmjs.org/electron/-/electron-25.9.8.tgz",
|
||||||
"integrity": "sha512-gM7GXUSd3JVRcYbBnNOtZeNnE5MCJjtZTT8QyIxJvpQ0Dh9dz3hTuEL62dOwnMFW/l47ACQ6es/8qi01P4QGZA==",
|
"integrity": "sha512-PGgp6PH46QVENHuAHc2NT1Su8Q1qov7qIl2jI5tsDpTibwV2zD8539AeWBQySeBU4dhbj9onIl7+1bXQ0wefBg==",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@electron/get": "^2.0.0",
|
"@electron/get": "^2.0.0",
|
||||||
@@ -16964,9 +16964,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"electron": {
|
"electron": {
|
||||||
"version": "25.9.5",
|
"version": "25.9.8",
|
||||||
"resolved": "https://registry.npmjs.org/electron/-/electron-25.9.5.tgz",
|
"resolved": "https://registry.npmjs.org/electron/-/electron-25.9.8.tgz",
|
||||||
"integrity": "sha512-gM7GXUSd3JVRcYbBnNOtZeNnE5MCJjtZTT8QyIxJvpQ0Dh9dz3hTuEL62dOwnMFW/l47ACQ6es/8qi01P4QGZA==",
|
"integrity": "sha512-PGgp6PH46QVENHuAHc2NT1Su8Q1qov7qIl2jI5tsDpTibwV2zD8539AeWBQySeBU4dhbj9onIl7+1bXQ0wefBg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@electron/get": "^2.0.0",
|
"@electron/get": "^2.0.0",
|
||||||
"@types/node": "^18.11.18",
|
"@types/node": "^18.11.18",
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"name": "trilium",
|
"name": "trilium",
|
||||||
"productName": "Trilium Notes",
|
"productName": "Trilium Notes",
|
||||||
"description": "Trilium Notes",
|
"description": "Trilium Notes",
|
||||||
"version": "0.62.2",
|
"version": "0.62.4",
|
||||||
"license": "AGPL-3.0-only",
|
"license": "AGPL-3.0-only",
|
||||||
"main": "electron.js",
|
"main": "electron.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -104,7 +104,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"cross-env": "7.0.3",
|
"cross-env": "7.0.3",
|
||||||
"electron": "25.9.5",
|
"electron": "25.9.8",
|
||||||
"electron-builder": "24.6.4",
|
"electron-builder": "24.6.4",
|
||||||
"electron-packager": "17.1.2",
|
"electron-packager": "17.1.2",
|
||||||
"electron-rebuild": "3.2.9",
|
"electron-rebuild": "3.2.9",
|
||||||
|
|||||||
@@ -117,14 +117,14 @@ async function renderCode(note, $renderedContent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function renderImage(entity, $renderedContent, options = {}) {
|
function renderImage(entity, $renderedContent, options = {}) {
|
||||||
const sanitizedTitle = entity.title.replace(/[^a-z0-9-.]/gi, "");
|
const encodedTitle = encodeURIComponent(entity.title);
|
||||||
|
|
||||||
let url;
|
let url;
|
||||||
|
|
||||||
if (entity instanceof FNote) {
|
if (entity instanceof FNote) {
|
||||||
url = `api/images/${entity.noteId}/${sanitizedTitle}?${Math.random()}`;
|
url = `api/images/${entity.noteId}/${encodedTitle}?${Math.random()}`;
|
||||||
} else if (entity instanceof FAttachment) {
|
} else if (entity instanceof FAttachment) {
|
||||||
url = `api/attachments/${entity.attachmentId}/image/${sanitizedTitle}?${entity.utcDateModified}">`;
|
url = `api/attachments/${entity.attachmentId}/image/${encodedTitle}?${entity.utcDateModified}">`;
|
||||||
}
|
}
|
||||||
|
|
||||||
$renderedContent // styles needed for the zoom to work well
|
$renderedContent // styles needed for the zoom to work well
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ async function createLink(notePath, options = {}) {
|
|||||||
const showNotePath = options.showNotePath === undefined ? false : options.showNotePath;
|
const showNotePath = options.showNotePath === undefined ? false : options.showNotePath;
|
||||||
const showNoteIcon = options.showNoteIcon === undefined ? false : options.showNoteIcon;
|
const showNoteIcon = options.showNoteIcon === undefined ? false : options.showNoteIcon;
|
||||||
const referenceLink = options.referenceLink === undefined ? false : options.referenceLink;
|
const referenceLink = options.referenceLink === undefined ? false : options.referenceLink;
|
||||||
|
const autoConvertToImage = options.autoConvertToImage === undefined ? false : options.autoConvertToImage;
|
||||||
|
|
||||||
const { noteId, parentNoteId } = treeService.getNoteIdAndParentIdFromUrl(notePath);
|
const { noteId, parentNoteId } = treeService.getNoteIdAndParentIdFromUrl(notePath);
|
||||||
const viewScope = options.viewScope || {};
|
const viewScope = options.viewScope || {};
|
||||||
@@ -58,6 +59,16 @@ async function createLink(notePath, options = {}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const note = await froca.getNote(noteId);
|
||||||
|
|
||||||
|
if (autoConvertToImage && ['image', 'canvas', 'mermaid'].includes(note.type) && viewMode === 'default') {
|
||||||
|
const encodedTitle = encodeURIComponent(linkTitle);
|
||||||
|
|
||||||
|
return $("<img>")
|
||||||
|
.attr("src", `api/images/${noteId}/${encodedTitle}?${Math.random()}`)
|
||||||
|
.attr("alt", linkTitle);
|
||||||
|
}
|
||||||
|
|
||||||
const $container = $("<span>");
|
const $container = $("<span>");
|
||||||
|
|
||||||
if (showNoteIcon) {
|
if (showNoteIcon) {
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ export default class IncludeNoteDialog extends BasicWidget {
|
|||||||
|
|
||||||
const boxSize = $("input[name='include-note-box-size']:checked").val();
|
const boxSize = $("input[name='include-note-box-size']:checked").val();
|
||||||
|
|
||||||
if (note.type === 'image') {
|
if (['image', 'canvas', 'mermaid'].includes(note.type)) {
|
||||||
// there's no benefit to use insert note functionlity for images,
|
// there's no benefit to use insert note functionlity for images,
|
||||||
// so we'll just add an IMG tag
|
// so we'll just add an IMG tag
|
||||||
this.textTypeWidget.addImage(noteId);
|
this.textTypeWidget.addImage(noteId);
|
||||||
|
|||||||
@@ -274,16 +274,16 @@ export default class RevisionsDialog extends BasicWidget {
|
|||||||
|
|
||||||
this.$content.html($table);
|
this.$content.html($table);
|
||||||
} else if (revisionItem.type === 'canvas') {
|
} else if (revisionItem.type === 'canvas') {
|
||||||
const sanitizedTitle = revisionItem.title.replace(/[^a-z0-9-.]/gi, "");
|
const encodedTitle = encodeURIComponent(revisionItem.title);
|
||||||
|
|
||||||
this.$content.html($("<img>")
|
this.$content.html($("<img>")
|
||||||
.attr("src", `api/revisions/${revisionItem.revisionId}/image/${sanitizedTitle}?${Math.random()}`)
|
.attr("src", `api/revisions/${revisionItem.revisionId}/image/${encodedTitle}?${Math.random()}`)
|
||||||
.css("max-width", "100%"));
|
.css("max-width", "100%"));
|
||||||
} else if (revisionItem.type === 'mermaid') {
|
} else if (revisionItem.type === 'mermaid') {
|
||||||
const sanitizedTitle = revisionItem.title.replace(/[^a-z0-9-.]/gi, "");
|
const encodedTitle = encodeURIComponent(revisionItem.title);
|
||||||
|
|
||||||
this.$content.html($("<img>")
|
this.$content.html($("<img>")
|
||||||
.attr("src", `api/revisions/${revisionItem.revisionId}/image/${sanitizedTitle}?${Math.random()}`)
|
.attr("src", `api/revisions/${revisionItem.revisionId}/image/${encodedTitle}?${Math.random()}`)
|
||||||
.css("max-width", "100%"));
|
.css("max-width", "100%"));
|
||||||
|
|
||||||
this.$content.append($("<pre>").text(fullRevision.content));
|
this.$content.append($("<pre>").text(fullRevision.content));
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ export default class HighlightsListWidget extends RightPanelWidget {
|
|||||||
.class("icon-action"),
|
.class("icon-action"),
|
||||||
new OnClickButtonWidget()
|
new OnClickButtonWidget()
|
||||||
.icon("bx-x")
|
.icon("bx-x")
|
||||||
.title("Close Highlights List")
|
|
||||||
.titlePlacement("left")
|
.titlePlacement("left")
|
||||||
.onClick(widget => widget.triggerCommand("closeHlt"))
|
.onClick(widget => widget.triggerCommand("closeHlt"))
|
||||||
.class("icon-action")
|
.class("icon-action")
|
||||||
|
|||||||
@@ -258,10 +258,11 @@ export default class NoteDetailWidget extends NoteContextAwareWidget {
|
|||||||
.append($("<h2>").text(this.note.title))
|
.append($("<h2>").text(this.note.title))
|
||||||
.append($promotedAttributes)
|
.append($promotedAttributes)
|
||||||
.prop('outerHTML'),
|
.prop('outerHTML'),
|
||||||
|
|
||||||
footer: `
|
footer: `
|
||||||
<script src="${assetPath}/libraries/katex/katex.min.js"></script>
|
<script src="${assetPath}/node_modules/katex/dist/katex.min.js"></script>
|
||||||
<script src="${assetPath}/libraries/katex/mhchem.min.js"></script>
|
<script src="${assetPath}/node_modules/katex/dist/contrib/mhchem.min.js"></script>
|
||||||
<script src="${assetPath}/libraries/katex/auto-render.min.js"></script>
|
<script src="${assetPath}/node_modules/katex/dist/contrib/auto-render.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
document.body.className += ' ck-content printed-content';
|
document.body.className += ' ck-content printed-content';
|
||||||
|
|
||||||
@@ -273,7 +274,7 @@ export default class NoteDetailWidget extends NoteContextAwareWidget {
|
|||||||
`${assetPath}/libraries/codemirror/codemirror.css`,
|
`${assetPath}/libraries/codemirror/codemirror.css`,
|
||||||
`${assetPath}/libraries/ckeditor/ckeditor-content.css`,
|
`${assetPath}/libraries/ckeditor/ckeditor-content.css`,
|
||||||
`${assetPath}/libraries/bootstrap/css/bootstrap.min.css`,
|
`${assetPath}/libraries/bootstrap/css/bootstrap.min.css`,
|
||||||
`${assetPath}/libraries/katex/katex.min.css`,
|
`${assetPath}/node_modules/katex/dist/katex.min.css`,
|
||||||
`${assetPath}/stylesheets/print.css`,
|
`${assetPath}/stylesheets/print.css`,
|
||||||
`${assetPath}/stylesheets/relation_map.css`,
|
`${assetPath}/stylesheets/relation_map.css`,
|
||||||
`${assetPath}/stylesheets/ckeditor-theme.css`
|
`${assetPath}/stylesheets/ckeditor-theme.css`
|
||||||
|
|||||||
@@ -402,11 +402,11 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
if (notes.length === 1) {
|
if (notes.length === 1) {
|
||||||
linkService.createLink(notes[0].noteId, {referenceLink: true})
|
linkService.createLink(notes[0].noteId, {referenceLink: true, autoConvertToImage: true})
|
||||||
.then($link => data.dataTransfer.setData("text/html", $link[0].outerHTML));
|
.then($link => data.dataTransfer.setData("text/html", $link[0].outerHTML));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Promise.all(notes.map(note => linkService.createLink(note.noteId, {referenceLink: true}))).then(links => {
|
Promise.all(notes.map(note => linkService.createLink(note.noteId, {referenceLink: true, autoConvertToImage: true}))).then(links => {
|
||||||
const $list = $("<ul>").append(...links.map($link => $("<li>").append($link)));
|
const $list = $("<ul>").append(...links.map($link => $("<li>").append($link)));
|
||||||
|
|
||||||
data.dataTransfer.setData("text/html", $list[0].outerHTML);
|
data.dataTransfer.setData("text/html", $list[0].outerHTML);
|
||||||
|
|||||||
@@ -8,8 +8,14 @@ import options from "../../services/options.js";
|
|||||||
import utils from "../../services/utils.js";
|
import utils from "../../services/utils.js";
|
||||||
|
|
||||||
const TPL = `
|
const TPL = `
|
||||||
<div>
|
<div class="promoted-attributes-widget">
|
||||||
<style>
|
<style>
|
||||||
|
body.mobile .promoted-attributes-widget {
|
||||||
|
/* https://github.com/zadam/trilium/issues/4468 */
|
||||||
|
flex-shrink: 0.4;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.promoted-attributes-container {
|
.promoted-attributes-container {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -68,7 +68,6 @@ export default class TocWidget extends RightPanelWidget {
|
|||||||
.class("icon-action"),
|
.class("icon-action"),
|
||||||
new OnClickButtonWidget()
|
new OnClickButtonWidget()
|
||||||
.icon("bx-x")
|
.icon("bx-x")
|
||||||
.title("Close Table of Contents")
|
|
||||||
.titlePlacement("left")
|
.titlePlacement("left")
|
||||||
.onClick(widget => widget.triggerCommand("closeToc"))
|
.onClick(widget => widget.triggerCommand("closeToc"))
|
||||||
.class("icon-action")
|
.class("icon-action")
|
||||||
|
|||||||
@@ -365,12 +365,10 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget {
|
|||||||
const note = await froca.getNote(noteId);
|
const note = await froca.getNote(noteId);
|
||||||
|
|
||||||
this.watchdog.editor.model.change( writer => {
|
this.watchdog.editor.model.change( writer => {
|
||||||
const sanitizedTitle = note.title.replace(/[^a-z0-9-.]/gi, "");
|
const encodedTitle = encodeURIComponent(note.title);
|
||||||
const src = `api/images/${note.noteId}/${sanitizedTitle}`;
|
const src = `api/images/${note.noteId}/${encodedTitle}`;
|
||||||
|
|
||||||
const imageElement = writer.createElement( 'image', { 'src': src } );
|
this.watchdog.editor.execute( 'insertImage', { source: src } );
|
||||||
|
|
||||||
this.watchdog.editor.model.insertContent(imageElement, this.watchdog.editor.model.document.selection);
|
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -153,8 +153,9 @@ function processContent(images, note, content) {
|
|||||||
const buffer = Buffer.from(dataUrl.split(",")[1], 'base64');
|
const buffer = Buffer.from(dataUrl.split(",")[1], 'base64');
|
||||||
|
|
||||||
const attachment = imageService.saveImageToAttachment(note.noteId, buffer, filename, true);
|
const attachment = imageService.saveImageToAttachment(note.noteId, buffer, filename, true);
|
||||||
const sanitizedTitle = attachment.title.replace(/[^a-z0-9-.]/gi, "");
|
|
||||||
const url = `api/attachments/${attachment.attachmentId}/image/${sanitizedTitle}`;
|
const encodedTitle = encodeURIComponent(attachment.title);
|
||||||
|
const url = `api/attachments/${attachment.attachmentId}/image/${encodedTitle}`;
|
||||||
|
|
||||||
log.info(`Replacing '${imageId}' with '${url}' in note '${note.noteId}'`);
|
log.info(`Replacing '${imageId}' with '${url}' in note '${note.noteId}'`);
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ const cls = require('../../services/cls');
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
const becca = require("../../becca/becca");
|
const becca = require("../../becca/becca");
|
||||||
const blobService = require("../../services/blob");
|
const blobService = require("../../services/blob");
|
||||||
|
const eraseService = require("../../services/erase.js");
|
||||||
|
|
||||||
function getRevisionBlob(req) {
|
function getRevisionBlob(req) {
|
||||||
const preview = req.query.preview === 'true';
|
const preview = req.query.preview === 'true';
|
||||||
@@ -88,11 +89,11 @@ function eraseAllRevisions(req) {
|
|||||||
const revisionIdsToErase = sql.getColumn('SELECT revisionId FROM revisions WHERE noteId = ?',
|
const revisionIdsToErase = sql.getColumn('SELECT revisionId FROM revisions WHERE noteId = ?',
|
||||||
[req.params.noteId]);
|
[req.params.noteId]);
|
||||||
|
|
||||||
revisionService.eraseRevisions(revisionIdsToErase);
|
eraseService.eraseRevisions(revisionIdsToErase);
|
||||||
}
|
}
|
||||||
|
|
||||||
function eraseRevision(req) {
|
function eraseRevision(req) {
|
||||||
revisionService.eraseRevisions([req.params.revisionId]);
|
eraseService.eraseRevisions([req.params.revisionId]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function restoreRevision(req) {
|
function restoreRevision(req) {
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
module.exports = { buildDate:"2023-11-21T20:49:24+01:00", buildRevision: "e2b1421bf3d764ffe444a103c118e67d8c563673" };
|
module.exports = { buildDate:"2023-12-07T00:03:59+01:00", buildRevision: "2e23c521c356c2305124f5df0f474532fa5f34ce" };
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ const becca = require("../becca/becca");
|
|||||||
const cloningService = require("./cloning");
|
const cloningService = require("./cloning");
|
||||||
const branchService = require("./branches");
|
const branchService = require("./branches");
|
||||||
const utils = require("./utils");
|
const utils = require("./utils");
|
||||||
|
const eraseService = require("./erase.js");
|
||||||
|
|
||||||
const ACTION_HANDLERS = {
|
const ACTION_HANDLERS = {
|
||||||
addLabel: (action, note) => {
|
addLabel: (action, note) => {
|
||||||
@@ -18,7 +19,7 @@ const ACTION_HANDLERS = {
|
|||||||
note.deleteNote(deleteId);
|
note.deleteNote(deleteId);
|
||||||
},
|
},
|
||||||
deleteRevisions: (action, note) => {
|
deleteRevisions: (action, note) => {
|
||||||
revisionService.eraseRevisions(note.getRevisions().map(rev => rev.revisionId));
|
eraseService.eraseRevisions(note.getRevisions().map(rev => rev.revisionId));
|
||||||
},
|
},
|
||||||
deleteLabel: (action, note) => {
|
deleteLabel: (action, note) => {
|
||||||
for (const label of note.getOwnedLabels(action.labelName)) {
|
for (const label of note.getOwnedLabels(action.labelName)) {
|
||||||
|
|||||||
@@ -467,7 +467,7 @@ class ConsistencyChecks {
|
|||||||
WHERE blobs.blobId IS NULL`,
|
WHERE blobs.blobId IS NULL`,
|
||||||
({revisionId, blobId}) => {
|
({revisionId, blobId}) => {
|
||||||
if (this.autoFix) {
|
if (this.autoFix) {
|
||||||
revisionService.eraseRevisions([revisionId]);
|
eraseService.eraseRevisions([revisionId]);
|
||||||
|
|
||||||
this.reloadNeeded = true;
|
this.reloadNeeded = true;
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ function eraseNotes(noteIdsToErase) {
|
|||||||
const revisionIdsToErase = sql.getManyRows(`SELECT revisionId FROM revisions WHERE noteId IN (???)`, noteIdsToErase)
|
const revisionIdsToErase = sql.getManyRows(`SELECT revisionId FROM revisions WHERE noteId IN (???)`, noteIdsToErase)
|
||||||
.map(row => row.revisionId);
|
.map(row => row.revisionId);
|
||||||
|
|
||||||
revisionService.eraseRevisions(revisionIdsToErase);
|
eraseRevisions(revisionIdsToErase);
|
||||||
|
|
||||||
log.info(`Erased notes: ${JSON.stringify(noteIdsToErase)}`);
|
log.info(`Erased notes: ${JSON.stringify(noteIdsToErase)}`);
|
||||||
}
|
}
|
||||||
@@ -79,6 +79,18 @@ function eraseAttachments(attachmentIdsToErase) {
|
|||||||
log.info(`Erased attachments: ${JSON.stringify(attachmentIdsToErase)}`);
|
log.info(`Erased attachments: ${JSON.stringify(attachmentIdsToErase)}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function eraseRevisions(revisionIdsToErase) {
|
||||||
|
if (revisionIdsToErase.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sql.executeMany(`DELETE FROM revisions WHERE revisionId IN (???)`, revisionIdsToErase);
|
||||||
|
|
||||||
|
setEntityChangesAsErased(sql.getManyRows(`SELECT * FROM entity_changes WHERE entityName = 'revisions' AND entityId IN (???)`, revisionIdsToErase));
|
||||||
|
|
||||||
|
log.info(`Removed revisions: ${JSON.stringify(revisionIdsToErase)}`);
|
||||||
|
}
|
||||||
|
|
||||||
function eraseUnusedBlobs() {
|
function eraseUnusedBlobs() {
|
||||||
const unusedBlobIds = sql.getColumn(`
|
const unusedBlobIds = sql.getColumn(`
|
||||||
SELECT blobs.blobId
|
SELECT blobs.blobId
|
||||||
@@ -184,5 +196,6 @@ module.exports = {
|
|||||||
eraseUnusedAttachmentsNow,
|
eraseUnusedAttachmentsNow,
|
||||||
eraseNotesWithDeleteId,
|
eraseNotesWithDeleteId,
|
||||||
eraseUnusedBlobs,
|
eraseUnusedBlobs,
|
||||||
eraseAttachments
|
eraseAttachments,
|
||||||
|
eraseRevisions
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -303,8 +303,8 @@ function importEnex(taskContext, file, parentNote) {
|
|||||||
|
|
||||||
const attachment = imageService.saveImageToAttachment(noteEntity.noteId, resource.content, originalName, taskContext.data.shrinkImages);
|
const attachment = imageService.saveImageToAttachment(noteEntity.noteId, resource.content, originalName, taskContext.data.shrinkImages);
|
||||||
|
|
||||||
const sanitizedTitle = attachment.title.replace(/[^a-z0-9-.]/gi, "");
|
const encodedTitle = encodeURIComponent(attachment.title);
|
||||||
const url = `api/attachments/${attachment.attachmentId}/image/${sanitizedTitle}`;
|
const url = `api/attachments/${attachment.attachmentId}/image/${encodedTitle}`;
|
||||||
const imageLink = `<img src="${url}">`;
|
const imageLink = `<img src="${url}">`;
|
||||||
|
|
||||||
content = content.replace(mediaRegex, imageLink);
|
content = content.replace(mediaRegex, imageLink);
|
||||||
|
|||||||
@@ -529,9 +529,9 @@ function downloadImages(noteId, content) {
|
|||||||
const imageService = require('../services/image');
|
const imageService = require('../services/image');
|
||||||
const attachment = imageService.saveImageToAttachment(noteId, imageBuffer, "inline image", true, true);
|
const attachment = imageService.saveImageToAttachment(noteId, imageBuffer, "inline image", true, true);
|
||||||
|
|
||||||
const sanitizedTitle = attachment.title.replace(/[^a-z0-9-.]/gi, "");
|
const encodedTitle = encodeURIComponent(attachment.title);
|
||||||
|
|
||||||
content = `${content.substr(0, imageMatch.index)}<img src="api/attachments/${attachment.attachmentId}/image/${sanitizedTitle}"${content.substr(imageMatch.index + imageMatch[0].length)}`;
|
content = `${content.substr(0, imageMatch.index)}<img src="api/attachments/${attachment.attachmentId}/image/${encodedTitle}"${content.substr(imageMatch.index + imageMatch[0].length)}`;
|
||||||
}
|
}
|
||||||
else if (!url.includes('api/images/') && !/api\/attachments\/.+\/image\/?.*/.test(url)
|
else if (!url.includes('api/images/') && !/api\/attachments\/.+\/image\/?.*/.test(url)
|
||||||
// this is an exception for the web clipper's "imageId"
|
// this is an exception for the web clipper's "imageId"
|
||||||
@@ -889,6 +889,10 @@ function scanForLinks(note, content) {
|
|||||||
* Things which have to be executed after updating content, but asynchronously (separate transaction)
|
* Things which have to be executed after updating content, but asynchronously (separate transaction)
|
||||||
*/
|
*/
|
||||||
async function asyncPostProcessContent(note, content) {
|
async function asyncPostProcessContent(note, content) {
|
||||||
|
if (note.hasStringContent() && !utils.isString(content)) {
|
||||||
|
content = content.toString();
|
||||||
|
}
|
||||||
|
|
||||||
scanForLinks(note, content);
|
scanForLinks(note, content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,18 +46,6 @@ function protectRevisions(note) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function eraseRevisions(revisionIdsToErase) {
|
|
||||||
if (revisionIdsToErase.length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
log.info(`Removing revisions: ${JSON.stringify(revisionIdsToErase)}`);
|
|
||||||
|
|
||||||
sql.executeMany(`DELETE FROM revisions WHERE revisionId IN (???)`, revisionIdsToErase);
|
|
||||||
sql.executeMany(`UPDATE entity_changes SET isErased = 1, utcDateChanged = '${dateUtils.utcNowDateTime()}' WHERE entityName = 'revisions' AND entityId IN (???)`, revisionIdsToErase);
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
protectRevisions,
|
protectRevisions
|
||||||
eraseRevisions
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -63,6 +63,8 @@ function isElectron() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function hash(text) {
|
function hash(text) {
|
||||||
|
text = text.normalize();
|
||||||
|
|
||||||
return crypto.createHash('sha1').update(text).digest('base64');
|
return crypto.createHash('sha1').update(text).digest('base64');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -303,6 +305,10 @@ function toMap(list, key) {
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isString(x) {
|
||||||
|
return Object.prototype.toString.call(x) === "[object String]";
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
randomSecureToken,
|
randomSecureToken,
|
||||||
randomString,
|
randomString,
|
||||||
@@ -335,4 +341,5 @@ module.exports = {
|
|||||||
normalize,
|
normalize,
|
||||||
hashedBlobId,
|
hashedBlobId,
|
||||||
toMap,
|
toMap,
|
||||||
|
isString
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user