mirror of
https://github.com/zadam/trilium.git
synced 2025-11-02 19:36:12 +01:00
Compare commits
92 Commits
v0.24.0-be
...
v0.25.0-be
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cfa926602a | ||
|
|
350cb52c07 | ||
|
|
af195beb7e | ||
|
|
cb00d42546 | ||
|
|
ee0b0c3dfe | ||
|
|
ddcb4a0e10 | ||
|
|
8cbb29ee25 | ||
|
|
9da11ac144 | ||
|
|
ba7c8e77e5 | ||
|
|
4577b03fc9 | ||
|
|
72d83aa85e | ||
|
|
8ee80cb5f1 | ||
|
|
4cc08bff8b | ||
|
|
295cfb2d75 | ||
|
|
7775376b33 | ||
|
|
9f64e994dc | ||
|
|
ee1e4fc710 | ||
|
|
5ea62c710d | ||
|
|
aeca31d06a | ||
|
|
9cb9ea6ab5 | ||
|
|
e37dd69827 | ||
|
|
6c51696d1a | ||
|
|
27787c8f37 | ||
|
|
e910595545 | ||
|
|
a616739805 | ||
|
|
bea28de6a0 | ||
|
|
4e198ca2f0 | ||
|
|
2fbd16a0e3 | ||
|
|
76fc49f037 | ||
|
|
139c99440f | ||
|
|
137b9dfa0b | ||
|
|
5f0fdd15eb | ||
|
|
61e1427b83 | ||
|
|
b3aa0ba47c | ||
|
|
56e2b44c25 | ||
|
|
4d5a17583f | ||
|
|
71eda5aa3d | ||
|
|
0711ea8dc8 | ||
|
|
be206872d1 | ||
|
|
fcf3fe8dcd | ||
|
|
62dbd4062a | ||
|
|
196e8b4380 | ||
|
|
551e1255ff | ||
|
|
e09b61d1ac | ||
|
|
ee23bcc783 | ||
|
|
3e351bd8d3 | ||
|
|
0d3bc22d73 | ||
|
|
d82898421e | ||
|
|
1db2f0c2c5 | ||
|
|
6cd8a2203e | ||
|
|
08e062ab34 | ||
|
|
3a06493459 | ||
|
|
8159564885 | ||
|
|
8ce3c1a480 | ||
|
|
dbc93f4a79 | ||
|
|
92ffe321aa | ||
|
|
6cb7d0098e | ||
|
|
bdcb4361b2 | ||
|
|
15366d37d7 | ||
|
|
acd001501b | ||
|
|
0019865807 | ||
|
|
137ffcc4e3 | ||
|
|
585398ad5c | ||
|
|
50401954d1 | ||
|
|
32a9df8489 | ||
|
|
5bf5d1cac4 | ||
|
|
3608857f25 | ||
|
|
16a1dc12df | ||
|
|
9c834229b9 | ||
|
|
3fd45b15e7 | ||
|
|
f20ab45576 | ||
|
|
77a89d85c8 | ||
|
|
30249a353e | ||
|
|
eb9bae9010 | ||
|
|
0c7ae527c5 | ||
|
|
fef4705e2f | ||
|
|
568c2c997f | ||
|
|
d6b5cd6ead | ||
|
|
00ce379962 | ||
|
|
b1ed022771 | ||
|
|
ad6cb6ba34 | ||
|
|
2e76de5f34 | ||
|
|
4f23f2515a | ||
|
|
8e16cc2326 | ||
|
|
49bca04ebb | ||
|
|
05e9669eaf | ||
|
|
62a250a7fc | ||
|
|
8299524682 | ||
|
|
7691a59977 | ||
|
|
3db2f6784d | ||
|
|
48684d0509 | ||
|
|
1ee8d9fd93 |
@@ -1,4 +1,7 @@
|
||||
.git
|
||||
.idea
|
||||
/bin
|
||||
/dist
|
||||
/docs
|
||||
/npm-debug.log
|
||||
node_modules
|
||||
npm-debug.log
|
||||
dist
|
||||
.idea
|
||||
26
Dockerfile
26
Dockerfile
@@ -1,21 +1,27 @@
|
||||
FROM node:10.12.0
|
||||
|
||||
RUN apt-get update && apt-get install -y nasm
|
||||
FROM node:10.14.0-alpine
|
||||
|
||||
# Create app directory
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
# Install app dependencies
|
||||
# A wildcard is used to ensure both package.json AND package-lock.json are copied
|
||||
# Copy both package.json and package-lock.json
|
||||
# where available (npm@5+)
|
||||
COPY package*.json ./
|
||||
COPY package.json package-lock.json ./
|
||||
|
||||
RUN npm install --production
|
||||
# If you are building your code for production
|
||||
# RUN npm install --only=production
|
||||
# Install app dependencies
|
||||
RUN set -x \
|
||||
&& apk add --no-cache --virtual .build-dependencies \
|
||||
autoconf \
|
||||
automake \
|
||||
g++ \
|
||||
gcc \
|
||||
libtool \
|
||||
make \
|
||||
nasm \
|
||||
&& npm install --production \
|
||||
&& apk del .build-dependencies
|
||||
|
||||
# Bundle app source
|
||||
COPY . .
|
||||
|
||||
EXPOSE 8080
|
||||
CMD [ "node", "src/www" ]
|
||||
CMD [ "node", "./src/www" ]
|
||||
|
||||
20
README.md
20
README.md
@@ -1,23 +1,21 @@
|
||||
# Trilium Notes
|
||||
|
||||
[](https://gitter.im/trilium-notes/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
Trilium Notes is a hierarchical note taking application. Picture tells a thousand words:
|
||||
Trilium Notes is a hierarchical note taking application with focus on building large personal knowledge bases. See [screenshots](https://github.com/zadam/trilium/wiki/Screenshot-tour) for quick overview:
|
||||
|
||||

|
||||
|
||||
See other pictures in [screenshot tour](https://github.com/zadam/trilium/wiki/Screenshot-tour).
|
||||
|
||||
## Features
|
||||
|
||||
* Notes can be arranged into arbitrarily deep hierarchy (tree)
|
||||
* Notes can have more than 1 parents - see [cloning](https://github.com/zadam/trilium/wiki/Cloning-notes)
|
||||
* Notes can be arranged into arbitrarily deep tree. Single note can be placed into multiple places in the tree (see [cloning](https://github.com/zadam/trilium/wiki/Cloning-notes))
|
||||
* Rich WYSIWYG note editing including e.g. tables and images with markdown [autoformat](https://github.com/zadam/trilium/wiki/Text-editor#autoformat)
|
||||
* Support for editing [notes with source code](https://github.com/zadam/trilium/wiki/Code-notes), including syntax highlighting
|
||||
* Fast and easy [navigation between notes](https://github.com/zadam/trilium/wiki/Note-navigation)
|
||||
* Seamless [note versioning](https://github.com/zadam/trilium/wiki/Note-revisions)
|
||||
* Note [attributes](https://github.com/zadam/trilium/wiki/Attributes) can be used for note organization, querying and advanced [scripting](https://github.com/zadam/trilium/wiki/Scripts)
|
||||
* [Synchronization](https://github.com/zadam/trilium/wiki/Synchronization) with self-hosted sync server
|
||||
* Strong [note encryption](https://github.com/zadam/trilium/wiki/Protected-notes)
|
||||
* Strong [note encryption](https://github.com/zadam/trilium/wiki/Protected-notes) with per-note granularity
|
||||
* [Relation maps](https://github.com/zadam/trilium/wiki/Relation-map) for visualizing notes and their relations
|
||||
* [Scripting](https://github.com/zadam/trilium/wiki/Scripts) - see [Advanced showcases](https://github.com/zadam/trilium/wiki/Advanced-showcases)
|
||||
* Scales well in both usability and performance upwards of 100 000 notes
|
||||
* [Night theme](https://github.com/zadam/trilium/wiki/Themes)
|
||||
@@ -25,16 +23,14 @@ See other pictures in [screenshot tour](https://github.com/zadam/trilium/wiki/Sc
|
||||
|
||||
## Builds
|
||||
|
||||
Trilium is provided as either desktop application ([Electron](https://electronjs.org)-based) or web application hosted on your server.
|
||||
Trilium is provided as either desktop application (Linux, Windows) or web application hosted on your server (Linux). Mac is planned but not available at the moment.
|
||||
|
||||
* If you want to use Trilium on the desktop, download binary release for your platform (currently Linux and Windows are supported) from [latest release](https://github.com/zadam/trilium/releases/latest), unzip the package and run ```trilium``` executable.
|
||||
* If you want to install Trilium on server, follow [this page](https://github.com/zadam/trilium/wiki/Server-installation).
|
||||
* Currently only recent Chrome and Firefox are supported (tested) browsers.
|
||||
|
||||
## Status
|
||||
|
||||
Trilium is beta quality software. While it is reasonably feature complete and is tested by its author, it lacks proper testing by more users. It's not yet recommended for daily use, but testing and experimentation is encouraged.
|
||||
|
||||
## Documentation
|
||||
|
||||
[See wiki for complete list of documentation pages.](https://github.com/zadam/trilium/wiki/)
|
||||
[See wiki for complete list of documentation pages.](https://github.com/zadam/trilium/wiki/)
|
||||
|
||||
You can also read [Patterns of personal knowledge base](https://github.com/zadam/trilium/wiki/Patterns-of-personal-knowledge-base) to get some inspiration on how you might use Trilium.
|
||||
@@ -1,8 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if [[ $# -eq 0 ]] ; then
|
||||
echo "Missing argument of new version"
|
||||
exit 1
|
||||
fi
|
||||
VERSION=`jq -r ".version" package.json`
|
||||
|
||||
sudo docker build -t zadam/trilium:latest -t zadam/trilium:$1 .
|
||||
sudo docker build -t zadam/trilium:latest -t zadam/trilium:$VERSION .
|
||||
19
bin/build-linux-ia32.sh
Executable file
19
bin/build-linux-ia32.sh
Executable file
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
BUILD_DIR=./dist/trilium-linux-ia32
|
||||
rm -rf $BUILD_DIR
|
||||
|
||||
echo "Rebuilding binaries for linux-ia32"
|
||||
./node_modules/.bin/electron-rebuild --arch=ia32
|
||||
|
||||
./node_modules/.bin/electron-packager . --out=dist --executable-name=trilium --platform=linux --arch=ia32 --overwrite
|
||||
|
||||
mv "./dist/Trilium Notes-linux-ia32" $BUILD_DIR
|
||||
|
||||
rm -r $BUILD_DIR/resources/app/bin/deps
|
||||
# removing software WebGL binaries because they are pretty huge and not necessary
|
||||
rm -r $BUILD_DIR/swiftshader
|
||||
|
||||
echo "Packaging linux ia32 electron distribution..."
|
||||
VERSION=`jq -r ".version" package.json`
|
||||
7z a $BUILD_DIR-${VERSION}.7z $BUILD_DIR
|
||||
20
bin/build-linux-x64.sh
Executable file
20
bin/build-linux-x64.sh
Executable file
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
BUILD_DIR=./dist/trilium-linux-x64
|
||||
rm -rf $BUILD_DIR
|
||||
|
||||
# we build x64 as second so that we keep X64 binaries in node_modules for local development and server build
|
||||
echo "Rebuilding binaries for linux-x64"
|
||||
./node_modules/.bin/electron-rebuild --arch=x64
|
||||
|
||||
./node_modules/.bin/electron-packager . --out=dist --executable-name=trilium --platform=linux --arch=x64 --overwrite
|
||||
|
||||
mv "./dist/Trilium Notes-linux-x64" $BUILD_DIR
|
||||
|
||||
rm -r $BUILD_DIR/resources/app/bin/deps
|
||||
# removing software WebGL binaries because they are pretty huge and not necessary
|
||||
rm -r $BUILD_DIR/swiftshader
|
||||
|
||||
echo "Packaging linux x64 electron distribution..."
|
||||
VERSION=`jq -r ".version" package.json`
|
||||
7z a $BUILD_DIR-${VERSION}.7z $BUILD_DIR
|
||||
27
bin/build-mac-x64.sh
Executable file
27
bin/build-mac-x64.sh
Executable file
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
BUILD_DIR=./dist/trilium-mac-x64
|
||||
rm -rf $BUILD_DIR
|
||||
|
||||
./node_modules/.bin/electron-packager . --out=dist --executable-name=trilium --platform=darwin --arch=x64 --overwrite --icon=src/public/images/app-icons/mac/icon.icns
|
||||
|
||||
# Mac build has by default useless directory level
|
||||
mv "./dist/Trilium Notes-darwin-x64" $BUILD_DIR
|
||||
|
||||
echo "Copying required mac binaries"
|
||||
|
||||
MAC_RES_DIR=$BUILD_DIR/Trilium\ Notes.app/Contents/Resources/app
|
||||
|
||||
rm -r "$MAC_RES_DIR/node_modules/sqlite3/lib/binding/*"
|
||||
|
||||
cp -r bin/deps/mac/sqlite/* "$MAC_RES_DIR/node_modules/sqlite3/lib/binding/"
|
||||
cp bin/deps/mac/image/cjpeg "$MAC_RES_DIR/node_modules/mozjpeg/vendor/"
|
||||
cp bin/deps/mac/image/pngquant "$MAC_RES_DIR/node_modules/pngquant-bin/vendor/"
|
||||
cp bin/deps/mac/image/gifsicle "$MAC_RES_DIR/node_modules/giflossy/vendor/"
|
||||
|
||||
rm -r "$MAC_RES_DIR/bin/deps"
|
||||
|
||||
echo "Packaging mac x64 electron distribution..."
|
||||
|
||||
VERSION=`jq -r ".version" package.json`
|
||||
7z a $BUILD_DIR-${VERSION}.7z $BUILD_DIR
|
||||
@@ -1,13 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if [[ $# -eq 0 ]] ; then
|
||||
echo "Missing argument of new version"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
VERSION=$1
|
||||
PKG_DIR=dist/trilium-linux-x64-server
|
||||
NODE_VERSION=10.12.0
|
||||
NODE_VERSION=10.14.1
|
||||
|
||||
rm -r $PKG_DIR
|
||||
mkdir $PKG_DIR
|
||||
@@ -35,4 +29,5 @@ chmod 755 trilium.sh
|
||||
|
||||
cd ..
|
||||
|
||||
VERSION=`jq -r ".version" package.json`
|
||||
7z a trilium-linux-x64-server-${VERSION}.7z trilium-linux-x64-server
|
||||
25
bin/build-win-x64.sh
Executable file
25
bin/build-win-x64.sh
Executable file
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
BUILD_DIR=./dist/trilium-windows-x64
|
||||
rm -rf $BUILD_DIR
|
||||
|
||||
./node_modules/.bin/electron-packager . --out=dist --executable-name=trilium --platform=win32 --arch=x64 --overwrite --icon=src/public/images/app-icons/win/icon.ico
|
||||
|
||||
mv "./dist/Trilium Notes-win32-x64" $BUILD_DIR
|
||||
|
||||
echo "Copying required windows binaries"
|
||||
|
||||
WIN_RES_DIR=$BUILD_DIR/resources/app
|
||||
|
||||
cp -r bin/deps/win/sqlite/* $WIN_RES_DIR/node_modules/sqlite3/lib/binding/
|
||||
cp bin/deps/win/image/cjpeg.exe $WIN_RES_DIR/node_modules/mozjpeg/vendor/
|
||||
cp bin/deps/win/image/pngquant.exe $WIN_RES_DIR/node_modules/pngquant-bin/vendor/
|
||||
cp bin/deps/win/image/gifsicle.exe $WIN_RES_DIR/node_modules/giflossy/vendor/
|
||||
|
||||
rm -r $WIN_RES_DIR/bin/deps
|
||||
# removing software WebGL binaries because they are pretty huge and not necessary
|
||||
rm -r $BUILD_DIR/swiftshader
|
||||
|
||||
echo "Packaging windows x64 electron distribution..."
|
||||
VERSION=`jq -r ".version" package.json`
|
||||
7z a $BUILD_DIR-${VERSION}.7z $BUILD_DIR
|
||||
29
bin/build.sh
29
bin/build.sh
@@ -8,30 +8,11 @@ echo "Deleting existing builds"
|
||||
|
||||
rm -r dist/*
|
||||
|
||||
echo "Rebuilding binaries for linux-ia32"
|
||||
./node_modules/.bin/electron-rebuild --arch=ia32
|
||||
bin/build-linux-ia32.sh
|
||||
|
||||
./node_modules/.bin/electron-packager . --out=dist --platform=linux --arch=ia32 --overwrite
|
||||
bin/build-win-x64.sh
|
||||
|
||||
./node_modules/.bin/electron-packager . --out=dist --platform=win32 --arch=x64 --overwrite
|
||||
bin/build-mac-x64.sh
|
||||
|
||||
# we build x64 as second so that we keep X64 binaries in node_modules for local development and server build
|
||||
echo "Rebuilding binaries for linux-x64"
|
||||
./node_modules/.bin/electron-rebuild --arch=x64
|
||||
|
||||
./node_modules/.bin/electron-packager . --out=dist --platform=linux --arch=x64 --overwrite
|
||||
|
||||
echo "Copying required windows binaries"
|
||||
|
||||
WIN_RES_DIR=./dist/trilium-win32-x64/resources/app
|
||||
|
||||
cp -r bin/deps/sqlite/* $WIN_RES_DIR/node_modules/sqlite3/lib/binding/
|
||||
cp bin/deps/image/cjpeg.exe $WIN_RES_DIR/node_modules/mozjpeg/vendor/
|
||||
cp bin/deps/image/pngquant.exe $WIN_RES_DIR/node_modules/pngquant-bin/vendor/
|
||||
cp bin/deps/image/gifsicle.exe $WIN_RES_DIR/node_modules/giflossy/vendor/
|
||||
|
||||
echo "Cleaning up unnecessary binaries from all builds"
|
||||
|
||||
rm -r ./dist/trilium-linux-ia32/resources/app/bin/deps
|
||||
rm -r ./dist/trilium-linux-x64/resources/app/bin/deps
|
||||
rm -r ./dist/trilium-win32-x64/resources/app/bin/deps
|
||||
# building X64 linux as the last so electron-rebuild will prepare X64 binaries for local development
|
||||
bin/build-linux-x64.sh
|
||||
|
||||
BIN
bin/deps/mac/image/cjpeg
Normal file
BIN
bin/deps/mac/image/cjpeg
Normal file
Binary file not shown.
BIN
bin/deps/mac/image/gifsicle
Normal file
BIN
bin/deps/mac/image/gifsicle
Normal file
Binary file not shown.
BIN
bin/deps/mac/image/pngquant
Normal file
BIN
bin/deps/mac/image/pngquant
Normal file
Binary file not shown.
BIN
bin/deps/mac/sqlite/electron-v4.0-darwin-x64/node_sqlite3.node
Normal file
BIN
bin/deps/mac/sqlite/electron-v4.0-darwin-x64/node_sqlite3.node
Normal file
Binary file not shown.
0
bin/generate-cert.sh
Normal file → Executable file
0
bin/generate-cert.sh
Normal file → Executable file
@@ -1,14 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
VERSION=`jq -r ".version" package.json`
|
||||
|
||||
cd dist
|
||||
|
||||
echo "Packaging linux x64 electron distribution..."
|
||||
7z a trilium-linux-x64-${VERSION}.7z trilium-linux-x64
|
||||
|
||||
echo "Packaging linux ia32 electron distribution..."
|
||||
7z a trilium-linux-ia32-${VERSION}.7z trilium-linux-ia32
|
||||
|
||||
echo "Packaging windows x64 electron distribution..."
|
||||
7z a trilium-windows-x64-${VERSION}.7z trilium-win32-x64
|
||||
@@ -42,18 +42,23 @@ git push origin $TAG
|
||||
|
||||
bin/build.sh
|
||||
|
||||
bin/package.sh
|
||||
|
||||
LINUX_X64_BUILD=trilium-linux-x64-$VERSION.7z
|
||||
LINUX_IA32_BUILD=trilium-linux-ia32-$VERSION.7z
|
||||
WINDOWS_X64_BUILD=trilium-windows-x64-$VERSION.7z
|
||||
MAC_X64_BUILD=trilium-mac-x64-$VERSION.7z
|
||||
SERVER_BUILD=trilium-linux-x64-server-$VERSION.7z
|
||||
|
||||
echo "Creating release in GitHub"
|
||||
|
||||
EXTRA=
|
||||
|
||||
if [[ $TAG == *"beta"* ]]; then
|
||||
EXTRA=--pre-release
|
||||
fi
|
||||
|
||||
github-release release \
|
||||
--tag $TAG \
|
||||
--name "$TAG release"
|
||||
--name "$TAG release" $EXTRA
|
||||
|
||||
echo "Uploading linux x64 build"
|
||||
|
||||
@@ -76,6 +81,13 @@ github-release upload \
|
||||
--name "$WINDOWS_X64_BUILD" \
|
||||
--file "dist/$WINDOWS_X64_BUILD"
|
||||
|
||||
echo "Uploading mac x64 build"
|
||||
|
||||
github-release upload \
|
||||
--tag $TAG \
|
||||
--name "$MAC_X64_BUILD" \
|
||||
--file "dist/$MAC_X64_BUILD"
|
||||
|
||||
echo "Packaging server version"
|
||||
|
||||
bin/build-server.sh $VERSION
|
||||
|
||||
BIN
db/demo.tar
BIN
db/demo.tar
Binary file not shown.
@@ -1,3 +1,9 @@
|
||||
-- first fix deleted status of existing images
|
||||
UPDATE note_images SET isDeleted = 1 WHERE noteId IN (SELECT noteId FROM notes WHERE isDeleted = 1);
|
||||
|
||||
-- we don't need set data to null because table is going to be dropped anyway and we want image size into attribute
|
||||
UPDATE images SET isDeleted = 1 WHERE imageId NOT IN (SELECT imageId FROM note_images WHERE isDeleted = 0);
|
||||
|
||||
-- allow null for note content (for deleted notes)
|
||||
CREATE TABLE IF NOT EXISTS "notes_mig" (
|
||||
`noteId` TEXT NOT NULL,
|
||||
|
||||
1
db/migrations/0117__fix_attributes_of_deleted_notes.sql
Normal file
1
db/migrations/0117__fix_attributes_of_deleted_notes.sql
Normal file
@@ -0,0 +1 @@
|
||||
UPDATE attributes SET isDeleted = 1 WHERE noteId IN (SELECT noteId FROM notes WHERE isDeleted = 1);
|
||||
1
db/migrations/0118__fix_broken_relations.sql
Normal file
1
db/migrations/0118__fix_broken_relations.sql
Normal file
@@ -0,0 +1 @@
|
||||
UPDATE attributes SET isDeleted = 1 WHERE type = 'relation' AND value NOT IN (SELECT noteId FROM notes WHERE notes.isDeleted = 0);
|
||||
1
db/migrations/0119__rename_mirror_to_inverse.sql
Normal file
1
db/migrations/0119__rename_mirror_to_inverse.sql
Normal file
@@ -0,0 +1 @@
|
||||
UPDATE attributes SET value = replace(value, 'mirrorRelation', 'inverseRelation') WHERE type = 'relation-definition';
|
||||
@@ -0,0 +1 @@
|
||||
UPDATE attributes SET name = 'archived' where name = 'hideInAutocomplete';
|
||||
@@ -288,7 +288,7 @@
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Thu Nov 15 2018 13:33:27 GMT+0100 (Central European Standard Time)
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a>
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
|
||||
@@ -730,7 +730,7 @@
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Thu Nov 15 2018 13:33:27 GMT+0100 (Central European Standard Time)
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a>
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
|
||||
@@ -3814,7 +3814,7 @@ transactional by default.
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Thu Nov 15 2018 13:33:27 GMT+0100 (Central European Standard Time)
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a>
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
|
||||
@@ -511,7 +511,7 @@ Each note can have multiple (at least one) branches, meaning it can be placed in
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Thu Nov 15 2018 13:33:27 GMT+0100 (Central European Standard Time)
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a>
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
|
||||
@@ -216,7 +216,7 @@
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Thu Nov 15 2018 13:33:27 GMT+0100 (Central European Standard Time)
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a>
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
|
||||
@@ -358,7 +358,7 @@ this is different concept than attribute/relation.</div>
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Thu Nov 15 2018 13:33:27 GMT+0100 (Central European Standard Time)
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a>
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
|
||||
@@ -7297,7 +7297,7 @@ Cache is note instance scoped.
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Thu Nov 15 2018 13:33:27 GMT+0100 (Central European Standard Time)
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a>
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
|
||||
@@ -403,7 +403,7 @@
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Thu Nov 15 2018 13:33:27 GMT+0100 (Central European Standard Time)
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a>
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
|
||||
@@ -311,7 +311,7 @@
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Thu Nov 15 2018 13:33:27 GMT+0100 (Central European Standard Time)
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a>
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
|
||||
@@ -288,7 +288,7 @@
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Thu Nov 15 2018 13:33:27 GMT+0100 (Central European Standard Time)
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a>
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
|
||||
@@ -75,7 +75,7 @@ module.exports = ApiToken;</code></pre>
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Thu Nov 15 2018 13:33:27 GMT+0100 (Central European Standard Time)
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a>
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
|
||||
@@ -151,7 +151,7 @@ module.exports = Attribute;</code></pre>
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Thu Nov 15 2018 13:33:27 GMT+0100 (Central European Standard Time)
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a>
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
|
||||
@@ -105,7 +105,7 @@ module.exports = Branch;</code></pre>
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Thu Nov 15 2018 13:33:27 GMT+0100 (Central European Standard Time)
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a>
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
|
||||
@@ -93,7 +93,7 @@ module.exports = Entity;</code></pre>
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Thu Nov 15 2018 13:33:27 GMT+0100 (Central European Standard Time)
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a>
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
|
||||
@@ -92,7 +92,7 @@ module.exports = Link;</code></pre>
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Thu Nov 15 2018 13:33:27 GMT+0100 (Central European Standard Time)
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a>
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
|
||||
@@ -651,7 +651,7 @@ module.exports = Note;</code></pre>
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Thu Nov 15 2018 13:33:27 GMT+0100 (Central European Standard Time)
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a>
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
|
||||
@@ -91,7 +91,7 @@ module.exports = NoteRevision;</code></pre>
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Thu Nov 15 2018 13:33:27 GMT+0100 (Central European Standard Time)
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a>
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
|
||||
@@ -78,7 +78,7 @@ module.exports = Option;</code></pre>
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Thu Nov 15 2018 13:33:27 GMT+0100 (Central European Standard Time)
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a>
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
|
||||
@@ -75,7 +75,7 @@ module.exports = RecentNote;</code></pre>
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Thu Nov 15 2018 13:33:27 GMT+0100 (Central European Standard Time)
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a>
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
|
||||
@@ -594,7 +594,7 @@
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Thu Nov 15 2018 13:33:27 GMT+0100 (Central European Standard Time)
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a>
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Thu Nov 15 2018 13:33:27 GMT+0100 (Central European Standard Time)
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a>
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
|
||||
@@ -278,7 +278,7 @@ module.exports = BackendScriptApi;</code></pre>
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Thu Nov 15 2018 13:33:27 GMT+0100 (Central European Standard Time)
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a>
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
|
||||
@@ -719,7 +719,7 @@
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Thu Nov 15 2018 13:33:28 GMT+0100 (Central European Standard Time)
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a>
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
|
||||
@@ -2846,7 +2846,7 @@ Internally this serializes the anonymous function into string and sends it to ba
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Thu Nov 15 2018 13:33:28 GMT+0100 (Central European Standard Time)
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a>
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
|
||||
@@ -279,7 +279,7 @@
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Thu Nov 15 2018 13:33:28 GMT+0100 (Central European Standard Time)
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a>
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
|
||||
@@ -1316,7 +1316,7 @@ Its notable omission is the note content.</div>
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Thu Nov 15 2018 13:33:28 GMT+0100 (Central European Standard Time)
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a>
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
|
||||
@@ -76,7 +76,7 @@ export default Branch;</code></pre>
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Thu Nov 15 2018 13:33:28 GMT+0100 (Central European Standard Time)
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a>
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
|
||||
@@ -64,7 +64,7 @@ export default NoteFull;</code></pre>
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Thu Nov 15 2018 13:33:28 GMT+0100 (Central European Standard Time)
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a>
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
|
||||
@@ -128,7 +128,7 @@ export default NoteShort;</code></pre>
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Thu Nov 15 2018 13:33:28 GMT+0100 (Central European Standard Time)
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a>
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
|
||||
@@ -339,7 +339,7 @@
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Thu Nov 15 2018 13:33:28 GMT+0100 (Central European Standard Time)
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a>
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Thu Nov 15 2018 13:33:28 GMT+0100 (Central European Standard Time)
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a>
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
|
||||
@@ -271,7 +271,7 @@ export default FrontendScriptApi;</code></pre>
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Thu Nov 15 2018 13:33:28 GMT+0100 (Central European Standard Time)
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a>
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
|
||||
@@ -6,6 +6,7 @@ const log = require('./src/services/log');
|
||||
const cls = require('./src/services/cls');
|
||||
const url = require("url");
|
||||
const port = require('./src/services/port');
|
||||
const appIconService = require('./src/services/app_icon');
|
||||
|
||||
const app = electron.app;
|
||||
const globalShortcut = electron.globalShortcut;
|
||||
@@ -13,6 +14,8 @@ const globalShortcut = electron.globalShortcut;
|
||||
// Adds debug features like hotkeys for triggering dev tools and reload
|
||||
require('electron-debug')();
|
||||
|
||||
appIconService.installLocalAppIcon();
|
||||
|
||||
// Prevent window being garbage collected
|
||||
let mainWindow;
|
||||
|
||||
@@ -70,6 +73,8 @@ app.on('activate', () => {
|
||||
});
|
||||
|
||||
app.on('ready', async () => {
|
||||
app.setAppUserModelId('com.github.zadam.trilium');
|
||||
|
||||
mainWindow = await createMainWindow();
|
||||
|
||||
const result = globalShortcut.register('CommandOrControl+Alt+P', cls.wrap(async () => {
|
||||
|
||||
7
jsdoc-conf.json
Normal file
7
jsdoc-conf.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"templates": {
|
||||
"default": {
|
||||
"includeDate": false
|
||||
}
|
||||
}
|
||||
}
|
||||
315
package-lock.json
generated
315
package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "trilium",
|
||||
"version": "0.23.1",
|
||||
"version": "0.24.5",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -65,21 +65,21 @@
|
||||
}
|
||||
},
|
||||
"@jimp/bmp": {
|
||||
"version": "0.5.4",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/bmp/-/bmp-0.5.4.tgz",
|
||||
"integrity": "sha512-P/ezH1FuoM3FwS0Dm2ZGkph4x5/rPBzFLEZor7KQkmGUnYEIEG4o0BUcAWFmJOp2HgzbT6O2SfrpJNBOcVACzQ==",
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/bmp/-/bmp-0.6.0.tgz",
|
||||
"integrity": "sha512-zZOcVT1zK/1QL5a7qirkzPPgDKB1ianER7pBdpR2J71vx/g8MnrPbL3h/jEVPxjdci2Hph/VWhc/oLBtTbqO8w==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.5.0",
|
||||
"@jimp/utils": "^0.6.0",
|
||||
"bmp-js": "^0.1.0",
|
||||
"core-js": "^2.5.7"
|
||||
}
|
||||
},
|
||||
"@jimp/core": {
|
||||
"version": "0.5.4",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/core/-/core-0.5.4.tgz",
|
||||
"integrity": "sha512-n3uvHy2ndUKItmbhnRO8xmU8J6KR+v6CQxO9sbeUDpSc3VXc1PkqrA8ZsCVFCjnDFcGBXL+MJeCTyQzq5W9Crw==",
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/core/-/core-0.6.0.tgz",
|
||||
"integrity": "sha512-ngAkyCLtX7buc2QyFy0ql/j4R2wGYQVsVhW2G3Y0GVAAklRIFIUYpyNKrqs228xA8f2O6XStbDStFlYkt7uNeg==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.5.0",
|
||||
"@jimp/utils": "^0.6.0",
|
||||
"any-base": "^1.1.0",
|
||||
"buffer": "^5.2.0",
|
||||
"core-js": "^2.5.7",
|
||||
@@ -114,252 +114,252 @@
|
||||
}
|
||||
},
|
||||
"@jimp/custom": {
|
||||
"version": "0.5.4",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/custom/-/custom-0.5.4.tgz",
|
||||
"integrity": "sha512-tLfyJoyouDl2J3RPFGfDzTtE+4S8ljqJUmLzy/cmx1n7+xS5TpLPdPskp7UaeAfNTqdF4CNAm94KYoxTZdj2mg==",
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/custom/-/custom-0.6.0.tgz",
|
||||
"integrity": "sha512-+YZIWhf03Rfbi+VPbHomKInu3tcntF/aij/JrIJd1QZq13f8m3mRNxakXupiL18KH0C8BPNDk8RiwFX+HaOw3A==",
|
||||
"requires": {
|
||||
"@jimp/core": "^0.5.4",
|
||||
"@jimp/core": "^0.6.0",
|
||||
"core-js": "^2.5.7"
|
||||
}
|
||||
},
|
||||
"@jimp/gif": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/gif/-/gif-0.5.0.tgz",
|
||||
"integrity": "sha512-HVB4c7b8r/yCpjhCjVNPRFLuujTav5UPmcQcFJjU6aIxmne6e29rAjRJEv3UMamHDGSu/96PzOsPZBO5U+ZGww==",
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/gif/-/gif-0.6.0.tgz",
|
||||
"integrity": "sha512-aWQ02P0ymTN1eh0BVsY+84wMdb/QeiVpCNQZl9y50cRnpuMM8TTmF/ZdCEBDiTRFcwXzHsqBXcLwEcYp3X2lTw==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.5.0",
|
||||
"@jimp/utils": "^0.6.0",
|
||||
"core-js": "^2.5.7",
|
||||
"omggif": "^1.0.9"
|
||||
}
|
||||
},
|
||||
"@jimp/jpeg": {
|
||||
"version": "0.5.4",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/jpeg/-/jpeg-0.5.4.tgz",
|
||||
"integrity": "sha512-YaPWm+YSGCThNE/jLMckM3Qs6uaMxd/VsHOnEaqu5tGA4GFbfVaWHjKqkNGAFuiNV+HdgKlNcCOF3of+elvzqQ==",
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/jpeg/-/jpeg-0.6.0.tgz",
|
||||
"integrity": "sha512-quYb+lM4h57jQvr2q9dEIkc0laTljws4dunIdFhJRfa5UlNL5mHInk8h5MxyALo0mZdT07TAcxiDHw5QXZ28JQ==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.5.0",
|
||||
"@jimp/utils": "^0.6.0",
|
||||
"core-js": "^2.5.7",
|
||||
"jpeg-js": "^0.3.4"
|
||||
}
|
||||
},
|
||||
"@jimp/plugin-blit": {
|
||||
"version": "0.5.4",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-blit/-/plugin-blit-0.5.4.tgz",
|
||||
"integrity": "sha512-WqDYOugv76hF1wnKy7+xPGf9PUbcm9vPW28/jHWn1hjbb2GnusJ2fVEFad76J/1SPfhrQ2Uebf2QCWJuLmOqZg==",
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-blit/-/plugin-blit-0.6.0.tgz",
|
||||
"integrity": "sha512-LjiCa+8OT2fgmvBpZt0ogurg/eu5kB8ZFWDRwHPcf8i+058sZC20dar/qrjVd5Knssq4ynjb5oAHsGuJq16Rqw==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.5.0",
|
||||
"@jimp/utils": "^0.6.0",
|
||||
"core-js": "^2.5.7"
|
||||
}
|
||||
},
|
||||
"@jimp/plugin-blur": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-blur/-/plugin-blur-0.5.0.tgz",
|
||||
"integrity": "sha512-5k0PXCA1RTJdITL7yMAyZ5tGQjKLHqFvwdXj/PCoBo5PuMyr0x6qfxmQEySixGk/ZHdDxMi80vYxHdKHjNNgjg==",
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-blur/-/plugin-blur-0.6.0.tgz",
|
||||
"integrity": "sha512-/vjGcEiHda6OLTCYqXPFkfSTbL+RatZoGcp1vewcWqChUccn9QVINTlxB7nEI/3Nb/i7KdhOPNEQh1k6q6QXsw==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.5.0",
|
||||
"@jimp/utils": "^0.6.0",
|
||||
"core-js": "^2.5.7"
|
||||
}
|
||||
},
|
||||
"@jimp/plugin-color": {
|
||||
"version": "0.5.5",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-color/-/plugin-color-0.5.5.tgz",
|
||||
"integrity": "sha512-hWeOqNCmLguGYLhSvBrpfCvlijsMEVaLZAOod62s1rzWnujozyKOzm2eZe+W3To6mHbp5RGJNVrIwHBWMab4ug==",
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-color/-/plugin-color-0.6.0.tgz",
|
||||
"integrity": "sha512-mvDeAwN8ZpDkOaABMJ0w9zUzo9OOtu1qvvPkSirXDTMiXt1nsbfz8BoeoD7nU2MFhQj5MiGjH65UDnsH5ZzYuw==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.5.0",
|
||||
"@jimp/utils": "^0.6.0",
|
||||
"core-js": "^2.5.7",
|
||||
"tinycolor2": "^1.4.1"
|
||||
}
|
||||
},
|
||||
"@jimp/plugin-contain": {
|
||||
"version": "0.5.4",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-contain/-/plugin-contain-0.5.4.tgz",
|
||||
"integrity": "sha512-8YJh4FI3S69unri0nJsWeqVLeVGA77N2R0Ws16iSuCCD/5UnWd9FeWRrSbKuidBG6TdMBaG2KUqSYZeHeH9GOQ==",
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-contain/-/plugin-contain-0.6.0.tgz",
|
||||
"integrity": "sha512-gPHnoQkDztMbvnTVo01BaMoM/hhDJdeJ7FRToD4p4Qvdor4V0I6NXtjOeUPXfD94miTgh/UTyJDqeG4GZzi4sA==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.5.0",
|
||||
"@jimp/utils": "^0.6.0",
|
||||
"core-js": "^2.5.7"
|
||||
}
|
||||
},
|
||||
"@jimp/plugin-cover": {
|
||||
"version": "0.5.4",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-cover/-/plugin-cover-0.5.4.tgz",
|
||||
"integrity": "sha512-2Rur7b44WiDDgizUI2M2uYWc1RmfhU5KjKS1xXruobjQ0tXkf5xlrPXSushq0hB6Ne0Ss6wv0+/6eQ8WeGHU2w==",
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-cover/-/plugin-cover-0.6.0.tgz",
|
||||
"integrity": "sha512-iv9lA2v3qv+x3eaTThtyzFg+hO8/pSnM8NBymC5OlpSJnR54aWi7BVFXLJAF27T4EZyXko432PVul2IdY3BEPw==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.5.0",
|
||||
"@jimp/utils": "^0.6.0",
|
||||
"core-js": "^2.5.7"
|
||||
}
|
||||
},
|
||||
"@jimp/plugin-crop": {
|
||||
"version": "0.5.4",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-crop/-/plugin-crop-0.5.4.tgz",
|
||||
"integrity": "sha512-6t0rqn4VazquGk48tO6hFBrQ+nkvC+A1RnR6UM/m8ZtG2/yjpwF0MXcpgJI1Fb+a4Ug7BY1fu2GPcZOhnAVK/g==",
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-crop/-/plugin-crop-0.6.0.tgz",
|
||||
"integrity": "sha512-YftdmFZ2YnZDYyBulkStCt2MZbKKfbjytkE+6i3Djk2b/Rfryg5xjgzVnAumCRQJhVPukexrnc2V7KKbEgx7mQ==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.5.0",
|
||||
"@jimp/utils": "^0.6.0",
|
||||
"core-js": "^2.5.7"
|
||||
}
|
||||
},
|
||||
"@jimp/plugin-displace": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-displace/-/plugin-displace-0.5.0.tgz",
|
||||
"integrity": "sha512-Bec7SQvnmKia4hOXEDjeNVx7vo/1bWqjuV6NO8xbNQcAO3gaCl91c9FjMDhsfAVb0Ou6imhbIuFPrLxorXsecQ==",
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-displace/-/plugin-displace-0.6.0.tgz",
|
||||
"integrity": "sha512-kkva5Fy3r7J7QmiqYQ5c9NeUKKkN7+KSfCGsZ6tkRHK4REMIXhQO/OnJN8XG6RReV29O6QykdyeTXDiHUDiROw==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.5.0",
|
||||
"@jimp/utils": "^0.6.0",
|
||||
"core-js": "^2.5.7"
|
||||
}
|
||||
},
|
||||
"@jimp/plugin-dither": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-dither/-/plugin-dither-0.5.0.tgz",
|
||||
"integrity": "sha512-We2WJQsD/Lm8oqBFp/vUv9/5r2avyenL+wNNu/s2b1HqA5O4sPGrjHy9K6vIov0NroQGCQ3bNznLkTmjiHKBcg==",
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-dither/-/plugin-dither-0.6.0.tgz",
|
||||
"integrity": "sha512-ILSG7bl3SOqmcIa9C4nBvs0h0E0ObnMbeKWUZiNuz6i0OAlbxryiIfU4j0UVQD5XqT9ksC5mviVNrvOMw4SZLw==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.5.0",
|
||||
"@jimp/utils": "^0.6.0",
|
||||
"core-js": "^2.5.7"
|
||||
}
|
||||
},
|
||||
"@jimp/plugin-flip": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-flip/-/plugin-flip-0.5.0.tgz",
|
||||
"integrity": "sha512-D/ehBQxLMNR7oNd80KXo4tnSET5zEm5mR70khYOTtTlfti/DlLp3qOdjPOzfLyAdqO7Ly4qCaXrIsnia+pfPrA==",
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-flip/-/plugin-flip-0.6.0.tgz",
|
||||
"integrity": "sha512-MXGGwABjERvfqVadEzJuVAmbsEQfjxXD0O/mMBegU1Qh7/JmnKAVplQCnojsMPxUdao/FKZjQqOnB/j4LLJtOQ==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.5.0",
|
||||
"@jimp/utils": "^0.6.0",
|
||||
"core-js": "^2.5.7"
|
||||
}
|
||||
},
|
||||
"@jimp/plugin-gaussian": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-gaussian/-/plugin-gaussian-0.5.0.tgz",
|
||||
"integrity": "sha512-Ln4kgxblv0/YzLBDb/J8DYPLhDzKH87Y8yHh5UKv3H+LPKnLaEG3L4iKTE9ivvdocnjmrtTFMYcWv2ERSPeHcg==",
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-gaussian/-/plugin-gaussian-0.6.0.tgz",
|
||||
"integrity": "sha512-RUsBCyj6Ukxgn/TU8v6c6WRbSFqKM0iknLVqDkKIuiOyJB7ougv66fqomh/i/h3ihIkEnf50BuO0c3ovrczfvw==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.5.0",
|
||||
"@jimp/utils": "^0.6.0",
|
||||
"core-js": "^2.5.7"
|
||||
}
|
||||
},
|
||||
"@jimp/plugin-invert": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-invert/-/plugin-invert-0.5.0.tgz",
|
||||
"integrity": "sha512-/vyKeIi3T7puf+8ruWovTjzDC585EnTwJ+lGOOUYiNPsdn4JDFe1B3xd+Ayv9aCQbXDIlPElZaM9vd/+wqDiIQ==",
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-invert/-/plugin-invert-0.6.0.tgz",
|
||||
"integrity": "sha512-zTCqK8el6eqcNKAxw0y57gHBFgxygI5iM8dQDPyqsvVWO71i8XII7ubnJhEvPPN7vhIKlOSnS9XXglezvJoX4Q==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.5.0",
|
||||
"@jimp/utils": "^0.6.0",
|
||||
"core-js": "^2.5.7"
|
||||
}
|
||||
},
|
||||
"@jimp/plugin-mask": {
|
||||
"version": "0.5.4",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-mask/-/plugin-mask-0.5.4.tgz",
|
||||
"integrity": "sha512-mUJ04pCrUWaJGXPjgoVbzhIQB8cVobj2ZEFlGO3BEAjyylYMrdJlNlsER8dd7UuJ2L/a4ocWtFDdsnuicnBghQ==",
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-mask/-/plugin-mask-0.6.0.tgz",
|
||||
"integrity": "sha512-zkZVqAA7lxWhkn5EbPjBQ6tPluYIGfLMSX4kD1gksj+MVJJnVAd459AVuEXCvkUvv4wG5AlH8m6ve5NZj9vvxw==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.5.0",
|
||||
"@jimp/utils": "^0.6.0",
|
||||
"core-js": "^2.5.7"
|
||||
}
|
||||
},
|
||||
"@jimp/plugin-normalize": {
|
||||
"version": "0.5.4",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-normalize/-/plugin-normalize-0.5.4.tgz",
|
||||
"integrity": "sha512-Q5W0oEz9wxsjuhvHAJynI/OqXZcmqEAuRONQId7Aw5ulCXSOg9C4y2a67EO7aZAt55T+zMVxI9UpVUpzVvO6hw==",
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-normalize/-/plugin-normalize-0.6.0.tgz",
|
||||
"integrity": "sha512-7bNGT+S0rw9gvmxpkNsA19JSqBZYFrAn9QhEmoN4HIimdKtJaoLJh/GnxrPuOBLuv1IPJntoTOOWvOmfrQ6/ww==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.5.0",
|
||||
"@jimp/utils": "^0.6.0",
|
||||
"core-js": "^2.5.7"
|
||||
}
|
||||
},
|
||||
"@jimp/plugin-print": {
|
||||
"version": "0.5.4",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-print/-/plugin-print-0.5.4.tgz",
|
||||
"integrity": "sha512-DOZr5TY9WyMWFBD37oz7KpTEBVioFIHQF/gH5b3O5jjFyj4JPMkw7k3kVBve9lIrzIYrvLqe0wH59vyAwpeEFg==",
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-print/-/plugin-print-0.6.0.tgz",
|
||||
"integrity": "sha512-kXNHYo7bGQiMZkUqhCvm6OomjJtZnLGs7cgXp9qsCfPcDBLLW+X3oxnoLaePQMlpQt6hX/lzFnNaWKv/KB1jlA==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.5.0",
|
||||
"@jimp/utils": "^0.6.0",
|
||||
"core-js": "^2.5.7",
|
||||
"load-bmfont": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"@jimp/plugin-resize": {
|
||||
"version": "0.5.4",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-resize/-/plugin-resize-0.5.4.tgz",
|
||||
"integrity": "sha512-lXNprNAT0QY1D1vG/1x6urUTlWuZe2dfL29P81ApW2Yfcio471+oqo45moX5FLS0q24xU600g7cHGf2/TzqSfA==",
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-resize/-/plugin-resize-0.6.0.tgz",
|
||||
"integrity": "sha512-m0AA/mPkJG++RuftBFDUMRenqgIN/uSh88Kqs33VURYaabApni4ML3QslE1TCJtl2Lnu1eosxYlbzODjHx49eg==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.5.0",
|
||||
"@jimp/utils": "^0.6.0",
|
||||
"core-js": "^2.5.7"
|
||||
}
|
||||
},
|
||||
"@jimp/plugin-rotate": {
|
||||
"version": "0.5.4",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-rotate/-/plugin-rotate-0.5.4.tgz",
|
||||
"integrity": "sha512-SIdUpMc8clObMchy8TnjgHgcXEQM992z5KavgiuOnCuBlsmSHtE3MrXTOyMW0Dn3gqapV9Y5vygrLm/BVtCCsg==",
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-rotate/-/plugin-rotate-0.6.0.tgz",
|
||||
"integrity": "sha512-1QGlIisyxs2HNLuynq/ETc4h7E6At3yR+IYAhG9U4KONG4RqlIy0giyDhnfEZaiqOE+O7f+0Z7zN6GoSHmQjzg==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.5.0",
|
||||
"@jimp/utils": "^0.6.0",
|
||||
"core-js": "^2.5.7"
|
||||
}
|
||||
},
|
||||
"@jimp/plugin-scale": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-scale/-/plugin-scale-0.5.0.tgz",
|
||||
"integrity": "sha512-5InIOr3cNtrS5aQ/uaosNf28qLLc0InpNGKFmGFTv8oqZqLch6PtDTjDBZ1GGWsPdA/ljy4Qyy7mJO1QBmgQeQ==",
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-scale/-/plugin-scale-0.6.0.tgz",
|
||||
"integrity": "sha512-le/ttYwYioNPRoMlMaoJMCTv+m8d1v0peo/3J8E6Rf9ok7Bw3agkvjL9ILnsmr8jXj1YLrBSPKRs5nJ6ziM/qA==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.5.0",
|
||||
"@jimp/utils": "^0.6.0",
|
||||
"core-js": "^2.5.7"
|
||||
}
|
||||
},
|
||||
"@jimp/plugins": {
|
||||
"version": "0.5.5",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugins/-/plugins-0.5.5.tgz",
|
||||
"integrity": "sha512-9oF6LbSM/K7YkFCcxaPaD8NUkL/ZY8vT8NIGfQ/NpX+tKQtcsLHcRavHpUC+M1xXShv/QGx9OdBV/jgiu82QYg==",
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugins/-/plugins-0.6.0.tgz",
|
||||
"integrity": "sha512-9+znfBJM1B31kvw+IcQFnAuDntQhwca/SONFnKOSZ8BNiQdiuTNbXHFxOo3tvdv1ngtB+LkkiTgK+QoF358b8g==",
|
||||
"requires": {
|
||||
"@jimp/plugin-blit": "^0.5.4",
|
||||
"@jimp/plugin-blur": "^0.5.0",
|
||||
"@jimp/plugin-color": "^0.5.5",
|
||||
"@jimp/plugin-contain": "^0.5.4",
|
||||
"@jimp/plugin-cover": "^0.5.4",
|
||||
"@jimp/plugin-crop": "^0.5.4",
|
||||
"@jimp/plugin-displace": "^0.5.0",
|
||||
"@jimp/plugin-dither": "^0.5.0",
|
||||
"@jimp/plugin-flip": "^0.5.0",
|
||||
"@jimp/plugin-gaussian": "^0.5.0",
|
||||
"@jimp/plugin-invert": "^0.5.0",
|
||||
"@jimp/plugin-mask": "^0.5.4",
|
||||
"@jimp/plugin-normalize": "^0.5.4",
|
||||
"@jimp/plugin-print": "^0.5.4",
|
||||
"@jimp/plugin-resize": "^0.5.4",
|
||||
"@jimp/plugin-rotate": "^0.5.4",
|
||||
"@jimp/plugin-scale": "^0.5.0",
|
||||
"@jimp/plugin-blit": "^0.6.0",
|
||||
"@jimp/plugin-blur": "^0.6.0",
|
||||
"@jimp/plugin-color": "^0.6.0",
|
||||
"@jimp/plugin-contain": "^0.6.0",
|
||||
"@jimp/plugin-cover": "^0.6.0",
|
||||
"@jimp/plugin-crop": "^0.6.0",
|
||||
"@jimp/plugin-displace": "^0.6.0",
|
||||
"@jimp/plugin-dither": "^0.6.0",
|
||||
"@jimp/plugin-flip": "^0.6.0",
|
||||
"@jimp/plugin-gaussian": "^0.6.0",
|
||||
"@jimp/plugin-invert": "^0.6.0",
|
||||
"@jimp/plugin-mask": "^0.6.0",
|
||||
"@jimp/plugin-normalize": "^0.6.0",
|
||||
"@jimp/plugin-print": "^0.6.0",
|
||||
"@jimp/plugin-resize": "^0.6.0",
|
||||
"@jimp/plugin-rotate": "^0.6.0",
|
||||
"@jimp/plugin-scale": "^0.6.0",
|
||||
"core-js": "^2.5.7",
|
||||
"timm": "^1.6.1"
|
||||
}
|
||||
},
|
||||
"@jimp/png": {
|
||||
"version": "0.5.4",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/png/-/png-0.5.4.tgz",
|
||||
"integrity": "sha512-J2NU7368zihF1HUZdmpXsL/Hhyf+I3ubmK+6Uz3Uoyvtk1VS7dO3L0io6fJQutfWmPZ4bvu6Ry022oHjbi6QCA==",
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/png/-/png-0.6.0.tgz",
|
||||
"integrity": "sha512-DBtMyQyrJxuKI7/1dVqLek+rCMM8U6BSOTHgo05wU7lhJKTB6fn2tbYfsnHQKzd9ld1M2qKuC+O1GTVdB2yl6w==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.5.0",
|
||||
"@jimp/utils": "^0.6.0",
|
||||
"core-js": "^2.5.7",
|
||||
"pngjs": "^3.3.3"
|
||||
}
|
||||
},
|
||||
"@jimp/tiff": {
|
||||
"version": "0.5.4",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/tiff/-/tiff-0.5.4.tgz",
|
||||
"integrity": "sha512-hr7Zq3eWjAZ+itSwuAObIWMRNv7oHVM3xuEDC2ouP7HfE7woBtyhCyfA7u12KlgtM57gKWeogXqTlewRGVzx6g==",
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/tiff/-/tiff-0.6.0.tgz",
|
||||
"integrity": "sha512-PV95CquEsolFziq0zZrAEJIzZSKwMK89TvkOXTPDi/xesgdXGC2rtG1IZFpC9L4UX5hi/M5GaeJa49xULX6Nqw==",
|
||||
"requires": {
|
||||
"core-js": "^2.5.7",
|
||||
"utif": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"@jimp/types": {
|
||||
"version": "0.5.4",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/types/-/types-0.5.4.tgz",
|
||||
"integrity": "sha512-nbZXM6TsdpnYHIBd8ZuoxGpvmxc2SqiggY30/bhOP/VJQoDBzm2v/20Ywz5M0snpIK2SdYG52eZPNjfjqUP39w==",
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/types/-/types-0.6.0.tgz",
|
||||
"integrity": "sha512-j4tm82huEWpLrwave/2NYnMTY6us/6K9Js6Vd/CHoM/ki8M71tMXEVzc8tly92wtnEzQ9+FEk0Ue6pYo68m/5A==",
|
||||
"requires": {
|
||||
"@jimp/bmp": "^0.5.4",
|
||||
"@jimp/gif": "^0.5.0",
|
||||
"@jimp/jpeg": "^0.5.4",
|
||||
"@jimp/png": "^0.5.4",
|
||||
"@jimp/tiff": "^0.5.4",
|
||||
"@jimp/bmp": "^0.6.0",
|
||||
"@jimp/gif": "^0.6.0",
|
||||
"@jimp/jpeg": "^0.6.0",
|
||||
"@jimp/png": "^0.6.0",
|
||||
"@jimp/tiff": "^0.6.0",
|
||||
"core-js": "^2.5.7",
|
||||
"timm": "^1.6.1"
|
||||
}
|
||||
},
|
||||
"@jimp/utils": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-0.5.0.tgz",
|
||||
"integrity": "sha512-7H9RFVU+Li2XmEko0GGyzy7m7JjSc7qa+m8l3fUzYg2GtwASApjKF/LSG2AUQCUmDKFLdfIEVjxvKvZUJFEmpw==",
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-0.6.0.tgz",
|
||||
"integrity": "sha512-z5iYEfqc45vlYweROneNkjv32en6jS7lPL/eMLIvaEcQAHaoza20Dw8fUoJ0Ht9S92kR74xeTunAZq+gK2w67Q==",
|
||||
"requires": {
|
||||
"core-js": "^2.5.7"
|
||||
}
|
||||
@@ -399,9 +399,9 @@
|
||||
"integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow=="
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "8.10.37",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.37.tgz",
|
||||
"integrity": "sha512-Jp39foY8Euv/PG4OGPyzxis82mnjcUtXLEMA8oFMCE4ilmuJgZPdV2nZNV1moz+99EJTtcpOSgDCgATUwABKig==",
|
||||
"version": "8.10.38",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.38.tgz",
|
||||
"integrity": "sha512-EibsnbJerd0hBFaDjJStFrVbVBAtOy4dgL8zZFw0uOvPqzBAX59Ci8cgjg3+RgJIWhsB5A4c+pi+D4P9tQQh/A==",
|
||||
"dev": true
|
||||
},
|
||||
"abab": {
|
||||
@@ -426,7 +426,8 @@
|
||||
"accessibility-developer-tools": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/accessibility-developer-tools/-/accessibility-developer-tools-2.12.0.tgz",
|
||||
"integrity": "sha1-PaDM6dbsY3OWS4TzXbfPw996tRQ="
|
||||
"integrity": "sha1-PaDM6dbsY3OWS4TzXbfPw996tRQ=",
|
||||
"dev": true
|
||||
},
|
||||
"acorn": {
|
||||
"version": "5.7.3",
|
||||
@@ -2202,6 +2203,7 @@
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/devtron/-/devtron-1.4.0.tgz",
|
||||
"integrity": "sha1-tedIvW6Vu+cL/MaKrm/mlhGUQeE=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"accessibility-developer-tools": "^2.11.0",
|
||||
"highlight.js": "^9.3.0",
|
||||
@@ -2372,9 +2374,9 @@
|
||||
"integrity": "sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ=="
|
||||
},
|
||||
"electron": {
|
||||
"version": "4.0.0-beta.7",
|
||||
"resolved": "https://registry.npmjs.org/electron/-/electron-4.0.0-beta.7.tgz",
|
||||
"integrity": "sha512-770Hzxq10nQrzq39uVmvHLNKpPY3TCNrk+IYGDQTNWqmkreXZX6+9iflMMo+xdg1ZHysrTj1QQZvsjjBY176pg==",
|
||||
"version": "4.0.0-beta.8",
|
||||
"resolved": "https://registry.npmjs.org/electron/-/electron-4.0.0-beta.8.tgz",
|
||||
"integrity": "sha512-zo0Tf3t1uary5O9Skdlo37axs+vvh9CPC+MkvZnnX3MA/3kWIc+I6jN+AL4bHUdxsMVtjbY8KnusjnCjKSb0sg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "^8.0.24",
|
||||
@@ -4903,7 +4905,8 @@
|
||||
"highlight.js": {
|
||||
"version": "9.12.0",
|
||||
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.12.0.tgz",
|
||||
"integrity": "sha1-5tnb5Xy+/mB1HwKvM2GVhwyQwB4="
|
||||
"integrity": "sha1-5tnb5Xy+/mB1HwKvM2GVhwyQwB4=",
|
||||
"dev": true
|
||||
},
|
||||
"hosted-git-info": {
|
||||
"version": "2.7.1",
|
||||
@@ -4965,7 +4968,8 @@
|
||||
"humanize-plus": {
|
||||
"version": "1.8.2",
|
||||
"resolved": "https://registry.npmjs.org/humanize-plus/-/humanize-plus-1.8.2.tgz",
|
||||
"integrity": "sha1-pls0RZrWNnrbs3B6gqPJ+RYWcDA="
|
||||
"integrity": "sha1-pls0RZrWNnrbs3B6gqPJ+RYWcDA=",
|
||||
"dev": true
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.23",
|
||||
@@ -5750,14 +5754,14 @@
|
||||
"dev": true
|
||||
},
|
||||
"jimp": {
|
||||
"version": "0.5.6",
|
||||
"resolved": "https://registry.npmjs.org/jimp/-/jimp-0.5.6.tgz",
|
||||
"integrity": "sha512-H0nHTu6KgAgQzDxa38ew2dXbnRzKm1w5uEyhMIxqwCQVjwgarOjjkV/avbNLxfxRHAFaNp4rGIc/qm8P+uhX9A==",
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/jimp/-/jimp-0.6.0.tgz",
|
||||
"integrity": "sha512-RYpN+AAlTEMf8Bnkhq2eeTNyr70rDK/2UUfUqzBJmwmZwdR6fxRJvgbCGWT1BDVRxaAqo+4CWm8ePBxOIsr4jg==",
|
||||
"requires": {
|
||||
"@babel/polyfill": "^7.0.0",
|
||||
"@jimp/custom": "^0.5.4",
|
||||
"@jimp/plugins": "^0.5.5",
|
||||
"@jimp/types": "^0.5.4",
|
||||
"@jimp/custom": "^0.6.0",
|
||||
"@jimp/plugins": "^0.6.0",
|
||||
"@jimp/types": "^0.6.0",
|
||||
"core-js": "^2.5.7"
|
||||
}
|
||||
},
|
||||
@@ -6417,11 +6421,18 @@
|
||||
"integrity": "sha512-L+xvyD9MkoYMXb1jAmzI/lWYAxAMCPvIBSWur0PZ5nOf5euahRLVqH//FKW9mWp2lkqUgYiXPgkzfMUFi4zVDw=="
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.20",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.20.tgz",
|
||||
"integrity": "sha512-HrkrPaP9vGuWbLK1B1FfgAkbqNjIuy4eHlIYnFi7kamZyLLrGlo2mpcx0bBmNpKqBtYtAfGbodDddIgddSJC2A==",
|
||||
"version": "2.1.21",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz",
|
||||
"integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==",
|
||||
"requires": {
|
||||
"mime-db": "~1.36.0"
|
||||
"mime-db": "~1.37.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"mime-db": {
|
||||
"version": "1.37.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz",
|
||||
"integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"mimic-fn": {
|
||||
@@ -7770,9 +7781,9 @@
|
||||
}
|
||||
},
|
||||
"pako": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz",
|
||||
"integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg=="
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.7.tgz",
|
||||
"integrity": "sha512-3HNK5tW4x8o5mO8RuHZp3Ydw9icZXx0RANAOMzlMzx7LVXhMJ4mo3MOBpzyd7r/+RUu8BmndP47LXT+vzjtWcQ=="
|
||||
},
|
||||
"parse-author": {
|
||||
"version": "2.0.0",
|
||||
@@ -10821,9 +10832,9 @@
|
||||
}
|
||||
},
|
||||
"ws": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-6.1.0.tgz",
|
||||
"integrity": "sha512-H3dGVdGvW2H8bnYpIDc3u3LH8Wue3Qh+Zto6aXXFzvESkTVT6rAfKR6tR/+coaUvxs8yHtmNV0uioBF62ZGSTg==",
|
||||
"version": "6.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-6.1.2.tgz",
|
||||
"integrity": "sha512-rfUqzvz0WxmSXtJpPMX2EeASXabOrSMk1ruMOV3JBTBjo4ac2lDjGGsbQSyxj8Odhw5fBib8ZKEjDNvgouNKYw==",
|
||||
"requires": {
|
||||
"async-limiter": "~1.0.0"
|
||||
}
|
||||
|
||||
19
package.json
19
package.json
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"name": "trilium",
|
||||
"productName": "Trilium Notes",
|
||||
"description": "Trilium Notes",
|
||||
"version": "0.24.0-beta",
|
||||
"version": "0.25.0-beta",
|
||||
"license": "AGPL-3.0-only",
|
||||
"main": "electron.js",
|
||||
"bin": {
|
||||
@@ -13,12 +14,9 @@
|
||||
},
|
||||
"scripts": {
|
||||
"start": "node ./src/www",
|
||||
"test-electron": "xo",
|
||||
"rebuild-electron": "electron-rebuild",
|
||||
"start-electron": "electron . --disable-gpu",
|
||||
"build-electron": "electron-packager . --out=dist --asar --overwrite --platform=win32,linux --arch=ia32,x64 --app-version= --icon=src/public/app-icons/win/icon.ico",
|
||||
"build-backend-docs": "jsdoc -d ./docs/backend_api src/entities/*.js src/services/backend_script_api.js",
|
||||
"build-frontend-docs": "jsdoc -d ./docs/frontend_api src/public/javascripts/entities/*.js src/public/javascripts/services/frontend_script_api.js",
|
||||
"build-backend-docs": "jsdoc -c jsdoc-conf.json -d ./docs/backend_api src/entities/*.js src/services/backend_script_api.js",
|
||||
"build-frontend-docs": "jsdoc -c jsdoc-conf.json -d ./docs/frontend_api src/public/javascripts/entities/*.js src/public/javascripts/services/frontend_script_api.js",
|
||||
"build-docs": "npm run build-backend-docs && npm run build-frontend-docs"
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -29,7 +27,6 @@
|
||||
"commonmark": "0.28.1",
|
||||
"cookie-parser": "1.4.3",
|
||||
"debug": "4.1.0",
|
||||
"devtron": "1.4.0",
|
||||
"ejs": "2.6.1",
|
||||
"electron-debug": "2.0.0",
|
||||
"electron-dl": "1.12.0",
|
||||
@@ -46,7 +43,8 @@
|
||||
"imagemin-mozjpeg": "8.0.0",
|
||||
"imagemin-pngquant": "6.0.0",
|
||||
"ini": "1.3.5",
|
||||
"jimp": "0.5.6",
|
||||
"jimp": "0.6.0",
|
||||
"mime-types": "^2.1.21",
|
||||
"moment": "2.22.2",
|
||||
"multer": "1.4.1",
|
||||
"open": "0.0.5",
|
||||
@@ -64,11 +62,12 @@
|
||||
"tar-stream": "1.6.2",
|
||||
"turndown": "5.0.1",
|
||||
"unescape": "1.0.1",
|
||||
"ws": "6.1.0",
|
||||
"ws": "6.1.2",
|
||||
"xml2js": "0.4.19"
|
||||
},
|
||||
"devDependencies": {
|
||||
"electron": "4.0.0-beta.7",
|
||||
"devtron": "1.4.0",
|
||||
"electron": "4.0.0-beta.8",
|
||||
"electron-compile": "6.4.3",
|
||||
"electron-packager": "12.2.0",
|
||||
"electron-rebuild": "1.8.2",
|
||||
|
||||
@@ -105,6 +105,11 @@ class Attribute extends Entity {
|
||||
this.dateModified = dateUtils.nowDate();
|
||||
}
|
||||
}
|
||||
|
||||
// cannot be static!
|
||||
updatePojo(pojo) {
|
||||
delete pojo.isOwned;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Attribute;
|
||||
@@ -59,6 +59,11 @@ class Branch extends Entity {
|
||||
this.dateModified = dateUtils.nowDate();
|
||||
}
|
||||
}
|
||||
|
||||
// cannot be static!
|
||||
updatePojo(pojo) {
|
||||
delete pojo.origParentNoteId;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Branch;
|
||||
@@ -4,6 +4,7 @@ const Entity = require('./entity');
|
||||
const Attribute = require('./attribute');
|
||||
const protectedSessionService = require('../services/protected_session');
|
||||
const repository = require('../services/repository');
|
||||
const sql = require('../services/sql');
|
||||
const dateUtils = require('../services/date_utils');
|
||||
|
||||
const LABEL = 'label';
|
||||
@@ -74,7 +75,9 @@ class Note extends Entity {
|
||||
/** @returns {boolean} true if this note is JavaScript (code or attachment) */
|
||||
isJavaScript() {
|
||||
return (this.type === "code" || this.type === "file")
|
||||
&& (this.mime.startsWith("application/javascript") || this.mime === "application/x-javascript");
|
||||
&& (this.mime.startsWith("application/javascript")
|
||||
|| this.mime === "application/x-javascript"
|
||||
|| this.mime === "text/javascript");
|
||||
}
|
||||
|
||||
/** @returns {boolean} true if this note is HTML */
|
||||
@@ -433,14 +436,32 @@ class Note extends Entity {
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds child notes with given attribute name and value. Only own attributes are considered, not inherited ones
|
||||
* @return {Promise<string[]>} return list of all descendant noteIds of this note. Returning just noteIds because number of notes can be huge. Includes also this note's noteId
|
||||
*/
|
||||
async getDescendantNoteIds() {
|
||||
return await sql.getColumn(`
|
||||
WITH RECURSIVE
|
||||
tree(noteId) AS (
|
||||
SELECT ?
|
||||
UNION
|
||||
SELECT branches.noteId FROM branches
|
||||
JOIN tree ON branches.parentNoteId = tree.noteId
|
||||
JOIN notes ON notes.noteId = branches.noteId
|
||||
WHERE notes.isDeleted = 0
|
||||
AND branches.isDeleted = 0
|
||||
)
|
||||
SELECT noteId FROM tree`, [this.noteId]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds descendant notes with given attribute name and value. Only own attributes are considered, not inherited ones
|
||||
*
|
||||
* @param {string} type - attribute type (label, relation, etc.)
|
||||
* @param {string} name - attribute name
|
||||
* @param {string} [value] - attribute value
|
||||
* @returns {Promise<Note[]>}
|
||||
*/
|
||||
async findChildNotesWithAttribute(type, name, value) {
|
||||
async getDescendantNotesWithAttribute(type, name, value) {
|
||||
const params = [this.noteId, name];
|
||||
let valueCondition = "";
|
||||
|
||||
@@ -472,22 +493,22 @@ class Note extends Entity {
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds notes with given label name and value. Only own labels are considered, not inherited ones
|
||||
* Finds descendant notes with given label name and value. Only own labels are considered, not inherited ones
|
||||
*
|
||||
* @param {string} name - label name
|
||||
* @param {string} [value] - label value
|
||||
* @returns {Promise<Note[]>}
|
||||
*/
|
||||
async findChildNotesWithLabel(name, value) { return await this.findChildNotesWithAttribute(LABEL, name, value); }
|
||||
async getDescendantNotesWithLabel(name, value) { return await this.getDescendantNotesWithAttribute(LABEL, name, value); }
|
||||
|
||||
/**
|
||||
* Finds notes with given relation name and value. Only own relations are considered, not inherited ones
|
||||
* Finds descendant notes with given relation name and value. Only own relations are considered, not inherited ones
|
||||
*
|
||||
* @param {string} name - relation name
|
||||
* @param {string} [value] - relation value
|
||||
* @returns {Promise<Note[]>}
|
||||
*/
|
||||
async findChildNotesWithRelation(name, value) { return await this.findChildNotesWithAttribute(RELATION, name, value); }
|
||||
async getDescendantNotesWithRelation(name, value) { return await this.getDescendantNotesWithAttribute(RELATION, name, value); }
|
||||
|
||||
/**
|
||||
* Returns note revisions of this note.
|
||||
@@ -587,10 +608,6 @@ class Note extends Entity {
|
||||
// we do this here because encryption needs the note ID for the IV
|
||||
this.generateIdIfNecessary();
|
||||
|
||||
if (this.isProtected) {
|
||||
protectedSessionService.encryptNote(this);
|
||||
}
|
||||
|
||||
if (!this.isDeleted) {
|
||||
this.isDeleted = false;
|
||||
}
|
||||
@@ -605,6 +622,17 @@ class Note extends Entity {
|
||||
this.dateModified = dateUtils.nowDate();
|
||||
}
|
||||
}
|
||||
|
||||
// cannot be static!
|
||||
updatePojo(pojo) {
|
||||
if (pojo.isProtected) {
|
||||
protectedSessionService.encryptNote(pojo);
|
||||
}
|
||||
|
||||
delete pojo.jsonContent;
|
||||
delete pojo.isContentAvailable;
|
||||
delete pojo.__attributeCache;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Note;
|
||||
BIN
src/public/images/app-icons/mac/icon.icns
Normal file
BIN
src/public/images/app-icons/mac/icon.icns
Normal file
Binary file not shown.
@@ -67,12 +67,13 @@ function AttributesModel() {
|
||||
attr.labelDefinition = (attr.type === 'label-definition' && attr.value) ? attr.value : {
|
||||
labelType: "text",
|
||||
multiplicityType: "singlevalue",
|
||||
isPromoted: true
|
||||
isPromoted: true,
|
||||
numberPrecision: 0
|
||||
};
|
||||
|
||||
attr.relationDefinition = (attr.type === 'relation-definition' && attr.value) ? attr.value : {
|
||||
multiplicityType: "singlevalue",
|
||||
mirrorRelation: "",
|
||||
inverseRelation: "",
|
||||
isPromoted: true
|
||||
};
|
||||
|
||||
@@ -114,7 +115,7 @@ function AttributesModel() {
|
||||
|
||||
function isValid() {
|
||||
for (let attributes = self.ownedAttributes(), i = 0; i < attributes.length; i++) {
|
||||
if (self.isEmptyName(i)) {
|
||||
if (self.isEmptyName(i) || self.isEmptyRelationTarget(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -187,11 +188,12 @@ function AttributesModel() {
|
||||
labelDefinition: {
|
||||
labelType: "text",
|
||||
multiplicityType: "singlevalue",
|
||||
isPromoted: true
|
||||
isPromoted: true,
|
||||
numberPrecision: 0
|
||||
},
|
||||
relationDefinition: {
|
||||
multiplicityType: "singlevalue",
|
||||
mirrorRelation: "",
|
||||
inverseRelation: "",
|
||||
isPromoted: true
|
||||
}
|
||||
}));
|
||||
@@ -209,7 +211,35 @@ function AttributesModel() {
|
||||
this.isEmptyName = function(index) {
|
||||
const cur = self.ownedAttributes()[index]();
|
||||
|
||||
return cur.name.trim() === "" && !cur.isDeleted && (cur.attributeId !== "" || cur.labelValue !== "" || cur.relationValue);
|
||||
if (cur.name.trim() || cur.isDeleted) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cur.attributeId) {
|
||||
// name is empty and attribute already exists so this is NO-GO
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cur.type === 'relation-definition' || cur.type === 'label-definition') {
|
||||
// for definitions there's no possible empty value so we always require name
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cur.type === 'label' && cur.labelValue) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cur.type === 'relation' && cur.relationValue) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
this.isEmptyRelationTarget = function(index) {
|
||||
const cur = self.ownedAttributes()[index]();
|
||||
|
||||
return cur.type === "relation" && !cur.isDeleted && cur.name && !cur.relationValue;
|
||||
};
|
||||
|
||||
this.getTargetAttribute = function(target) {
|
||||
|
||||
77
src/public/javascripts/dialogs/export.js
Normal file
77
src/public/javascripts/dialogs/export.js
Normal file
@@ -0,0 +1,77 @@
|
||||
import treeService from '../services/tree.js';
|
||||
import treeUtils from "../services/tree_utils.js";
|
||||
import exportService from "../services/export.js";
|
||||
|
||||
const $dialog = $("#export-dialog");
|
||||
const $form = $("#export-form");
|
||||
const $noteTitle = $dialog.find(".note-title");
|
||||
const $subtreeFormats = $("#export-subtree-formats");
|
||||
const $singleFormats = $("#export-single-formats");
|
||||
const $subtreeType = $("#export-type-subtree");
|
||||
const $singleType = $("#export-type-single");
|
||||
|
||||
async function showDialog(defaultType) {
|
||||
if (defaultType === 'subtree') {
|
||||
$subtreeType.prop("checked", true).change();
|
||||
}
|
||||
else if (defaultType === 'single') {
|
||||
$singleType.prop("checked", true).change();
|
||||
}
|
||||
else {
|
||||
throw new Error("Unrecognized type " + defaultType);
|
||||
}
|
||||
|
||||
glob.activeDialog = $dialog;
|
||||
|
||||
$dialog.modal();
|
||||
|
||||
const currentNode = treeService.getCurrentNode();
|
||||
const noteTitle = await treeUtils.getNoteTitle(currentNode.data.noteId);
|
||||
|
||||
$noteTitle.html(noteTitle);
|
||||
}
|
||||
|
||||
$form.submit(() => {
|
||||
const exportType = $dialog.find("input[name='export-type']:checked").val();
|
||||
|
||||
if (!exportType) {
|
||||
// this shouldn't happen as we always choose default export type
|
||||
alert("Choose export type first please");
|
||||
return;
|
||||
}
|
||||
|
||||
const exportFormat = exportType === 'subtree'
|
||||
? $("input[name=export-subtree-format]:checked").val()
|
||||
: $("input[name=export-single-format]:checked").val();
|
||||
|
||||
const currentNode = treeService.getCurrentNode();
|
||||
|
||||
exportService.exportBranch(currentNode.data.branchId, exportType, exportFormat);
|
||||
|
||||
$dialog.modal('hide');
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
$('input[name=export-type]').change(function () {
|
||||
if (this.value === 'subtree') {
|
||||
if ($("input[name=export-subtree-format]:checked").length === 0) {
|
||||
$("input[name=export-subtree-format]:first").prop("checked", true);
|
||||
}
|
||||
|
||||
$subtreeFormats.slideDown();
|
||||
$singleFormats.slideUp();
|
||||
}
|
||||
else {
|
||||
if ($("input[name=export-single-format]:checked").length === 0) {
|
||||
$("input[name=export-single-format]:first").prop("checked", true);
|
||||
}
|
||||
|
||||
$subtreeFormats.slideUp();
|
||||
$singleFormats.slideDown();
|
||||
}
|
||||
});
|
||||
|
||||
export default {
|
||||
showDialog
|
||||
};
|
||||
@@ -1,35 +0,0 @@
|
||||
import treeService from '../services/tree.js';
|
||||
import server from '../services/server.js';
|
||||
import treeUtils from "../services/tree_utils.js";
|
||||
import exportService from "../services/export.js";
|
||||
|
||||
const $dialog = $("#export-subtree-dialog");
|
||||
const $form = $("#export-subtree-form");
|
||||
const $noteTitle = $dialog.find(".note-title");
|
||||
|
||||
async function showDialog() {
|
||||
glob.activeDialog = $dialog;
|
||||
|
||||
$dialog.modal();
|
||||
|
||||
const currentNode = treeService.getCurrentNode();
|
||||
const noteTitle = await treeUtils.getNoteTitle(currentNode.data.noteId);
|
||||
|
||||
$noteTitle.html(noteTitle);
|
||||
}
|
||||
|
||||
$form.submit(() => {
|
||||
const exportFormat = $dialog.find("input[name='export-format']:checked").val();
|
||||
|
||||
const currentNode = treeService.getCurrentNode();
|
||||
|
||||
exportService.exportSubtree(currentNode.data.branchId, exportFormat);
|
||||
|
||||
$dialog.modal('hide');
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
export default {
|
||||
showDialog
|
||||
};
|
||||
@@ -1,6 +1,9 @@
|
||||
const $dialog = $("#prompt-dialog");
|
||||
const $question = $("#prompt-dialog-question");
|
||||
const $answer = $("#prompt-dialog-answer");
|
||||
const $dialogBody = $dialog.find(".modal-body");
|
||||
|
||||
let $question;
|
||||
let $answer;
|
||||
|
||||
const $form = $("#prompt-dialog-form");
|
||||
|
||||
let resolve;
|
||||
@@ -11,8 +14,21 @@ function ask({ message, defaultValue, shown }) {
|
||||
|
||||
shownCb = shown;
|
||||
|
||||
$question.text(message);
|
||||
$answer.val(defaultValue || "");
|
||||
$question = $("<label>")
|
||||
.prop("for", "prompt-dialog-answer")
|
||||
.text(message);
|
||||
|
||||
$answer = $("<input>")
|
||||
.prop("type", "text")
|
||||
.prop("id", "prompt-dialog-answer")
|
||||
.addClass("form-control")
|
||||
.val(defaultValue || "");
|
||||
|
||||
$dialogBody.empty().append(
|
||||
$("<div>")
|
||||
.addClass("form-group")
|
||||
.append($question)
|
||||
.append($answer));
|
||||
|
||||
$dialog.modal();
|
||||
|
||||
|
||||
@@ -50,7 +50,12 @@ async function execute(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
const sqlQuery = codeEditor.getValue();
|
||||
// execute the selected text or the whole content if there's no selection
|
||||
let sqlQuery = codeEditor.getSelection();
|
||||
|
||||
if (!sqlQuery) {
|
||||
sqlQuery = codeEditor.getValue();
|
||||
}
|
||||
|
||||
const result = await server.post("sql/execute", {
|
||||
query: sqlQuery
|
||||
|
||||
@@ -14,7 +14,7 @@ class Branch {
|
||||
/** @param {string} */
|
||||
this.prefix = row.prefix;
|
||||
/** @param {boolean} */
|
||||
this.isExpanded = row.isExpanded;
|
||||
this.isExpanded = !!row.isExpanded;
|
||||
}
|
||||
|
||||
/** @returns {NoteShort} */
|
||||
|
||||
@@ -10,11 +10,13 @@ function initAttributeNameAutocomplete({ $el, attributeType, open }) {
|
||||
$el.autocomplete({
|
||||
appendTo: document.querySelector('body'),
|
||||
hint: false,
|
||||
autoselect: true,
|
||||
openOnFocus: true,
|
||||
minLength: 0
|
||||
minLength: 0,
|
||||
tabAutocomplete: false
|
||||
}, [{
|
||||
displayKey: 'name',
|
||||
// disabling cache is important here because otherwise cache can stay intact when switching between attribute type which will lead to autocomplete displaying attribute names for incorrect attribute type
|
||||
cache: false,
|
||||
source: async (term, cb) => {
|
||||
const type = typeof attributeType === "function" ? attributeType() : attributeType;
|
||||
|
||||
@@ -23,10 +25,6 @@ function initAttributeNameAutocomplete({ $el, attributeType, open }) {
|
||||
return {name};
|
||||
});
|
||||
|
||||
if (result.length === 0) {
|
||||
result.push({name: "No results"});
|
||||
}
|
||||
|
||||
cb(result);
|
||||
}
|
||||
}]);
|
||||
@@ -55,9 +53,9 @@ async function initLabelValueAutocomplete({ $el, open }) {
|
||||
$el.autocomplete({
|
||||
appendTo: document.querySelector('body'),
|
||||
hint: false,
|
||||
autoselect: true,
|
||||
openOnFocus: true,
|
||||
minLength: 0
|
||||
minLength: 0,
|
||||
tabAutocomplete: false
|
||||
}, [{
|
||||
displayKey: 'value',
|
||||
source: function (term, cb) {
|
||||
|
||||
@@ -3,14 +3,13 @@ import utils from "./utils.js";
|
||||
import messagingService from "./messaging.js";
|
||||
import treeUtils from "./tree_utils.js";
|
||||
import noteAutocompleteService from "./note_autocomplete.js";
|
||||
import treeService from "./tree.js";
|
||||
import linkService from "./link.js";
|
||||
import infoService from "./info.js";
|
||||
import noteDetailService from "./note_detail.js";
|
||||
|
||||
const $attributeList = $("#attribute-list");
|
||||
const $attributeListInner = $("#attribute-list-inner");
|
||||
const $promotedAttributesContainer = $("#note-detail-promoted-attributes");
|
||||
const $savedIndicator = $("#saved-indicator");
|
||||
|
||||
let attributePromise;
|
||||
|
||||
@@ -146,7 +145,8 @@ async function createPromotedAttributeRow(definitionAttr, valueAttr) {
|
||||
hint: false,
|
||||
autoselect: true,
|
||||
openOnFocus: true,
|
||||
minLength: 0
|
||||
minLength: 0,
|
||||
tabAutocomplete: false
|
||||
}, [{
|
||||
displayKey: 'value',
|
||||
source: function (term, cb) {
|
||||
@@ -161,6 +161,14 @@ async function createPromotedAttributeRow(definitionAttr, valueAttr) {
|
||||
}
|
||||
else if (definition.labelType === 'number') {
|
||||
$input.prop("type", "number");
|
||||
|
||||
let step = 1;
|
||||
|
||||
for (let i = 0; i < (definition.numberPrecision || 0) && i < 10; i++) {
|
||||
step /= 10;
|
||||
}
|
||||
|
||||
$input.prop("step", step);
|
||||
}
|
||||
else if (definition.labelType === 'boolean') {
|
||||
$input.prop("type", "checkbox");
|
||||
@@ -267,7 +275,12 @@ async function promotedAttributeChanged(event) {
|
||||
|
||||
$attr.prop("attribute-id", result.attributeId);
|
||||
|
||||
infoService.showMessage("Attribute has been saved.");
|
||||
// animate only if it's not being animated already, this is important especially for e.g. number inputs
|
||||
// which can be changed many times in a second by clicking on higher/lower buttons.
|
||||
if ($savedIndicator.queue().length === 0) {
|
||||
$savedIndicator.fadeOut();
|
||||
$savedIndicator.fadeIn();
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
|
||||
9
src/public/javascripts/services/bootstrap.js
vendored
9
src/public/javascripts/services/bootstrap.js
vendored
@@ -7,6 +7,7 @@ import recentChangesDialog from '../dialogs/recent_changes.js';
|
||||
import optionsDialog from '../dialogs/options.js';
|
||||
import sqlConsoleDialog from '../dialogs/sql_console.js';
|
||||
import markdownImportDialog from '../dialogs/markdown_import.js';
|
||||
import exportDialog from '../dialogs/export.js';
|
||||
|
||||
import cloning from './cloning.js';
|
||||
import contextMenu from './tree_context_menu.js';
|
||||
@@ -103,7 +104,13 @@ if (utils.isElectron()) {
|
||||
});
|
||||
}
|
||||
|
||||
$("#export-note-to-markdown-button").click(() => exportService.exportSubtree(noteDetailService.getCurrentNoteId(), 'markdown-single'));
|
||||
$("#export-note-button").click(function () {
|
||||
if ($(this).hasClass("disabled")) {
|
||||
return;
|
||||
}
|
||||
|
||||
exportDialog.showDialog('single');
|
||||
});
|
||||
|
||||
treeService.showTree();
|
||||
|
||||
|
||||
@@ -10,15 +10,13 @@ const dragAndDropSetup = {
|
||||
|
||||
node.setSelected(true);
|
||||
|
||||
const selectedNodes = treeService.getSelectedNodes().map(node => {
|
||||
return {
|
||||
noteId: node.data.noteId,
|
||||
title: node.title
|
||||
}
|
||||
});
|
||||
|
||||
// this is for dragging notes into relation map
|
||||
data.dataTransfer.setData("text", JSON.stringify(selectedNodes));
|
||||
// we allow to drag only one note at a time because it multi-drag conflicts with multiple single drags
|
||||
// in UX and single drag is probably more useful
|
||||
data.dataTransfer.setData("text", JSON.stringify({
|
||||
noteId: node.data.noteId,
|
||||
title: node.title
|
||||
}));
|
||||
|
||||
// This function MUST be defined to enable dragging for the tree.
|
||||
// Return false to cancel dragging of node.
|
||||
|
||||
@@ -25,14 +25,26 @@ function registerEntrypoints() {
|
||||
$("#jump-to-note-dialog-button").click(jumpToNoteDialog.showDialog);
|
||||
utils.bindShortcut('ctrl+j', jumpToNoteDialog.showDialog);
|
||||
|
||||
$("#show-note-revisions-button").click(noteRevisionsDialog.showCurrentNoteRevisions);
|
||||
$("#show-note-revisions-button").click(function() {
|
||||
if ($(this).hasClass("disabled")) {
|
||||
return;
|
||||
}
|
||||
|
||||
$("#show-source-button").click(noteSourceDialog.showDialog);
|
||||
noteRevisionsDialog.showCurrentNoteRevisions();
|
||||
});
|
||||
|
||||
$("#show-source-button").click(function() {
|
||||
if ($(this).hasClass("disabled")) {
|
||||
return;
|
||||
}
|
||||
|
||||
noteSourceDialog.showDialog();
|
||||
});
|
||||
|
||||
$("#recent-changes-button").click(recentChangesDialog.showDialog);
|
||||
|
||||
$("#protected-session-on").click(protectedSessionService.enterProtectedSession);
|
||||
$("#protected-session-off").click(protectedSessionService.leaveProtectedSession);
|
||||
$("#enter-protected-session-button").click(protectedSessionService.enterProtectedSession);
|
||||
$("#leave-protected-session-button").click(protectedSessionService.leaveProtectedSession);
|
||||
|
||||
$("#toggle-search-button").click(searchNotesService.toggleSearch);
|
||||
utils.bindShortcut('ctrl+s', searchNotesService.toggleSearch);
|
||||
@@ -85,10 +97,17 @@ function registerEntrypoints() {
|
||||
|
||||
$(document).bind('keydown', 'ctrl+f', () => {
|
||||
if (utils.isElectron()) {
|
||||
const searchInPage = require('electron-in-page-search').default;
|
||||
const remote = require('electron').remote;
|
||||
const $searchWindowWebview = $(".electron-in-page-search-window");
|
||||
$searchWindowWebview.show();
|
||||
|
||||
const inPageSearch = searchInPage(remote.getCurrentWebContents());
|
||||
const searchInPage = require('electron-in-page-search').default;
|
||||
const {remote} = require('electron');
|
||||
|
||||
const inPageSearch = searchInPage(remote.getCurrentWebContents(), {
|
||||
searchWindowWebview: $searchWindowWebview[0],
|
||||
//openDevToolsOfSearchWindow: true,
|
||||
customCssPath: '/libraries/electron-in-page-search/default-style.css'
|
||||
});
|
||||
|
||||
inPageSearch.openSearchWindow();
|
||||
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
import treeService from './tree.js';
|
||||
import infoService from './info.js';
|
||||
import protectedSessionHolder from './protected_session_holder.js';
|
||||
import utils from './utils.js';
|
||||
import server from './server.js';
|
||||
|
||||
function exportSubtree(noteId, format) {
|
||||
const url = utils.getHost() + "/api/notes/" + noteId + "/export/" + format +
|
||||
"?protectedSessionId=" + encodeURIComponent(protectedSessionHolder.getProtectedSessionId());
|
||||
function exportBranch(branchId, type, format) {
|
||||
const url = utils.getHost() + `/api/notes/${branchId}/export/${type}/${format}?protectedSessionId=` + encodeURIComponent(protectedSessionHolder.getProtectedSessionId());
|
||||
|
||||
console.log(url);
|
||||
|
||||
utils.download(url);
|
||||
|
||||
infoService.showMessage("Export to file has been finished.");
|
||||
}
|
||||
|
||||
let importNoteId;
|
||||
@@ -47,6 +45,6 @@ $("#import-upload").change(async function() {
|
||||
});
|
||||
|
||||
export default {
|
||||
exportSubtree,
|
||||
exportBranch,
|
||||
importIntoNote
|
||||
};
|
||||
@@ -5,13 +5,9 @@ function showMessage(message) {
|
||||
console.debug(utils.now(), "message: ", message);
|
||||
|
||||
$.notify({
|
||||
// options
|
||||
icon: 'jam jam-check',
|
||||
message: message
|
||||
}, {
|
||||
// options
|
||||
type: 'success',
|
||||
delay: 3000
|
||||
});
|
||||
}, getNotifySettings('success', 3000));
|
||||
}
|
||||
|
||||
function showAndLogError(message, delay = 10000) {
|
||||
@@ -25,12 +21,26 @@ function showError(message, delay = 10000) {
|
||||
|
||||
$.notify({
|
||||
// options
|
||||
icon: 'jam jam-alert',
|
||||
message: message
|
||||
}, {
|
||||
// options
|
||||
type: 'danger',
|
||||
}, getNotifySettings('danger', delay));
|
||||
}
|
||||
|
||||
function getNotifySettings(type, delay) {
|
||||
return {
|
||||
element: 'body',
|
||||
type: type,
|
||||
z_index: 90000,
|
||||
placement: {
|
||||
from: "top",
|
||||
align: "center"
|
||||
},
|
||||
animate: {
|
||||
enter: 'animated fadeInDown',
|
||||
exit: 'animated fadeOutUp'
|
||||
},
|
||||
delay: delay
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function throwError(message) {
|
||||
|
||||
@@ -76,7 +76,8 @@ function initNoteAutocomplete($el, options) {
|
||||
hint: false,
|
||||
autoselect: true,
|
||||
openOnFocus: true,
|
||||
minLength: 0
|
||||
minLength: 0,
|
||||
tabAutocomplete: false
|
||||
}, [
|
||||
{
|
||||
source: autocompleteSource,
|
||||
@@ -92,7 +93,7 @@ function initNoteAutocomplete($el, options) {
|
||||
$el.on('autocomplete:selected', (event, suggestion) => $el.setSelectedPath(suggestion.path));
|
||||
$el.on('autocomplete:closed', () => {
|
||||
if (!$el.val().trim()) {
|
||||
$el.setSelectedPath("");
|
||||
clearText($el);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ const $noteDetailWrapper = $("#note-detail-wrapper");
|
||||
const $noteIdDisplay = $("#note-id-display");
|
||||
const $childrenOverview = $("#children-overview");
|
||||
const $scriptArea = $("#note-detail-script-area");
|
||||
const $savedIndicator = $("#saved-indicator");
|
||||
|
||||
let currentNote = null;
|
||||
|
||||
@@ -78,6 +79,8 @@ function noteChanged() {
|
||||
}
|
||||
|
||||
isNoteChanged = true;
|
||||
|
||||
$savedIndicator.fadeOut();
|
||||
}
|
||||
|
||||
async function reload() {
|
||||
@@ -120,15 +123,16 @@ async function saveNote() {
|
||||
protectedSessionHolder.touchProtectedSession();
|
||||
}
|
||||
|
||||
infoService.showMessage("Saved!");
|
||||
$savedIndicator.fadeIn();
|
||||
}
|
||||
|
||||
async function saveNoteIfChanged() {
|
||||
if (!isNoteChanged) {
|
||||
return;
|
||||
if (isNoteChanged) {
|
||||
await saveNote();
|
||||
}
|
||||
|
||||
await saveNote();
|
||||
// make sure indicator is visible in a case there was some race condition.
|
||||
$savedIndicator.fadeIn();
|
||||
}
|
||||
|
||||
function setNoteBackgroundIfProtected(note) {
|
||||
@@ -294,7 +298,7 @@ $(document).ready(() => {
|
||||
// this sends the request asynchronously and doesn't wait for result
|
||||
$(window).on('beforeunload', () => { saveNoteIfChanged(); }); // don't convert to short form, handler doesn't like returned promise
|
||||
|
||||
setInterval(saveNoteIfChanged, 5000);
|
||||
setInterval(saveNoteIfChanged, 3000);
|
||||
|
||||
export default {
|
||||
reload,
|
||||
|
||||
@@ -32,7 +32,10 @@ async function show() {
|
||||
lint: true,
|
||||
gutters: ["CodeMirror-lint-markers"],
|
||||
lineNumbers: true,
|
||||
tabindex: 100
|
||||
tabindex: 100,
|
||||
// we linewrap partly also because without it horizontal scrollbar displays only when you scroll
|
||||
// all the way to the bottom of the note. With line wrap there's no horizontal scrollbar so no problem
|
||||
lineWrapping: true
|
||||
});
|
||||
|
||||
onNoteChange(noteDetailService.noteChanged);
|
||||
@@ -43,7 +46,9 @@ async function show() {
|
||||
const currentNote = noteDetailService.getCurrentNote();
|
||||
|
||||
// this needs to happen after the element is shown, otherwise the editor won't be refreshed
|
||||
codeEditor.setValue(currentNote.content);
|
||||
// CodeMirror breaks pretty badly on null so even though it shouldn't happen (guarded by consistency check)
|
||||
// we provide fallback
|
||||
codeEditor.setValue(currentNote.content || "");
|
||||
|
||||
const info = CodeMirror.findModeByMIME(currentNote.mime);
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import infoService from "./info.js";
|
||||
import server from "./server.js";
|
||||
|
||||
const $component = $('#note-detail-image');
|
||||
const $imageWrapper = $('#note-detail-image-wrapper');
|
||||
const $imageView = $('#note-detail-image-view');
|
||||
|
||||
const $imageDownloadButton = $("#image-download");
|
||||
@@ -39,10 +40,10 @@ function selectImage(element) {
|
||||
}
|
||||
|
||||
$copyToClipboardButton.click(() => {
|
||||
$component.attr('contenteditable','true');
|
||||
$imageWrapper.attr('contenteditable','true');
|
||||
|
||||
try {
|
||||
selectImage($component.get(0));
|
||||
selectImage($imageWrapper.get(0));
|
||||
|
||||
const success = document.execCommand('copy');
|
||||
|
||||
@@ -55,7 +56,7 @@ $copyToClipboardButton.click(() => {
|
||||
}
|
||||
finally {
|
||||
window.getSelection().removeAllRanges();
|
||||
$component.removeAttr('contenteditable');
|
||||
$imageWrapper.removeAttr('contenteditable');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ const $relationMapContainer = $("#relation-map-container");
|
||||
const $createChildNote = $("#relation-map-create-child-note");
|
||||
const $zoomInButton = $("#relation-map-zoom-in");
|
||||
const $zoomOutButton = $("#relation-map-zoom-out");
|
||||
const $centerButton = $("#relation-map-center");
|
||||
const $resetPanZoomButton = $("#relation-map-reset-pan-zoom");
|
||||
|
||||
let mapData;
|
||||
let jsPlumbInstance;
|
||||
@@ -50,7 +50,7 @@ const biDirectionalOverlays = [
|
||||
} ]
|
||||
];
|
||||
|
||||
const mirrorOverlays = [
|
||||
const inverseRelationsOverlays = [
|
||||
[ "Arrow", {
|
||||
location: 1,
|
||||
id: "arrow",
|
||||
@@ -117,6 +117,15 @@ async function show() {
|
||||
|
||||
}
|
||||
|
||||
function clearMap() {
|
||||
// delete all endpoints and connections
|
||||
// this is done at this point (after async operations) to reduce flicker to the minimum
|
||||
jsPlumbInstance.deleteEveryEndpoint();
|
||||
|
||||
// without this we still end up with note boxes remaining in the canvas
|
||||
$relationMapContainer.empty();
|
||||
}
|
||||
|
||||
async function loadNotesAndRelations() {
|
||||
const noteIds = mapData.notes.map(note => note.noteId);
|
||||
const data = await server.post("notes/relation-map", {noteIds});
|
||||
@@ -125,12 +134,12 @@ async function loadNotesAndRelations() {
|
||||
|
||||
for (const relation of data.relations) {
|
||||
const match = relations.find(rel =>
|
||||
rel.name === data.mirrorRelations[relation.name]
|
||||
rel.name === data.inverseRelations[relation.name]
|
||||
&& ((rel.sourceNoteId === relation.sourceNoteId && rel.targetNoteId === relation.targetNoteId)
|
||||
|| (rel.sourceNoteId === relation.targetNoteId && rel.targetNoteId === relation.sourceNoteId)));
|
||||
|
||||
if (match) {
|
||||
match.type = relation.type = relation.name === data.mirrorRelations[relation.name] ? 'biDirectional' : 'mirror';
|
||||
match.type = relation.type = relation.name === data.inverseRelations[relation.name] ? 'biDirectional' : 'inverse';
|
||||
relation.render = false; // don't render second relation
|
||||
} else {
|
||||
relation.type = 'uniDirectional';
|
||||
@@ -142,11 +151,9 @@ async function loadNotesAndRelations() {
|
||||
|
||||
mapData.notes = mapData.notes.filter(note => note.noteId in data.noteTitles);
|
||||
|
||||
// delete all endpoints and connections
|
||||
// this is done at this point (after async operations) to reduce flicker to the minimum
|
||||
jsPlumbInstance.deleteEveryEndpoint();
|
||||
|
||||
jsPlumbInstance.batch(async function () {
|
||||
clearMap();
|
||||
|
||||
for (const note of mapData.notes) {
|
||||
const title = data.noteTitles[note.noteId];
|
||||
|
||||
@@ -166,9 +173,9 @@ async function loadNotesAndRelations() {
|
||||
|
||||
connection.id = relation.attributeId;
|
||||
|
||||
if (relation.type === 'mirror') {
|
||||
if (relation.type === 'inverse') {
|
||||
connection.getOverlay("label-source").setLabel(relation.name);
|
||||
connection.getOverlay("label-target").setLabel(data.mirrorRelations[relation.name]);
|
||||
connection.getOverlay("label-target").setLabel(data.inverseRelations[relation.name]);
|
||||
}
|
||||
else {
|
||||
connection.getOverlay("label").setLabel(relation.name);
|
||||
@@ -208,10 +215,17 @@ function initPanZoom() {
|
||||
|
||||
mapData.notes.push({ noteId: clipboard.noteId, x, y });
|
||||
|
||||
saveData();
|
||||
|
||||
clipboard = null;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
filterKey: function(e, dx, dy, dz) {
|
||||
// if ALT is pressed then panzoom should bubble the event up
|
||||
// this is to preserve ALT-LEFT, ALT-RIGHT navigation working
|
||||
return e.altKey;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -226,6 +240,10 @@ function initPanZoom() {
|
||||
|
||||
pzInstance.moveTo(mapData.transform.x, mapData.transform.y);
|
||||
}
|
||||
else {
|
||||
// set to initial coordinates
|
||||
pzInstance.moveTo(0, 0);
|
||||
}
|
||||
|
||||
$zoomInButton.click(() => pzInstance.zoomTo(0, 0, 1.2));
|
||||
$zoomOutButton.click(() => pzInstance.zoomTo(0, 0, 0.8));
|
||||
@@ -244,11 +262,7 @@ function saveCurrentTransform() {
|
||||
|
||||
function cleanup() {
|
||||
if (jsPlumbInstance) {
|
||||
// delete all endpoints and connections
|
||||
jsPlumbInstance.deleteEveryEndpoint();
|
||||
|
||||
// without this we still end up with note boxes remaining in the canvas
|
||||
$relationMapContainer.empty();
|
||||
clearMap();
|
||||
}
|
||||
|
||||
if (pzInstance) {
|
||||
@@ -276,7 +290,7 @@ function initJsPlumbInstance () {
|
||||
|
||||
jsPlumbInstance.registerConnectionType("biDirectional", { anchor:"Continuous", connector:"StateMachine", overlays: biDirectionalOverlays });
|
||||
|
||||
jsPlumbInstance.registerConnectionType("mirror", { anchor:"Continuous", connector:"StateMachine", overlays: mirrorOverlays });
|
||||
jsPlumbInstance.registerConnectionType("inverse", { anchor:"Continuous", connector:"StateMachine", overlays: inverseRelationsOverlays });
|
||||
|
||||
jsPlumbInstance.registerConnectionType("link", { anchor:"Continuous", connector:"StateMachine", overlays: linkOverlays });
|
||||
|
||||
@@ -312,8 +326,6 @@ function connectionContextMenuHandler(connection, event) {
|
||||
async function connectionCreatedHandler(info, originalEvent) {
|
||||
const connection = info.connection;
|
||||
|
||||
const isRelation = relations.some(rel => rel.attributeId === connection.id);
|
||||
|
||||
connection.bind("contextmenu", (obj, event) => {
|
||||
if (connection.getType().includes("link")) {
|
||||
// don't create context menu if it's a link since there's nothing to do with link from relation map
|
||||
@@ -362,9 +374,7 @@ async function connectionCreatedHandler(info, originalEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
const attribute = await server.put(`notes/${sourceNoteId}/relations/${name}/to/${targetNoteId}`);
|
||||
|
||||
relations.push({ attributeId: attribute.attributeId , targetNoteId, sourceNoteId, name });
|
||||
await server.put(`notes/${sourceNoteId}/relations/${name}/to/${targetNoteId}`);
|
||||
|
||||
await refresh();
|
||||
}
|
||||
@@ -512,43 +522,20 @@ function getZoom() {
|
||||
async function dropNoteOntoRelationMapHandler(ev) {
|
||||
ev.preventDefault();
|
||||
|
||||
const notes = JSON.parse(ev.originalEvent.dataTransfer.getData("text"));
|
||||
const note = JSON.parse(ev.originalEvent.dataTransfer.getData("text"));
|
||||
|
||||
let {x, y} = getMousePosition(ev);
|
||||
|
||||
// modifying position so that cursor is on the top-center of the box
|
||||
const startX = x -= 80;
|
||||
y -= 15;
|
||||
const exists = mapData.notes.some(n => n.noteId === note.noteId);
|
||||
|
||||
const currentNoteId = treeService.getCurrentNode().data.noteId;
|
||||
if (exists) {
|
||||
await infoDialog.info(`Note "${note.title}" is already placed into the diagram`);
|
||||
|
||||
for (const note of notes) {
|
||||
if (note.noteId === currentNoteId) {
|
||||
// we don't allow placing current (relation map) into itself
|
||||
// the reason is that when dragging notes from the tree, the relation map is always selected
|
||||
// since it's focused.
|
||||
continue;
|
||||
}
|
||||
|
||||
const exists = mapData.notes.some(n => n.noteId === note.noteId);
|
||||
|
||||
if (exists) {
|
||||
await infoDialog.info(`Note "${note.title}" is already placed into the diagram`);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
mapData.notes.push({noteId: note.noteId, x, y});
|
||||
|
||||
if (x - startX > 1000) {
|
||||
x = startX;
|
||||
y += 200;
|
||||
}
|
||||
else {
|
||||
x += 200;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
mapData.notes.push({noteId: note.noteId, x, y});
|
||||
|
||||
saveData();
|
||||
|
||||
await refresh();
|
||||
@@ -565,40 +552,10 @@ function getMousePosition(evt) {
|
||||
};
|
||||
}
|
||||
|
||||
$centerButton.click(() => {
|
||||
if (mapData.notes.length === 0) {
|
||||
return; // nothing to recenter on
|
||||
}
|
||||
|
||||
let totalX = 0, totalY = 0;
|
||||
|
||||
for (const note of mapData.notes) {
|
||||
totalX += note.x;
|
||||
totalY += note.y;
|
||||
}
|
||||
|
||||
let averageX = totalX / mapData.notes.length;
|
||||
let averageY = totalY / mapData.notes.length;
|
||||
|
||||
// find note with smallest X, Y difference from the average (most central note)
|
||||
const {noteId} = mapData.notes.map(note => {
|
||||
return {
|
||||
noteId: note.noteId,
|
||||
diff: Math.abs(note.x - averageX) + Math.abs(note.y - averageY)
|
||||
}
|
||||
}).reduce((min, val) => min.diff <= val.min ? min : val, { diff: 9999999999 });
|
||||
|
||||
const $noteBox = $("#" + noteIdToId(noteId));
|
||||
|
||||
const clientRect = $noteBox[0].getBoundingClientRect();
|
||||
const cx = clientRect.left + clientRect.width / 2;
|
||||
const cy = clientRect.top + clientRect.height / 2;
|
||||
|
||||
const container = $component[0].getBoundingClientRect();
|
||||
const dx = container.width / 2 - cx;
|
||||
const dy = container.height / 2 - cy;
|
||||
|
||||
pzInstance.moveBy(dx, dy, true);
|
||||
$resetPanZoomButton.click(() => {
|
||||
// reset to initial pan & zoom state
|
||||
pzInstance.zoomTo(0, 0, 1 / getZoom());
|
||||
pzInstance.moveTo(0, 0);
|
||||
});
|
||||
|
||||
$component.on("drop", dropNoteOntoRelationMapHandler);
|
||||
|
||||
@@ -11,8 +11,8 @@ const $password = $("#protected-session-password");
|
||||
const $noteDetailWrapper = $("#note-detail-wrapper");
|
||||
const $protectButton = $("#protect-button");
|
||||
const $unprotectButton = $("#unprotect-button");
|
||||
const $protectedSessionOnButton = $("#protected-session-on");
|
||||
const $protectedSessionOffButton = $("#protected-session-off");
|
||||
const $enterProtectedSessionButton = $("#enter-protected-session-button");
|
||||
const $leaveProtectedSessionButton = $("#leave-protected-session-button");
|
||||
|
||||
let protectedSessionDeferred = null;
|
||||
|
||||
@@ -57,7 +57,7 @@ async function setupProtectedSession() {
|
||||
const response = await enterProtectedSessionOnServer(password);
|
||||
|
||||
if (!response.success) {
|
||||
infoService.showError("Wrong password.");
|
||||
infoService.showError("Wrong password.", 3000);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -65,9 +65,11 @@ async function setupProtectedSession() {
|
||||
|
||||
$dialog.modal("hide");
|
||||
|
||||
await noteDetailService.reload();
|
||||
await treeService.reload();
|
||||
|
||||
treeService.reload();
|
||||
// it's important that tree has been already reloaded at this point
|
||||
// since detail also uses tree cache (for children overview)
|
||||
await noteDetailService.reload();
|
||||
|
||||
if (protectedSessionDeferred !== null) {
|
||||
ensureDialogIsClosed($dialog, $password);
|
||||
@@ -77,8 +79,8 @@ async function setupProtectedSession() {
|
||||
protectedSessionDeferred.resolve(true);
|
||||
protectedSessionDeferred = null;
|
||||
|
||||
$protectedSessionOnButton.addClass('active');
|
||||
$protectedSessionOffButton.removeClass('active');
|
||||
$enterProtectedSessionButton.hide();
|
||||
$leaveProtectedSessionButton.show();
|
||||
}
|
||||
|
||||
infoService.showMessage("Protected session has been started.");
|
||||
|
||||
@@ -12,9 +12,10 @@ function getHeaders() {
|
||||
|
||||
// headers need to be lowercase because node.js automatically converts them to lower case
|
||||
// so hypothetical protectedSessionId becomes protectedsessionid on the backend
|
||||
// also avoiding using underscores instead of dashes since nginx filters them out by default
|
||||
return {
|
||||
protected_session_id: protectedSessionId,
|
||||
source_id: glob.sourceId
|
||||
'trilium-protected-session-id': protectedSessionId,
|
||||
'trilium-source-id': glob.sourceId
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,10 @@ function setupTooltip() {
|
||||
if ($(this).is(":hover")) {
|
||||
$(this).tooltip({
|
||||
delay: {"show": 300, "hide": 100},
|
||||
container: 'body',
|
||||
placement: 'auto',
|
||||
trigger: 'manual',
|
||||
boundary: 'window',
|
||||
title: html,
|
||||
html: true
|
||||
});
|
||||
@@ -50,7 +54,7 @@ function setupTooltip() {
|
||||
});
|
||||
|
||||
$(document).on("mouseleave", "a", function() {
|
||||
$(this).tooltip('hide');
|
||||
$(this).tooltip('dispose');
|
||||
});
|
||||
|
||||
// close any tooltip after click, this fixes the problem that sometimes tooltips remained on the screen
|
||||
|
||||
@@ -500,6 +500,12 @@ async function createNote(node, parentNoteId, target, isProtected, saveSelection
|
||||
if (noteDetailService.getCurrentNoteType() !== 'text') {
|
||||
saveSelection = false;
|
||||
}
|
||||
else {
|
||||
// just disable this feature altogether - there's a problem that note containing image or table at the beginning
|
||||
// of the content will be auto-selected by CKEditor and then CTRL-P with no user interaction will automatically save
|
||||
// the selection - see https://github.com/ckeditor/ckeditor5/issues/1384
|
||||
saveSelection = false;
|
||||
}
|
||||
|
||||
let title, content;
|
||||
|
||||
@@ -564,8 +570,6 @@ async function createNote(node, parentNoteId, target, isProtected, saveSelection
|
||||
|
||||
clearSelectedNodes(); // to unmark previously active node
|
||||
|
||||
infoService.showMessage("Created!");
|
||||
|
||||
return {note, branch};
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import protectedSessionService from './protected_session.js';
|
||||
import treeChangesService from './branches.js';
|
||||
import treeUtils from './tree_utils.js';
|
||||
import branchPrefixDialog from '../dialogs/branch_prefix.js';
|
||||
import exportSubtreeDialog from '../dialogs/export_subtree.js';
|
||||
import exportDialog from '../dialogs/export.js';
|
||||
import infoService from "./info.js";
|
||||
import treeCache from "./tree_cache.js";
|
||||
import syncService from "./sync.js";
|
||||
@@ -93,7 +93,7 @@ const contextMenuItems = [
|
||||
{title: "Paste into <kbd>Ctrl+V</kbd>", cmd: "pasteInto", uiIcon: "clipboard"},
|
||||
{title: "Paste after", cmd: "pasteAfter", uiIcon: "clipboard"},
|
||||
{title: "----"},
|
||||
{title: "Export subtree", cmd: "exportSubtree", uiIcon: "arrow-up-right"},
|
||||
{title: "Export", cmd: "export", uiIcon: "arrow-up-right"},
|
||||
{title: "Import into note (tar, opml, md, enex)", cmd: "importIntoNote", uiIcon: "arrow-down-left"},
|
||||
{title: "----"},
|
||||
{title: "Collapse subtree <kbd>Alt+-</kbd>", cmd: "collapseSubtree", uiIcon: "align-justify"},
|
||||
@@ -127,7 +127,7 @@ async function getContextMenuItems(event) {
|
||||
enableItem("pasteAfter", clipboardIds.length > 0 && isNotRoot && parentNote.type !== 'search');
|
||||
enableItem("pasteInto", clipboardIds.length > 0 && note.type !== 'search');
|
||||
enableItem("importIntoNote", note.type !== 'search');
|
||||
enableItem("exportSubtree", note.type !== 'search');
|
||||
enableItem("export", note.type !== 'search');
|
||||
enableItem("editBranchPrefix", isNotRoot && parentNote.type !== 'search');
|
||||
|
||||
// Activate node on right-click
|
||||
@@ -179,8 +179,8 @@ function selectContextMenuItem(event, cmd) {
|
||||
else if (cmd === "delete") {
|
||||
treeChangesService.deleteNodes(treeService.getSelectedNodes(true));
|
||||
}
|
||||
else if (cmd === "exportSubtree") {
|
||||
exportSubtreeDialog.showDialog();
|
||||
else if (cmd === "export") {
|
||||
exportDialog.showDialog("subtree");
|
||||
}
|
||||
else if (cmd === "importIntoNote") {
|
||||
exportService.importIntoNote(node.data.noteId);
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
html, body {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", "Helvetica", "Meiryo", sans-serif;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.inpage-search-body {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin: 8px;
|
||||
padding: 10px;
|
||||
border: solid #aaaaaa 1px;
|
||||
border-radius: 10px;
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
.inpage-search-input {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.inpage-search-matches {
|
||||
color: #999;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
.inpage-search-back {
|
||||
margin-left: 2px;
|
||||
padding-left: 6px;
|
||||
padding-right: 2px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.inpage-search-forward {
|
||||
padding-left: 2px;
|
||||
padding-right: 6px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.inpage-search-close {
|
||||
margin-left: 4px;
|
||||
padding: 0 2px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.inpage-search-back:hover,
|
||||
.inpage-search-forward:hover,
|
||||
.inpage-search-close:hover {
|
||||
background-color: #e2e0e2;
|
||||
border-radius: 0.2em;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes" />
|
||||
<link href="/libraries/bootstrap/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="inpage-search-body">
|
||||
<input class="inpage-search-input form-control form-control-sm" type="search" placeholder="Search..." autocomplete="off" autofocus/>
|
||||
|
||||
<div class="inpage-search-matches">0/0</div>
|
||||
|
||||
<div class="inpage-search-back" title="Previous result"><</div>
|
||||
|
||||
<div class="inpage-search-forward" title="Next result">></div>
|
||||
|
||||
<div class="inpage-search-close" title="Close search">✕</div>
|
||||
</div>
|
||||
</body>
|
||||
<script>var exports = {}</script>
|
||||
</html>
|
||||
@@ -5,9 +5,7 @@
|
||||
|
||||
#relation-map-wrapper {
|
||||
position: relative;
|
||||
overflow: hidden !important;
|
||||
height: 4000px; /* we need to set fixed dimentions. This number is probably enough to cover any screen */
|
||||
width: 4000px;
|
||||
height: 100%;
|
||||
outline: none; /* remove dotted outline on click */
|
||||
}
|
||||
|
||||
|
||||
@@ -76,9 +76,13 @@ body {
|
||||
position: relative;
|
||||
overflow: auto;
|
||||
flex-basis: content;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.note-detail-component {
|
||||
flex-grow: 100;
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -210,12 +214,12 @@ div.ui-tooltip {
|
||||
*/
|
||||
.electron-in-page-search-window {
|
||||
position: fixed;
|
||||
top: 50px;
|
||||
right: 0;
|
||||
border: solid grey 1px;
|
||||
background-color: white;
|
||||
width: 300px;
|
||||
height: 36px;
|
||||
top: 45px;
|
||||
right: 10px;
|
||||
width: 360px;
|
||||
height: 55px;
|
||||
display: none;
|
||||
z-index: 1001;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -343,11 +347,11 @@ div.ui-tooltip {
|
||||
#children-overview {
|
||||
flex-grow: 1000;
|
||||
flex-shrink: 1000;
|
||||
flex-basis: 0px;
|
||||
flex-basis: 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-content: flex-start;
|
||||
height: 100px;
|
||||
height: 110px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
@@ -527,12 +531,12 @@ table.promoted-attributes-in-tooltip td, table.promoted-attributes-in-tooltip th
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.context-menu {
|
||||
.context-menu-container {
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
.context-menu .dropdown-item {
|
||||
padding: 2px 10px 2px 10px;
|
||||
#context-menu-container .dropdown-item {
|
||||
padding: 0 7px 0 10px;
|
||||
}
|
||||
|
||||
/* if modal height overflows, then only modal body scrolls */
|
||||
@@ -541,6 +545,11 @@ table.promoted-attributes-in-tooltip td, table.promoted-attributes-in-tooltip th
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/* this should help with tooltip flickering */
|
||||
.tooltip {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.tooltip-inner {
|
||||
background-color: #fbfbfb !important;
|
||||
max-width: 400px;
|
||||
@@ -557,6 +566,10 @@ table.promoted-attributes-in-tooltip td, table.promoted-attributes-in-tooltip th
|
||||
max-height: 250px;
|
||||
}
|
||||
|
||||
.tooltip-inner figure.image-style-side {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.tooltip.show {
|
||||
opacity: 1;
|
||||
}
|
||||
@@ -607,11 +620,11 @@ table.promoted-attributes-in-tooltip td, table.promoted-attributes-in-tooltip th
|
||||
}
|
||||
|
||||
.modalless {
|
||||
top:10%;
|
||||
left:50%;
|
||||
bottom:auto;
|
||||
right:auto;
|
||||
margin-left:-300px;
|
||||
top: 15%;
|
||||
left: 40%;
|
||||
bottom: auto;
|
||||
right: auto;
|
||||
margin-left: -300px;
|
||||
}
|
||||
|
||||
.multiplicity {
|
||||
@@ -621,4 +634,68 @@ table.promoted-attributes-in-tooltip td, table.promoted-attributes-in-tooltip th
|
||||
/* this is because bootstrap (?) sets code color to red for some reason */
|
||||
code {
|
||||
color: inherit !important;
|
||||
}
|
||||
|
||||
.animated {
|
||||
animation-duration: 1s;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
@keyframes fadeInDown {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translate3d(0, -100%, 0);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
.fadeInDown {
|
||||
animation-name: fadeInDown;
|
||||
}
|
||||
|
||||
@keyframes fadeOutUp {
|
||||
from {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 0;
|
||||
-webkit-transform: translate3d(0, -100%, 0);
|
||||
transform: translate3d(0, -100%, 0);
|
||||
}
|
||||
}
|
||||
|
||||
.fadeOutUp {
|
||||
animation-name: fadeOutUp;
|
||||
}
|
||||
|
||||
div[data-notify="container"] {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#saved-indicator {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 11px;
|
||||
font-size: x-large;
|
||||
color: #777;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
#export-form .form-check {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
#export-form .format-choice {
|
||||
padding-left: 40px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#export-form .form-check-label {
|
||||
padding: 2px;
|
||||
}
|
||||
@@ -95,7 +95,7 @@ async function updateNoteAttributes(req) {
|
||||
attributeEntity.isInheritable = attribute.isInheritable;
|
||||
attributeEntity.isDeleted = attribute.isDeleted;
|
||||
|
||||
if (attributeEntity.type === 'relation' && !attributeEntity.value.trim()) {
|
||||
if (attributeEntity.type === 'relation' && !attribute.value.trim()) {
|
||||
// relation should never have empty target
|
||||
attributeEntity.isDeleted = true;
|
||||
}
|
||||
|
||||
@@ -1,28 +1,22 @@
|
||||
"use strict";
|
||||
|
||||
const nativeTarExportService = require('../../services/export/native_tar');
|
||||
const markdownTarExportService = require('../../services/export/markdown_tar');
|
||||
const markdownSingleExportService = require('../../services/export/markdown_single');
|
||||
const tarExportService = require('../../services/export/tar');
|
||||
const singleExportService = require('../../services/export/single');
|
||||
const opmlExportService = require('../../services/export/opml');
|
||||
const repository = require("../../services/repository");
|
||||
|
||||
async function exportNote(req, res) {
|
||||
// entityId maybe either noteId or branchId depending on format
|
||||
const entityId = req.params.entityId;
|
||||
const format = req.params.format;
|
||||
async function exportBranch(req, res) {
|
||||
const {branchId, type, format} = req.params;
|
||||
const branch = await repository.getBranch(branchId);
|
||||
|
||||
if (format === 'native-tar') {
|
||||
await nativeTarExportService.exportToTar(await repository.getBranch(entityId), res);
|
||||
if (type === 'subtree' && (format === 'html' || format === 'markdown')) {
|
||||
await tarExportService.exportToTar(branch, format, res);
|
||||
}
|
||||
else if (format === 'markdown-tar') {
|
||||
await markdownTarExportService.exportToMarkdown(await repository.getBranch(entityId), res);
|
||||
}
|
||||
// export single note without subtree
|
||||
else if (format === 'markdown-single') {
|
||||
await markdownSingleExportService.exportSingleMarkdown(await repository.getNote(entityId), res);
|
||||
else if (type === 'single') {
|
||||
await singleExportService.exportSingleNote(branch, format, res);
|
||||
}
|
||||
else if (format === 'opml') {
|
||||
await opmlExportService.exportToOpml(await repository.getBranch(entityId), res);
|
||||
await opmlExportService.exportToOpml(branch, res);
|
||||
}
|
||||
else {
|
||||
return [404, "Unrecognized export format " + format];
|
||||
@@ -30,5 +24,5 @@ async function exportNote(req, res) {
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
exportNote
|
||||
exportBranch
|
||||
};
|
||||
@@ -4,7 +4,8 @@ const repository = require('../../services/repository');
|
||||
const enexImportService = require('../../services/import/enex');
|
||||
const opmlImportService = require('../../services/import/opml');
|
||||
const tarImportService = require('../../services/import/tar');
|
||||
const markdownImportService = require('../../services/import/markdown');
|
||||
const singleImportService = require('../../services/import/single');
|
||||
const cls = require('../../services/cls');
|
||||
const path = require('path');
|
||||
|
||||
async function importToBranch(req) {
|
||||
@@ -23,6 +24,10 @@ async function importToBranch(req) {
|
||||
|
||||
const extension = path.extname(file.originalname).toLowerCase();
|
||||
|
||||
// running all the event handlers on imported notes (and attributes) is slow
|
||||
// and may produce unintended consequences
|
||||
cls.disableEntityEvents();
|
||||
|
||||
if (extension === '.tar') {
|
||||
return await tarImportService.importTar(file.buffer, parentNote);
|
||||
}
|
||||
@@ -30,7 +35,10 @@ async function importToBranch(req) {
|
||||
return await opmlImportService.importOpml(file.buffer, parentNote);
|
||||
}
|
||||
else if (extension === '.md') {
|
||||
return await markdownImportService.importMarkdown(file, parentNote);
|
||||
return await singleImportService.importMarkdown(file, parentNote);
|
||||
}
|
||||
else if (extension === '.html' || extension === '.htm') {
|
||||
return await singleImportService.importHtml(file, parentNote);
|
||||
}
|
||||
else if (extension === '.enex') {
|
||||
return await enexImportService.importEnex(file, parentNote);
|
||||
|
||||
@@ -117,8 +117,8 @@ async function getRelationMap(req) {
|
||||
// noteId => title
|
||||
noteTitles: {},
|
||||
relations: [],
|
||||
// relation name => mirror relation name
|
||||
mirrorRelations: {},
|
||||
// relation name => inverse relation name
|
||||
inverseRelations: {},
|
||||
links: []
|
||||
};
|
||||
|
||||
@@ -143,8 +143,8 @@ async function getRelationMap(req) {
|
||||
}; }));
|
||||
|
||||
for (const relationDefinition of await note.getRelationDefinitions()) {
|
||||
if (relationDefinition.value.mirrorRelation) {
|
||||
resp.mirrorRelations[relationDefinition.name] = relationDefinition.value.mirrorRelation;
|
||||
if (relationDefinition.value.inverseRelation) {
|
||||
resp.inverseRelations[relationDefinition.name] = relationDefinition.value.inverseRelation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ function route(method, path, middleware, routeHandler, resultHandler, transactio
|
||||
router[method](path, ...middleware, async (req, res, next) => {
|
||||
try {
|
||||
const result = await cls.init(async () => {
|
||||
cls.namespace.set('sourceId', req.headers.source_id);
|
||||
cls.namespace.set('sourceId', req.headers['trilium-source-id']);
|
||||
protectedSessionService.setProtectedSessionId(req);
|
||||
|
||||
if (transactional) {
|
||||
@@ -128,7 +128,7 @@ function register(app) {
|
||||
apiRoute(PUT, '/api/notes/:noteId/clone-to/:parentNoteId', cloningApiRoute.cloneNoteToParent);
|
||||
apiRoute(PUT, '/api/notes/:noteId/clone-after/:afterBranchId', cloningApiRoute.cloneNoteAfter);
|
||||
|
||||
route(GET, '/api/notes/:entityId/export/:format', [auth.checkApiAuthOrElectron], exportRoute.exportNote);
|
||||
route(GET, '/api/notes/:branchId/export/:type/:format', [auth.checkApiAuthOrElectron], exportRoute.exportBranch);
|
||||
route(POST, '/api/notes/:parentNoteId/import', [auth.checkApiAuthOrElectron, uploadMiddleware], importRoute.importToBranch, apiResultHandler);
|
||||
|
||||
route(POST, '/api/notes/:parentNoteId/upload', [auth.checkApiAuthOrElectron, uploadMiddleware],
|
||||
|
||||
67
src/services/app_icon.js
Normal file
67
src/services/app_icon.js
Normal file
@@ -0,0 +1,67 @@
|
||||
"use strict";
|
||||
|
||||
const path = require('path');
|
||||
const {APP_PNG_ICON_DIR, ELECTRON_APP_ROOT_DIR} = require("./resource_dir");
|
||||
const log = require("./log");
|
||||
const os = require('os');
|
||||
const fs = require('fs');
|
||||
const config = require('./config');
|
||||
const utils = require('./utils');
|
||||
|
||||
const template = `[Desktop Entry]
|
||||
Type=Application
|
||||
Name=Trilium Notes
|
||||
Icon=#APP_PNG_ICON_DIR#/128x128.png
|
||||
Exec=#EXE_PATH#
|
||||
Categories=Office
|
||||
Terminal=false
|
||||
`;
|
||||
|
||||
/**
|
||||
* Installs .desktop icon into standard ~/.local/share/applications directory.
|
||||
* We overwrite this file during every run as it might have been updated.
|
||||
*/
|
||||
function installLocalAppIcon() {
|
||||
if (!utils.isElectron()
|
||||
|| ["win32", "darwin"].includes(os.platform())
|
||||
|| (config.General && config.General.noDesktopIcon)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const desktopDir = path.resolve(os.homedir(), '.local/share/applications');
|
||||
|
||||
fs.stat(desktopDir, function (err, stats) {
|
||||
if (err) {
|
||||
// Directory doesn't exist so we won't attempt to create the .desktop file
|
||||
return;
|
||||
}
|
||||
|
||||
if (stats.isDirectory()) {
|
||||
const desktopFilePath = path.resolve(desktopDir, "trilium-notes.desktop");
|
||||
|
||||
fs.writeFile(desktopFilePath, getDesktopFileContent(), function (err) {
|
||||
if (err) {
|
||||
log.error("Desktop icon installation to ~/.local/share/applications failed.");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getDesktopFileContent() {
|
||||
return template
|
||||
.replace("#APP_PNG_ICON_DIR#", escapePath(APP_PNG_ICON_DIR))
|
||||
.replace("#EXE_PATH#", escapePath(getExePath()));
|
||||
}
|
||||
|
||||
function escapePath(path) {
|
||||
return path.replace(" ", "\\ ");
|
||||
}
|
||||
|
||||
function getExePath() {
|
||||
return path.resolve(ELECTRON_APP_ROOT_DIR, 'trilium');
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
installLocalAppIcon
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user