mirror of
https://github.com/zadam/trilium.git
synced 2025-11-06 05:15:59 +01:00
Compare commits
17 Commits
v0.45.0-be
...
v0.45.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
af41e5d115 | ||
|
|
4f75b6aaaf | ||
|
|
82f410f695 | ||
|
|
2bc06959c3 | ||
|
|
b898973ee6 | ||
|
|
a2b0d8a379 | ||
|
|
06a4eab7d5 | ||
|
|
25df1a054c | ||
|
|
8c4ff7ed2a | ||
|
|
609829653e | ||
|
|
5f20d033a8 | ||
|
|
93d0324177 | ||
|
|
0afd3c65aa | ||
|
|
8901c3ec91 | ||
|
|
c671b0a345 | ||
|
|
9f424836e2 | ||
|
|
7f5af4b959 |
21
.idea/codeStyles/Project.xml
generated
21
.idea/codeStyles/Project.xml
generated
@@ -6,26 +6,11 @@
|
|||||||
<option name="TAB_SIZE" value="2" />
|
<option name="TAB_SIZE" value="2" />
|
||||||
</value>
|
</value>
|
||||||
</option>
|
</option>
|
||||||
|
<H2CodeStyleSettings version="5">
|
||||||
|
<option name="USE_GENERAL_STYLE" value="false" />
|
||||||
|
</H2CodeStyleSettings>
|
||||||
<JSCodeStyleSettings version="0">
|
<JSCodeStyleSettings version="0">
|
||||||
<option name="USE_EXPLICIT_JS_EXTENSION" value="TRUE" />
|
<option name="USE_EXPLICIT_JS_EXTENSION" value="TRUE" />
|
||||||
</JSCodeStyleSettings>
|
</JSCodeStyleSettings>
|
||||||
<JetCodeStyleSettings>
|
|
||||||
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
|
|
||||||
<value>
|
|
||||||
<package name="java.util" alias="false" withSubpackages="false" />
|
|
||||||
<package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" />
|
|
||||||
<package name="io.ktor" alias="false" withSubpackages="true" />
|
|
||||||
</value>
|
|
||||||
</option>
|
|
||||||
<option name="PACKAGES_IMPORT_LAYOUT">
|
|
||||||
<value>
|
|
||||||
<package name="" alias="false" withSubpackages="true" />
|
|
||||||
<package name="java" alias="false" withSubpackages="true" />
|
|
||||||
<package name="javax" alias="false" withSubpackages="true" />
|
|
||||||
<package name="kotlin" alias="false" withSubpackages="true" />
|
|
||||||
<package name="" alias="true" withSubpackages="true" />
|
|
||||||
</value>
|
|
||||||
</option>
|
|
||||||
</JetCodeStyleSettings>
|
|
||||||
</code_scheme>
|
</code_scheme>
|
||||||
</component>
|
</component>
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
FROM node:12.16.3-alpine
|
FROM node:12.19.0-alpine
|
||||||
|
|
||||||
# Create app directory
|
# Create app directory
|
||||||
WORKDIR /usr/src/app
|
WORKDIR /usr/src/app
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ SERIES=${VERSION:0:4}-latest
|
|||||||
|
|
||||||
cat package.json | grep -v electron > server-package.json
|
cat package.json | grep -v electron > server-package.json
|
||||||
|
|
||||||
sudo docker build -t zadam/trilium:$VERSION -t zadam/trilium:$SERIES .
|
sudo docker build -t zadam/trilium:$VERSION --network host -t zadam/trilium:$SERIES .
|
||||||
|
|
||||||
if [[ $VERSION != *"beta"* ]]; then
|
if [[ $VERSION != *"beta"* ]]; then
|
||||||
sudo docker tag zadam/trilium:$VERSION zadam/trilium:latest
|
sudo docker tag zadam/trilium:$VERSION zadam/trilium:latest
|
||||||
|
|||||||
2
libraries/ckeditor/ckeditor.js
vendored
2
libraries/ckeditor/ckeditor.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
8
package-lock.json
generated
8
package-lock.json
generated
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "trilium",
|
"name": "trilium",
|
||||||
"version": "0.44.9",
|
"version": "0.45.1",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -2658,9 +2658,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"electron": {
|
"electron": {
|
||||||
"version": "9.3.2",
|
"version": "9.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/electron/-/electron-9.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/electron/-/electron-9.3.3.tgz",
|
||||||
"integrity": "sha512-0lleEf9msAXGDi2GukAuiGdw3VDgSTlONOnJgqDEz1fuSEVsXz5RX+hNPKDsVDerLTFg/C34RuJf4LwHvkKcBA==",
|
"integrity": "sha512-xghKeUY1qgnEcJ5w2rXo/toH+8NT2Dktx2aAxBNPV7CIJr3mejJJAPwLbycwtddzr37tgKxHeHlc8ivfKtMkJQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@electron/get": "^1.0.1",
|
"@electron/get": "^1.0.1",
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"name": "trilium",
|
"name": "trilium",
|
||||||
"productName": "Trilium Notes",
|
"productName": "Trilium Notes",
|
||||||
"description": "Trilium Notes",
|
"description": "Trilium Notes",
|
||||||
"version": "0.45.0-beta",
|
"version": "0.45.2",
|
||||||
"license": "AGPL-3.0-only",
|
"license": "AGPL-3.0-only",
|
||||||
"main": "electron.js",
|
"main": "electron.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -40,7 +40,6 @@
|
|||||||
"electron-window-state": "5.0.3",
|
"electron-window-state": "5.0.3",
|
||||||
"express": "4.17.1",
|
"express": "4.17.1",
|
||||||
"express-session": "1.17.1",
|
"express-session": "1.17.1",
|
||||||
"file-type": "16.0.0",
|
|
||||||
"fs-extra": "9.0.1",
|
"fs-extra": "9.0.1",
|
||||||
"helmet": "4.1.1",
|
"helmet": "4.1.1",
|
||||||
"html": "1.0.0",
|
"html": "1.0.0",
|
||||||
@@ -77,7 +76,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"cross-env": "7.0.2",
|
"cross-env": "7.0.2",
|
||||||
"electron": "9.3.2",
|
"electron": "9.3.3",
|
||||||
"electron-builder": "22.9.1",
|
"electron-builder": "22.9.1",
|
||||||
"electron-packager": "15.1.0",
|
"electron-packager": "15.1.0",
|
||||||
"electron-rebuild": "2.3.2",
|
"electron-rebuild": "2.3.2",
|
||||||
|
|||||||
@@ -57,8 +57,15 @@ function id() {
|
|||||||
return randtoken.generate(10);
|
return randtoken.generate(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
function note(title, type = 'text', mime = 'text/html') {
|
function note(title, extraParams = {}) {
|
||||||
const note = new Note(noteCache, {noteId: id(), title, type, mime});
|
const row = Object.assign({
|
||||||
|
noteId: id(),
|
||||||
|
title: title,
|
||||||
|
type: 'text',
|
||||||
|
mime: 'text/html'
|
||||||
|
}, extraParams);
|
||||||
|
|
||||||
|
const note = new Note(noteCache, row);
|
||||||
|
|
||||||
return new NoteBuilder(note);
|
return new NoteBuilder(note);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -247,6 +247,6 @@ describe("Invalid expressions", () => {
|
|||||||
searchContext
|
searchContext
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(searchContext.error).toEqual('Misplaced or incomplete expression "="')
|
expect(searchContext.error).toEqual('Relation can be compared only with property, e.g. ~relation.title=hello in ""')
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -53,8 +53,8 @@ describe("Search", () => {
|
|||||||
|
|
||||||
it("normal search looks also at type and mime", () => {
|
it("normal search looks also at type and mime", () => {
|
||||||
rootNote
|
rootNote
|
||||||
.child(note("Effective Java", 'book', ''))
|
.child(note("Effective Java", {type: 'book', mime:''}))
|
||||||
.child(note("Hello World.java", 'code', 'text/x-java'));
|
.child(note("Hello World.java", {type: 'code', mime: 'text/x-java'}));
|
||||||
|
|
||||||
const searchContext = new SearchContext();
|
const searchContext = new SearchContext();
|
||||||
let searchResults = searchService.findNotesWithQuery('book', searchContext);
|
let searchResults = searchService.findNotesWithQuery('book', searchContext);
|
||||||
@@ -178,7 +178,7 @@ describe("Search", () => {
|
|||||||
// dates should not be coerced into numbers which would then give wrong numbers
|
// dates should not be coerced into numbers which would then give wrong numbers
|
||||||
|
|
||||||
rootNote
|
rootNote
|
||||||
.child(note("My note")
|
.child(note("My note", {dateCreated: dateUtils.localNowDateTime()})
|
||||||
.label('year', new Date().getFullYear().toString())
|
.label('year', new Date().getFullYear().toString())
|
||||||
.label('month', dateUtils.localNowDate().substr(0, 7))
|
.label('month', dateUtils.localNowDate().substr(0, 7))
|
||||||
.label('date', dateUtils.localNowDate())
|
.label('date', dateUtils.localNowDate())
|
||||||
@@ -209,6 +209,8 @@ describe("Search", () => {
|
|||||||
test("#month = month", 1);
|
test("#month = month", 1);
|
||||||
test("#month = 'MONTH'", 0);
|
test("#month = 'MONTH'", 0);
|
||||||
|
|
||||||
|
test("note.dateCreated =* month", 1);
|
||||||
|
|
||||||
test("#date = TODAY", 1);
|
test("#date = TODAY", 1);
|
||||||
test("#date = today", 1);
|
test("#date = today", 1);
|
||||||
test("#date = 'today'", 0);
|
test("#date = 'today'", 0);
|
||||||
@@ -586,7 +588,7 @@ describe("Search", () => {
|
|||||||
|
|
||||||
const searchContext = new SearchContext();
|
const searchContext = new SearchContext();
|
||||||
|
|
||||||
let searchResults = searchService.findNotesWithQuery('# note.text *=* rati and note.noteId != root', searchContext);
|
let searchResults = searchService.findNotesWithQuery('# note.text *=* vaki and note.noteId != root', searchContext);
|
||||||
expect(searchResults.length).toEqual(1);
|
expect(searchResults.length).toEqual(1);
|
||||||
expect(noteCache.notes[searchResults[0].noteId].title).toEqual("Slovakia");
|
expect(noteCache.notes[searchResults[0].noteId].title).toEqual("Slovakia");
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,6 +8,11 @@ const TPL = `
|
|||||||
<p>Your username is <strong id="credentials-username"></strong>.</p>
|
<p>Your username is <strong id="credentials-username"></strong>.</p>
|
||||||
|
|
||||||
<h3>Change password</h3>
|
<h3>Change password</h3>
|
||||||
|
|
||||||
|
<div class="alert alert-warning" role="alert" style="font-weight: bold; color: red !important;">
|
||||||
|
Please take care to remember your new password. Password is used to encrypt protected notes. If you forget your password, then all your protected notes are forever lost with no recovery options.
|
||||||
|
</div>
|
||||||
|
|
||||||
<form id="change-password-form">
|
<form id="change-password-form">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="old-password">Old password</label>
|
<label for="old-password">Old password</label>
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import utils from "./utils.js";
|
|||||||
import renderService from "./render.js";
|
import renderService from "./render.js";
|
||||||
import protectedSessionService from "./protected_session.js";
|
import protectedSessionService from "./protected_session.js";
|
||||||
import protectedSessionHolder from "./protected_session_holder.js";
|
import protectedSessionHolder from "./protected_session_holder.js";
|
||||||
|
import libraryLoader from "./library_loader.js";
|
||||||
|
|
||||||
async function getRenderedContent(note) {
|
async function getRenderedContent(note) {
|
||||||
const type = getRenderingType(note);
|
const type = getRenderingType(note);
|
||||||
@@ -13,6 +14,12 @@ async function getRenderedContent(note) {
|
|||||||
const fullNote = await server.get('notes/' + note.noteId);
|
const fullNote = await server.get('notes/' + note.noteId);
|
||||||
|
|
||||||
$rendered = $('<div class="ck-content">').html(fullNote.content);
|
$rendered = $('<div class="ck-content">').html(fullNote.content);
|
||||||
|
|
||||||
|
if ($rendered.find('span.math-tex').length > 0) {
|
||||||
|
await libraryLoader.requireLibrary(libraryLoader.KATEX);
|
||||||
|
|
||||||
|
renderMathInElement($rendered[0], {});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (type === 'code') {
|
else if (type === 'code') {
|
||||||
const fullNote = await server.get('notes/' + note.noteId);
|
const fullNote = await server.get('notes/' + note.noteId);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import linkService from "./link.js";
|
|||||||
import treeCache from "./tree_cache.js";
|
import treeCache from "./tree_cache.js";
|
||||||
import utils from "./utils.js";
|
import utils from "./utils.js";
|
||||||
import attributeRenderer from "./attribute_renderer.js";
|
import attributeRenderer from "./attribute_renderer.js";
|
||||||
|
import libraryLoader from "./library_loader.js";
|
||||||
|
|
||||||
function setupGlobalTooltip() {
|
function setupGlobalTooltip() {
|
||||||
$(document).on("mouseenter", "a", mouseEnterHandler);
|
$(document).on("mouseenter", "a", mouseEnterHandler);
|
||||||
@@ -101,7 +102,15 @@ async function renderTooltip(note, noteComplement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (note.type === 'text' && !utils.isHtmlEmpty(noteComplement.content)) {
|
if (note.type === 'text' && !utils.isHtmlEmpty(noteComplement.content)) {
|
||||||
content += '<div class="ck-content">' + noteComplement.content + '</div>';
|
const $content = $('<div class="ck-content">').append(noteComplement.content);
|
||||||
|
|
||||||
|
if ($content.find('span.math-tex').length > 0) {
|
||||||
|
await libraryLoader.requireLibrary(libraryLoader.KATEX);
|
||||||
|
|
||||||
|
renderMathInElement($content[0], {});
|
||||||
|
}
|
||||||
|
|
||||||
|
content += $content[0].outerHTML;
|
||||||
}
|
}
|
||||||
else if (note.type === 'code' && noteComplement.content && noteComplement.content.trim()) {
|
else if (note.type === 'code' && noteComplement.content && noteComplement.content.trim()) {
|
||||||
content += $("<pre>")
|
content += $("<pre>")
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ export default class TabManager extends Component {
|
|||||||
|
|
||||||
// using pushState instead of directly modifying document.location because it does not trigger hashchange
|
// using pushState instead of directly modifying document.location because it does not trigger hashchange
|
||||||
window.history.pushState(null, "", url);
|
window.history.pushState(null, "", url);
|
||||||
|
}
|
||||||
|
|
||||||
document.title = "Trilium Notes";
|
document.title = "Trilium Notes";
|
||||||
|
|
||||||
@@ -122,7 +123,6 @@ export default class TabManager extends Component {
|
|||||||
// it helps navigating in history if note title is included in the title
|
// it helps navigating in history if note title is included in the title
|
||||||
document.title += " - " + activeTabContext.note.title;
|
document.title += " - " + activeTabContext.note.title;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
this.triggerEvent('activeNoteChanged'); // trigger this even in on popstate event
|
this.triggerEvent('activeNoteChanged'); // trigger this even in on popstate event
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ function closePersistent(id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function showMessage(message, delay = 2000) {
|
function showMessage(message, delay = 2000) {
|
||||||
console.debug(utils.now(), "message: ", message);
|
console.debug(utils.now(), "message:", message);
|
||||||
|
|
||||||
toast({
|
toast({
|
||||||
title: "Info",
|
title: "Info",
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ class TreeCache {
|
|||||||
async loadInitialTree() {
|
async loadInitialTree() {
|
||||||
const resp = await server.get('tree');
|
const resp = await server.get('tree');
|
||||||
|
|
||||||
|
// FIXME: we need to do this to cover for ascendants of template notes which are not loaded
|
||||||
|
await this.loadParents(resp, false);
|
||||||
|
|
||||||
// clear the cache only directly before adding new content which is important for e.g. switching to protected session
|
// clear the cache only directly before adding new content which is important for e.g. switching to protected session
|
||||||
|
|
||||||
/** @type {Object.<string, NoteShort>} */
|
/** @type {Object.<string, NoteShort>} */
|
||||||
@@ -40,6 +43,8 @@ class TreeCache {
|
|||||||
async loadSubTree(subTreeNoteId) {
|
async loadSubTree(subTreeNoteId) {
|
||||||
const resp = await server.get('tree?subTreeNoteId=' + subTreeNoteId);
|
const resp = await server.get('tree?subTreeNoteId=' + subTreeNoteId);
|
||||||
|
|
||||||
|
await this.loadParents(resp, true);
|
||||||
|
|
||||||
this.addResp(resp);
|
this.addResp(resp);
|
||||||
|
|
||||||
return this.notes[subTreeNoteId];
|
return this.notes[subTreeNoteId];
|
||||||
@@ -191,13 +196,18 @@ class TreeCache {
|
|||||||
if (note.type === 'search') {
|
if (note.type === 'search') {
|
||||||
const searchResultNoteIds = await server.get('search-note/' + note.noteId);
|
const searchResultNoteIds = await server.get('search-note/' + note.noteId);
|
||||||
|
|
||||||
if (!searchResultNoteIds) {
|
if (!Array.isArray(searchResultNoteIds)) {
|
||||||
throw new Error(`Search note ${note.noteId} failed.`);
|
throw new Error(`Search note ${note.noteId} failed: ${searchResultNoteIds}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// force to load all the notes at once instead of one by one
|
// force to load all the notes at once instead of one by one
|
||||||
await this.getNotes(searchResultNoteIds);
|
await this.getNotes(searchResultNoteIds);
|
||||||
|
|
||||||
|
// reset all the virtual branches from old search results
|
||||||
|
if (note.noteId in treeCache.notes) {
|
||||||
|
treeCache.notes[note.noteId].children = [];
|
||||||
|
}
|
||||||
|
|
||||||
const branches = resp.branches.filter(b => b.noteId === note.noteId || b.parentNoteId === note.noteId);
|
const branches = resp.branches.filter(b => b.noteId === note.noteId || b.parentNoteId === note.noteId);
|
||||||
|
|
||||||
searchResultNoteIds.forEach((resultNoteId, index) => branches.push({
|
searchResultNoteIds.forEach((resultNoteId, index) => branches.push({
|
||||||
|
|||||||
@@ -283,7 +283,9 @@ export default class AttributeDetailWidget extends TabAwareWidget {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.attribute.value = suggestion.notePath;
|
const pathChunks = suggestion.notePath.split('/');
|
||||||
|
|
||||||
|
this.attribute.value = pathChunks[pathChunks.length - 1]; // noteId
|
||||||
|
|
||||||
this.triggerCommand('updateAttributeList', { attributes: this.allAttributes });
|
this.triggerCommand('updateAttributeList', { attributes: this.allAttributes });
|
||||||
this.updateRelatedNotes();
|
this.updateRelatedNotes();
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ export default class PromotedAttributesWidget extends TabAwareWidget {
|
|||||||
}
|
}
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
$input.on('autocomplete:noteselected', e => this.promotedAttributeChanged(e))
|
$input.on('autocomplete:selected', e => this.promotedAttributeChanged(e))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (definition.labelType === 'number') {
|
else if (definition.labelType === 'number') {
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
addTextToActiveEditorEvent(text) {
|
addTextToActiveEditorEvent({text}) {
|
||||||
if (!this.isActive()) {
|
if (!this.isActive()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,8 @@ async function searchFromNote(req) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (note.isDeleted) {
|
if (note.isDeleted) {
|
||||||
return [400, `Note ${req.params.noteId} is deleted.`];
|
// this can be triggered from recent changes and it's harmless to return empty list rather than fail
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (note.type !== 'search') {
|
if (note.type !== 'search') {
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
module.exports = { buildDate:"2020-10-21T22:57:54+02:00", buildRevision: "283808d69181628b84d7d48b5029c51bc5a1cf98" };
|
module.exports = { buildDate:"2020-10-29T22:57:25+01:00", buildRevision: "4f75b6aaafef8144080fd17f403a605f61f5590d" };
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
const sax = require("sax");
|
const sax = require("sax");
|
||||||
const FileType = require('file-type');
|
|
||||||
const stream = require('stream');
|
const stream = require('stream');
|
||||||
const log = require("../log");
|
const log = require("../log");
|
||||||
const utils = require("../utils");
|
const utils = require("../utils");
|
||||||
@@ -138,17 +137,6 @@ function importEnex(taskContext, file, parentNote) {
|
|||||||
}
|
}
|
||||||
else if (currentTag === 'mime') {
|
else if (currentTag === 'mime') {
|
||||||
resource.mime = text.toLowerCase();
|
resource.mime = text.toLowerCase();
|
||||||
|
|
||||||
if (text.startsWith("image/")) {
|
|
||||||
resource.title = "image";
|
|
||||||
|
|
||||||
// images don't have "file-name" tag so we'll create attribute here
|
|
||||||
resource.attributes.push({
|
|
||||||
type: 'label',
|
|
||||||
name: 'originalFileName',
|
|
||||||
value: resource.title + "." + text.substr(6) // extension from mime type
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (previousTag === 'note') {
|
else if (previousTag === 'note') {
|
||||||
@@ -243,11 +231,7 @@ function importEnex(taskContext, file, parentNote) {
|
|||||||
|
|
||||||
const mediaRegex = new RegExp(`<en-media hash="${hash}"[^>]*>`, 'g');
|
const mediaRegex = new RegExp(`<en-media hash="${hash}"[^>]*>`, 'g');
|
||||||
|
|
||||||
const fileTypeFromBuffer = FileType.fromBuffer(resource.content);
|
resource.mime = resource.mime || "application/octet-stream";
|
||||||
if (fileTypeFromBuffer) {
|
|
||||||
// If fileType returns something for buffer, then set the mime given
|
|
||||||
resource.mime = fileTypeFromBuffer.mime;
|
|
||||||
}
|
|
||||||
|
|
||||||
const createFileNote = () => {
|
const createFileNote = () => {
|
||||||
const resourceNote = noteService.createNewNote({
|
const resourceNote = noteService.createNewNote({
|
||||||
@@ -260,7 +244,7 @@ function importEnex(taskContext, file, parentNote) {
|
|||||||
}).note;
|
}).note;
|
||||||
|
|
||||||
for (const attr of resource.attributes) {
|
for (const attr of resource.attributes) {
|
||||||
noteEntity.addAttribute(attr.type, attr.name, attr.value);
|
resourceNote.addAttribute(attr.type, attr.name, attr.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateDates(resourceNote.noteId, utcDateCreated, utcDateModified);
|
updateDates(resourceNote.noteId, utcDateCreated, utcDateModified);
|
||||||
@@ -274,10 +258,18 @@ function importEnex(taskContext, file, parentNote) {
|
|||||||
|
|
||||||
if (resource.mime && resource.mime.startsWith('image/')) {
|
if (resource.mime && resource.mime.startsWith('image/')) {
|
||||||
try {
|
try {
|
||||||
const originalName = "image." + resource.mime.substr(6);
|
const originalName = (resource.title && resource.title !== 'resource')
|
||||||
|
? resource.title
|
||||||
|
: `image.${resource.mime.substr(6)}`; // default if real name is not present
|
||||||
|
|
||||||
const {url, note: imageNote} = imageService.saveImage(noteEntity.noteId, resource.content, originalName, taskContext.data.shrinkImages);
|
const {url, note: imageNote} = imageService.saveImage(noteEntity.noteId, resource.content, originalName, taskContext.data.shrinkImages);
|
||||||
|
|
||||||
|
for (const attr of resource.attributes) {
|
||||||
|
if (attr.name !== 'originalFileName') { // this one is already saved in imageService
|
||||||
|
imageNote.addAttribute(attr.type, attr.name, attr.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
updateDates(imageNote.noteId, utcDateCreated, utcDateModified);
|
updateDates(imageNote.noteId, utcDateCreated, utcDateModified);
|
||||||
|
|
||||||
const imageLink = `<img src="${url}">`;
|
const imageLink = `<img src="${url}">`;
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ const htmlSanitizer = require('../html_sanitizer');
|
|||||||
* @param {Note} parentNote
|
* @param {Note} parentNote
|
||||||
* @return {Promise<*[]|*>}
|
* @return {Promise<*[]|*>}
|
||||||
*/
|
*/
|
||||||
function importOpml(taskContext, fileBuffer, parentNote) {
|
async function importOpml(taskContext, fileBuffer, parentNote) {
|
||||||
const xml = new Promise(function(resolve, reject)
|
const xml = await new Promise(function(resolve, reject)
|
||||||
{
|
{
|
||||||
parseString(fileBuffer, function (err, result) {
|
parseString(fileBuffer, function (err, result) {
|
||||||
if (err) {
|
if (err) {
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ const stringComparators = {
|
|||||||
">=": comparedValue => (val => val >= comparedValue),
|
">=": comparedValue => (val => val >= comparedValue),
|
||||||
"<": comparedValue => (val => val < comparedValue),
|
"<": comparedValue => (val => val < comparedValue),
|
||||||
"<=": comparedValue => (val => val <= comparedValue),
|
"<=": comparedValue => (val => val <= comparedValue),
|
||||||
"*=": comparedValue => (val => val.endsWith(comparedValue)),
|
"*=": comparedValue => (val => val && val.endsWith(comparedValue)),
|
||||||
"=*": comparedValue => (val => val.startsWith(comparedValue)),
|
"=*": comparedValue => (val => val && val.startsWith(comparedValue)),
|
||||||
"*=*": comparedValue => (val => val.includes(comparedValue)),
|
"*=*": comparedValue => (val => val && val.includes(comparedValue)),
|
||||||
};
|
};
|
||||||
|
|
||||||
const numericComparators = {
|
const numericComparators = {
|
||||||
|
|||||||
@@ -80,10 +80,14 @@ function getExpression(tokens, searchContext, level = 0) {
|
|||||||
|
|
||||||
if (i + 2 < tokens.length) {
|
if (i + 2 < tokens.length) {
|
||||||
if (tokens[i + 1].token === '+') {
|
if (tokens[i + 1].token === '+') {
|
||||||
delta += parseInt(tokens[i + 2].token);
|
i += 2;
|
||||||
|
|
||||||
|
delta += parseInt(tokens[i].token);
|
||||||
}
|
}
|
||||||
else if (tokens[i + 1].token === '-') {
|
else if (tokens[i + 1].token === '-') {
|
||||||
delta -= parseInt(tokens[i + 2].token);
|
i += 2;
|
||||||
|
|
||||||
|
delta -= parseInt(tokens[i].token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,16 +200,18 @@ function getExpression(tokens, searchContext, level = 0) {
|
|||||||
if (PropertyComparisonExp.isProperty(tokens[i].token)) {
|
if (PropertyComparisonExp.isProperty(tokens[i].token)) {
|
||||||
const propertyName = tokens[i].token;
|
const propertyName = tokens[i].token;
|
||||||
const operator = tokens[i + 1].token;
|
const operator = tokens[i + 1].token;
|
||||||
const comparedValue = tokens[i + 2].token;
|
|
||||||
|
i += 2;
|
||||||
|
|
||||||
|
const comparedValue = resolveConstantOperand();
|
||||||
|
|
||||||
const comparator = buildComparator(operator, comparedValue);
|
const comparator = buildComparator(operator, comparedValue);
|
||||||
|
|
||||||
if (!comparator) {
|
if (!comparator) {
|
||||||
searchContext.addError(`Can't find operator '${operator}' in ${context(i)}`);
|
searchContext.addError(`Can't find operator '${operator}' in ${context(i - 2)}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
i += 2;
|
|
||||||
|
|
||||||
return new PropertyComparisonExp(propertyName, comparator);
|
return new PropertyComparisonExp(propertyName, comparator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user