Compare commits

...

108 Commits

Author SHA1 Message Date
zadam
82a437f2a8 remove unnecessary debounce which caused missed changes 2024-05-30 06:55:45 +02:00
zadam
a64a0e52ec Merge branch 'refs/heads/stable'
# Conflicts:
#	package-lock.json
2024-05-30 06:46:36 +02:00
zadam
88c4171031 lock file 2024-05-30 06:46:22 +02:00
zadam
b6c7e2e48f error handling 2024-05-30 06:25:03 +02:00
zadam
305d28b5b3 remove warning about the relation map - trilium is sunsetting anyway, there's no point now in deprecating this feature, fixes #4779 2024-05-30 06:24:50 +02:00
zadam
a88bf68eb6 verify that the uploaded modified file is temporary
(cherry picked from commit a2711cfb7b5b454182393aa160e45ccbf52c949d)
2024-05-30 06:10:30 +02:00
zadam
8ebebecd93
Merge pull request #4772 from gigamonster256/macos-arm64
Support compiling native MacOS arm64 (Apple Silicon) builds
2024-05-30 06:06:08 +02:00
Caleb Norton
f0d30dbe49 Add macos arm64 to release script 2024-05-18 03:48:33 -05:00
Caleb Norton
d142d3261d support compiling native arm64 macos builds 2024-05-18 03:34:24 -05:00
zadam
25b49e1ca2 release 0.63.6 2024-05-18 06:17:21 +02:00
zadam
c7f19e04fa Merge remote-tracking branch 'origin/master' 2024-05-18 05:50:53 +02:00
zadam
a2711cfb7b verify that the uploaded modified file is temporary 2024-05-18 05:50:46 +02:00
zadam
f984b361ee
Merge pull request #4717 from MatMasIt/italian-translation
Italian translation of README
2024-05-05 05:13:26 +02:00
Mattia Mascarello
ac1e1ebe43 Forgot to translate a heading 2024-03-28 20:51:28 +01:00
Mattia Mascarello
499bfaea9b Added italian to other READMEs language section 2024-03-28 20:42:53 +01:00
Mattia Mascarello
fa4772b91e proofreading 2024-03-28 20:38:20 +01:00
Mattia Mascarello
fa7b190c6b Translated readme in italian 2024-03-28 19:23:01 +01:00
zadam
84feec2e7e Merge branch 'stable'
# Conflicts:
#	package-lock.json
2024-03-28 07:26:17 +01:00
zadam
3035473751 release 0.63.5 2024-03-28 07:11:39 +01:00
zadam
399458b52f package lock 2024-03-28 07:08:31 +01:00
zadam
becac5fbad fix rendering of math on non-root paths, closes #4713 2024-03-28 07:08:15 +01:00
zadam
1e26b31090 release 0.63.4 2024-03-28 07:00:01 +01:00
zadam
0ebd03869d use "n space" instead of zero length space to make it obvious there is a character there 2024-03-28 06:57:44 +01:00
zadam
a4a713f102 allow cancelling mention UI with escape, fixes #4692, #4684 2024-03-28 06:43:26 +01:00
zadam
83d5d6bbd8 fix copy link in browser, closes #4682 2024-03-27 20:42:36 +01:00
zadam
90f4c6b0d1 allow converting file attachments to file notes 2024-03-27 06:59:57 +01:00
zadam
bfb8aa6481 remove eslint 2024-03-06 07:17:51 +01:00
zadam
2bb4cccd82 fix excalidraw 0.17 integration 2024-03-06 07:13:30 +01:00
zadam
6fad5f2b51 Merge branch 'master' into excali-17-2 2024-03-06 06:53:19 +01:00
zadam
36357bdf86 update mermaid 2024-03-06 06:52:41 +01:00
zadam
80eaf10656 remove husky 2024-03-06 06:51:25 +01:00
zadam
f46ce0417d more prettier removals 2024-03-06 06:48:25 +01:00
zadam
6f1e6402f0 package upgrades + removal of prettier 2024-03-06 06:47:30 +01:00
zadam
bdfa13a8a0
Merge pull request #4676 from st3iny/fix/invisible-unchecked-todo
fix: invisible unchecked to-do items
2024-03-06 06:32:23 +01:00
Richard Steinmetz
d5622dfbf7 fix: invisible unchecked to-do items 2024-03-05 22:29:10 +01:00
zadam
0948853539 release 0.63.3 2024-03-03 06:58:18 +01:00
zadam
0ad337c8e8 add API method to erase a revision #4662 2024-03-03 06:34:43 +01:00
zadam
9565b0b43d
Merge pull request #4671 from AlexeiKharchev/master
Reduce warnings count caused by bin/copy-trilium.sh
2024-03-03 06:26:18 +01:00
zadam
a115b14136 fix highlighting search results with regexp characters in fulltext string, closes #4665 2024-03-02 07:35:52 +01:00
Alexei Kharchev
bb8bfc61ed Improved scriptes bin/copy-trilium.sh, bin/build-linux-x64.sh 2024-03-02 14:18:39 +08:00
zadam
2d19f073d9 fix searching fulltext with tags, closes #4661 2024-03-02 07:13:02 +01:00
Alexei Kharchev
ff5d5d20d9 Reduce warnings count caused by bin/copy-trilium.sh 2024-03-02 11:49:17 +08:00
zadam
1f95e88cfd release 0.63.2-beta 2024-02-17 22:47:50 +01:00
zadam
15677f7178
Update README.md 2024-02-16 12:16:58 +01:00
zadam
3a0bb91b77 fix 2024-02-16 11:25:23 +01:00
zadam
157f894c9b
Merge pull request #4642 from henrikx/patch-1
Fix ribbon tooltips getting stuck on the screen by setting a small delay before saving attributes in attributeeditor
2024-02-16 11:02:13 +01:00
zadam
e6dec701c0 Merge remote-tracking branch 'origin/master' 2024-02-16 10:42:30 +01:00
zadam
450b52f6da JSDoc improvements 2024-02-16 10:42:25 +01:00
zadam
4ef31eaf3d
Merge pull request #4635 from WantToLearnJapanese/WantToLearnJapanese-patch-unhoist-bookmark
Fix showing unhoist confirm dialogue for bookmarked notes.
2024-02-16 06:48:04 +01:00
zadam
2d865576cf Merge remote-tracking branch 'origin/master' 2024-02-16 06:46:38 +01:00
zadam
41e623b009 fix JSDoc, closes #4633 2024-02-16 06:46:32 +01:00
zadam
239786e7d1
Merge pull request #4632 from bavis-m/master
Add the -o option to the groupmod command used in start-docker.sh
2024-02-16 06:40:38 +01:00
zadam
89e1e47900 Merge remote-tracking branch 'origin/master' 2024-02-14 07:21:36 +01:00
zadam
67cb926233 PWA manifest fixes for extra auth, fixes #4611 2024-02-14 07:21:31 +01:00
henrikx
2f813dfc5d
Update attribute_editor.js 2024-02-09 10:58:41 +01:00
WantToLearnJapanese
a939599223
Fix showing unhoist confirm dialogue for bookmarked notes. 2024-02-02 16:36:54 +09:00
Mark
fb10e0ad33 Add the -o option to the groupmod command used in start-docker.sh when USER_GID is set, otherwise we won't be added to existing groups (e.g. you want node to run in the users (100) group) 2024-02-01 11:56:37 -08:00
zadam
46bd5bc1ef
Update README.md 2024-01-29 22:36:52 +01:00
zadam
5abfb5c08a revert unintended license changes 2024-01-28 23:09:57 +01:00
zadam
9357caeb5a activate parent note when deleting a note, #4601 2024-01-28 23:08:44 +01:00
zadam
6b58e59819 added keyboard shortcut for toggling the right pane, closes #4552 2024-01-28 08:58:40 +01:00
zadam
c6df25ece8 fix pin button shadow, closes #4595 2024-01-28 08:36:16 +01:00
zadam
ebd6276b5e CKEditor 41.0.0 2024-01-27 23:02:11 +01:00
zadam
92e8b155e4 Merge branch 'stable'
# Conflicts:
#	package.json
#	src/services/build.js
#	src/services/migration.js
2024-01-27 22:52:47 +01:00
zadam
69b686ba3b basic emoji #4119 2024-01-21 10:44:23 +01:00
zadam
ace5660809 add special characters to CKEditor build #4119 2024-01-21 10:33:16 +01:00
zadam
8bc99fd799 downgrades to try to fix flatpak build 2024-01-12 00:17:04 +01:00
zadam
f0c3a090a2 release 0.63.1-beta 2024-01-12 00:02:50 +01:00
zadam
17e063f01d updates 2024-01-12 00:02:45 +01:00
zadam
76c9873705 fix erase sync 2024-01-10 23:51:53 +01:00
zadam
2c7b774356 Merge branch 'stable' 2024-01-10 22:57:05 +01:00
zadam
dff4f73366
Merge pull request #4571 from Nriver/master
fix typo in keyboard shortcuts description
2024-01-09 22:53:41 +01:00
Nriver
23a5cea338 fix typo in keyboard shortcuts description 2024-01-08 10:20:23 +08:00
zadam
e2cb3c0d14 Merge branch 'stable'
# Conflicts:
#	package.json
#	src/services/build.js
#	src/services/notes.js
2024-01-08 00:21:46 +01:00
zadam
d63d42d87c Merge branch 'stable' 2024-01-07 22:46:23 +01:00
zadam
37baa4cd74
Merge pull request #4550 from spasche/zip-export-sort-children
sort children during export to ensure a more stable format
2024-01-07 22:38:14 +01:00
zadam
68e03c434e release 0.63.0-beta 2024-01-04 00:49:06 +01:00
zadam
394530921e downgrade electron 2024-01-03 23:50:29 +01:00
zadam
57ccd5a954 stronger light anonymization 2024-01-03 22:10:29 +01:00
zadam
a28d8843ac fix migration 2024-01-03 22:08:26 +01:00
Sylvain Pasche
cb523faaad
sort children during export to ensure a more stable format 2023-12-31 16:52:19 +01:00
zadam
f704cacdee bugfixes to sync 2023-12-30 00:34:46 +01:00
zadam
8dbc592563 add "copy image" context menu to also attachments, fixes #4514 2023-12-28 00:02:09 +01:00
zadam
a3783131a2
Merge pull request #4522 from Nriver/master
fix decoding issue for request data chunks
2023-12-27 22:58:27 +01:00
zadam
8199073342 excali 17 2023-12-27 22:48:46 +01:00
zadam
33af9a3595 updates 2023-12-27 22:48:16 +01:00
Nriver
30c3c10524 fix decoding issue for request data chunks 2023-12-14 11:10:13 +08:00
zadam
df85a5eee4 Merge branch 'stable'
# Conflicts:
#	src/routes/api/revisions.js
#	src/services/bulk_actions.js
2023-12-11 23:07:15 +01:00
zadam
c35167f2f5 sometimes CPU info is not available #3957 2023-12-03 21:37:50 +01:00
zadam
929f7f3114 add node version to app_info 2023-11-27 23:12:22 +01:00
zadam
9e914b9016 remove relation map from the demo document 2023-11-27 10:54:38 +01:00
zadam
947627d8a0 relation map deprecation - don't show it in menu to create new note 2023-11-27 10:50:17 +01:00
zadam
ed00797179 Merge branch 'stable'
# Conflicts:
#	package-lock.json
2023-11-27 10:41:07 +01:00
zadam
3b10bb742b pin versions 2023-11-22 20:46:20 +01:00
zadam
1f206a9c24 load panzoom from node_modules 2023-11-22 20:28:17 +01:00
zadam
f026646bb5 load split.js from node_modules 2023-11-22 20:26:20 +01:00
zadam
f9bfc8ad86 load printThis from node_modules 2023-11-22 20:22:16 +01:00
zadam
e70539ff48 load jquery-hotkeys from node_modules 2023-11-22 20:15:21 +01:00
zadam
a439be79b3 load jquery from node_modules 2023-11-22 20:11:41 +01:00
zadam
edf2dfe8f9 load mermaid from node_modules 2023-11-22 20:09:04 +01:00
zadam
0e4c49ea5b load box icons from node_modules 2023-11-22 20:06:44 +01:00
zadam
52cfd138d1 load force-graph from node_modules 2023-11-22 20:02:35 +01:00
zadam
258b97f833 Merge remote-tracking branch 'origin/master' 2023-11-22 19:58:59 +01:00
zadam
837b17d62a load day.js from node_modules 2023-11-22 19:58:54 +01:00
zadam
d82720f62f
Merge pull request #4461 from Nriver/master
fix typo
2023-11-22 19:47:48 +01:00
zadam
cf99345962 use .js extension for require() as a preparation for future migration to ESM 2023-11-22 19:34:48 +01:00
Nriver
9e54496d00 fix more typo 2023-11-22 10:41:44 +08:00
Nriver
8ae6598b8a fix typo 2023-11-22 10:37:23 +08:00
257 changed files with 6453 additions and 29571 deletions

View File

@ -1,7 +0,0 @@
node_modules
dist
bin
docs
libraries
coverage
play

View File

@ -1,212 +0,0 @@
module.exports = {
env: {
browser: true,
commonjs: true,
es2021: true,
node: true,
},
// plugins: ['prettier'], // to be activated
extends: ['eslint:recommended', 'airbnb-base', 'plugin:jsonc/recommended-with-jsonc', 'prettier'],
overrides: [
{
files: ['*.json', '*.json5', '*.jsonc'],
parser: 'jsonc-eslint-parser',
},
{
files: ['package.json'],
parser: 'jsonc-eslint-parser',
rules: {
'jsonc/sort-keys': [
'off',
{
pathPattern: '^$',
order: [
'name',
'version',
'private',
'packageManager',
'description',
'type',
'keywords',
'homepage',
'bugs',
'license',
'author',
'contributors',
'funding',
'files',
'main',
'module',
'exports',
'unpkg',
'jsdelivr',
'browser',
'bin',
'man',
'directories',
'repository',
'publishConfig',
'scripts',
'peerDependencies',
'peerDependenciesMeta',
'optionalDependencies',
'dependencies',
'devDependencies',
'engines',
'config',
'overrides',
'pnpm',
'husky',
'lint-staged',
'eslintConfig',
],
},
{
pathPattern: '^(?:dev|peer|optional|bundled)?[Dd]ependencies$',
order: { type: 'asc' },
},
],
},
},
],
globals: {
$: true,
jQuery: true,
glob: true,
log: true,
EditorWatchdog: true,
React: true,
appState: true,
ExcalidrawLib: true,
elements: true,
files: true,
ReactDOM: true,
// src\public\app\widgets\type_widgets\relation_map.js
jsPlumb: true,
panzoom: true,
logError: true,
// src\public\app\widgets\type_widgets\image.js
WZoom: true,
// \src\public\app\widgets\type_widgets\read_only_text.js
renderMathInElement: true,
// \src\public\app\widgets\type_widgets\editable_text.js
BalloonEditor: true,
FancytreeNode: true,
CKEditorInspector: true,
// \src\public\app\widgets\type_widgets\editable_code.js
CodeMirror: true,
// \src\public\app\services\resizer.js
Split: true,
// \src\public\app\services\content_renderer.js
mermaid: true,
// src\public\app\services\frontend_script_api.js
dayjs: true,
// \src\public\app\widgets\note_map.js
ForceGraph: true,
// \src\public\app\setup.js
ko: true,
syncInProgress: true,
// src\public\app\services\utils.js
logInfo: true,
__non_webpack_require__: true,
describe: true,
it: true,
expect: true
},
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
},
rules: {
// eslint:recommended
'no-unused-vars': 'off',
'linebreak-style': 'off',
'no-useless-escape': 'off',
'no-empty': 'off',
'no-constant-condition': 'off',
'getter-return': 'off',
'no-cond-assign': 'off',
'no-async-promise-executor': 'off',
'no-extra-semi': 'off',
'no-inner-declarations': 'off',
// prettier
'prettier/prettier': ['off', { endOfLine: 'auto' }],
// airbnb-base
'no-console': 'off',
'no-plusplus': 'off',
'no-param-reassign': 'off',
'global-require': 'off',
'no-use-before-define': 'off',
'no-await-in-loop': 'off',
radix: 'off',
'import/order': 'off',
'import/no-extraneous-dependencies': 'off',
'prefer-destructuring': 'off',
'no-shadow': 'off',
'no-new': 'off',
'no-restricted-syntax': 'off',
strict: 'off',
'class-methods-use-this': 'off',
'no-else-return': 'off',
'import/no-dynamic-require': 'off',
'no-underscore-dangle': 'off',
'prefer-template': 'off',
'consistent-return': 'off',
'no-continue': 'off',
'object-shorthand': 'off',
'one-var': 'off',
'prefer-const': 'off',
'spaced-comment': 'off',
'no-loop-func': 'off',
'arrow-body-style': 'off',
'guard-for-in': 'off',
'no-return-assign': 'off',
'dot-notation': 'off',
'func-names': 'off',
'import/no-useless-path-segments': 'off',
'default-param-last': 'off',
'prefer-arrow-callback': 'off',
'no-unneeded-ternary': 'off',
'no-return-await': 'off',
'import/extensions': 'off',
'no-var': 'off',
'import/newline-after-import': 'off',
'no-restricted-globals': 'off',
'operator-assignment': 'off',
'no-eval': 'off',
'max-classes-per-file': 'off',
'vars-on-top': 'off',
'no-bitwise': 'off',
'no-lonely-if': 'off',
'no-multi-assign': 'off',
'no-promise-executor-return': 'off',
'no-empty-function': 'off',
'import/no-unresolved': 'off',
camelcase: 'off',
eqeqeq: 'off',
'lines-between-class-members': 'off',
'import/no-cycle': 'off',
'new-cap': 'off',
'prefer-object-spread': 'off',
'no-new-func': 'off',
'no-unused-expressions': 'off',
'lines-around-directive': 'off',
'prefer-exponentiation-operator': 'off',
'no-restricted-properties': 'off',
'prefer-rest-params': 'off',
'no-unreachable-loop': 'off',
'no-alert': 'off',
'no-useless-return': 'off',
'no-nested-ternary': 'off',
'prefer-regex-literals': 'off',
'import/no-named-as-default-member': 'off',
yoda: 'off',
'no-script-url': 'off',
'no-prototype-builtins':'off'
},
};

1
.husky/.gitignore vendored
View File

@ -1 +0,0 @@
_

View File

@ -1,4 +0,0 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
#npx lint-staged

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EslintConfiguration">
<option name="fix-on-save" value="true" />
</component>
</project>

View File

@ -1,13 +0,0 @@
//https://prettier.io/docs/en/options.html
module.exports = {
semi: true,
trailingComma: 'none',
singleQuote: true,
printWidth: 100,
tabWidth: 4,
useTabs: false,
quoteProps: "as-needed",
bracketSpacing: true,
arrowParens: "avoid"
// htmlWhitespaceSensitivity: 'ignore',
};

View File

@ -1,6 +0,0 @@
{
"recommendations": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
]
}

33
.vscode/settings.json vendored
View File

@ -1,33 +1,4 @@
{
"[javascript]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
},
"[json]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
},
"editor.formatOnSave": true,
"eslint.format.enable": true,
"eslint.probe": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
"html",
"vue",
"markdown",
"json",
"jsonc"
],
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
"html",
"vue",
"markdown",
"json",
"jsonc"
],
"files.eol": "\n",
}
"files.eol": "\n"
}

View File

@ -1,6 +1,6 @@
# Trilium Notes
[English](https://github.com/zadam/trilium/blob/master/README.md) | [Chinese](https://github.com/zadam/trilium/blob/master/README-ZH_CN.md) | [Russian](https://github.com/zadam/trilium/blob/master/README.ru.md) | [Japanese](https://github.com/zadam/trilium/blob/master/README.ja.md)
[English](https://github.com/zadam/trilium/blob/master/README.md) | [Chinese](https://github.com/zadam/trilium/blob/master/README-ZH_CN.md) | [Russian](https://github.com/zadam/trilium/blob/master/README.ru.md) | [Japanese](https://github.com/zadam/trilium/blob/master/README.ja.md) | [Italian](https://github.com/zadam/trilium/blob/master/README.it.md)
[![Join the chat at https://gitter.im/trilium-notes/Lobby](https://badges.gitter.im/trilium-notes/Lobby.svg)](https://gitter.im/trilium-notes/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
Trilium Notes 是一个层次化的笔记应用程序,专注于建立大型个人知识库。请参阅[屏幕截图](https://github.com/zadam/trilium/wiki/Screenshot-tour)以快速了解:

93
README.it.md Normal file
View File

@ -0,0 +1,93 @@
# Trilium Notes
## Trilium è in manutenzione - vedi i dettagli in https://github.com/zadam/trilium/issues/4620
Le discussioni preliminari sull'organizzazione si stanno svolgendo in [Trilium Next discussions](https://github.com/orgs/TriliumNext/discussions).
[![Join the chat at https://gitter.im/trilium-notes/Lobby](https://badges.gitter.im/trilium-notes/Lobby.svg)](https://gitter.im/trilium-notes/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [English](https://github.com/zadam/trilium/blob/master/README.md) | [Chinese](https://github.com/zadam/trilium/blob/master/README-ZH_CN.md) | [Russian](https://github.com/zadam/trilium/blob/master/README.ru.md) | [Japanese](https://github.com/zadam/trilium/blob/master/README.ja.md) | [Italian](https://github.com/zadam/trilium/blob/master/README.it.md)
Trilium Notes è un'applicazione per appunti ad organizzazione gerarchica, studiata per la costruzione di archivi di conoscenza personali di grandi dimensioni.
Vedi [fotografie](https://github.com/zadam/trilium/wiki/Screenshot-tour) per una panoramica veloce:
<a href="https://github.com/zadam/trilium/wiki/Screenshot-tour"><img src="https://raw.githubusercontent.com/wiki/zadam/trilium/images/screenshot.png" alt="Trilium Screenshot" width="1000"></a>
L'Ucraina si sta difendendo dall'aggressione russa, considera [donare all'esercito ucraino o a organizzazioni umanitarie](https://standforukraine.com/).
<p float="left">
<img src="https://upload.wikimedia.org/wikipedia/commons/4/49/Flag_of_Ukraine.svg" alt="drawing" width="400"/>
<img src="https://signmyrocket.com//uploads/2b2a523cd0c0e76cdbba95a89a9636b2_1676971281.jpg" alt="Trilium Notes supports Ukraine!" width="570"/>
</p>
## 🎁 Funzionalità
* Gli appunti possono essere organizzati in un albero di profondità arbitraria. Un singolo appunto può essere collocato in più posti nell'albero (vedi [clonazione](https://github.com/zadam/trilium/wiki/Cloning-notes))
* Ricco editor visuale (WYSIWYG), con supporto -tra l'altro- per tabelle, immagini ed [espressioni matematiche](https://github.com/zadam/trilium/wiki/Text-notes#math-support) e con [formattazione automatica](https://github.com/zadam/trilium/wiki/Text-notes#autoformat) per markdown
* Supporto per la modifica di [appunti con codice sorgente](https://github.com/zadam/trilium/wiki/Code-notes), con evidenziazione della sintassi
* [Navigazione veloce](https://github.com/zadam/trilium/wiki/Note-navigation) tra gli appunti, ricerca testuale completa e [fissaggio degli appunti](https://github.com/zadam/trilium/wiki/Note-hoisting)
* Supporto integrato ed automatico per le [revisioni degli appunti](https://github.com/zadam/trilium/wiki/Note-revisions)
* Gli [attributi](https://github.com/zadam/trilium/wiki/Attributes) degli appunti possono essere utilizzati per l'organizzazione, per l'interrogazione e per lo scripting avanzato (prorgrammazione).
* [Sincronizzazione](https://github.com/zadam/trilium/wiki/Synchronization) con un server di sincronizzazione auto-ospitato
* c'è un [servizio di terze parti per ospitare server di sincronizzazione](https://trilium.cc/paid-hosting)
* [Condivisione](https://github.com/zadam/trilium/wiki/Sharing) (pubblicazione) di appunti sull'internet pubblico
* Robusta [crittografia](https://github.com/zadam/trilium/wiki/Protected-notes) configurabile singolarmente per ogni appunto
* Disegno di diagrammi con Excalidraw (tipo di appunto "canvas")
* [Mappe relazionali](https://github.com/zadam/trilium/wiki/Relation-map) e [mappe di collegamenti](https://github.com/zadam/trilium/wiki/Link-map) per visualizzare gli appunti e le loro relazioni
* [Scripting](https://github.com/zadam/trilium/wiki/Scripts) - vedi [Esempi avanzati](https://github.com/zadam/trilium/wiki/Advanced-showcases)
* [API REST](https://github.com/zadam/trilium/wiki/ETAPI) per l'automazione
* Si adatta bene sia in termini di usabilità che di prestazioni fino ad oltre 100 000 appunti
* Interfaccia utente ottimizzata per il [mobile](https://github.com/zadam/trilium/wiki/Mobile-frontend) (smartphone e tablet)
* [Tema Notturno](https://github.com/zadam/trilium/wiki/Themes)
* Supporto per importazione ed esportazione da e per [Evernote](https://github.com/zadam/trilium/wiki/Evernote-import) e [Markdown import](https://github.com/zadam/trilium/wiki/Markdown)
* [Web Clipper](https://github.com/zadam/trilium/wiki/Web-clipper) per il salvataggio facile di contenuti web
Dai un'occhiata a [awesome-trilium](https://github.com/Nriver/awesome-trilium) per temi, script, plugin e altro di terze parti.
## 🏗 Rilasci
Trilium è fornito come applicazione desktop (Linux e Windows) o come applicazione web ospitata sul tuo server (Linux). La versione desktop per Mac OS è disponibile, ma [non è supportata](https://github.com/zadam/trilium/wiki/FAQ#mac-os-support).
* Se vuoi usare Trilium sul tuo desktop, scarica il rilascio binario per la tua piattaforma dall'[ultimo rilascio](https://github.com/zadam/trilium/releases/latest), decomprimi l'archivio e avvia l'eseguibile ```trilium```.
* Se vuoi installare Trilium su un server, segui [questa pagina](https://github.com/zadam/trilium/wiki/Server-installation).
* Per ora solo Chrome e Firefox sono i browser supportati (testati).
Trilium è anche disponibile su Flatpak:
[<img width="240" src="https://flathub.org/assets/badges/flathub-badge-en.png">](https://flathub.org/apps/details/com.github.zadam.trilium)
## 📝 Documentazione
[Vedi la wiki per una lista completa delle pagine di documentazione.](https://github.com/zadam/trilium/wiki/)
Puoi anche leggere ["Patterns of personal knowledge base"](https://github.com/zadam/trilium/wiki/Patterns-of-personal-knowledge-base) per avere un'ispirazione su come potresti utilizzare Trilium.
## 💻 Contribuire
Usa un ambiente di sviluppo basato su browser
[![Apri in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/zadam/trilium)
O clona localmente ed esegui
```
npm install
npm run start-server
```
## 📢 Riconoscimenti
* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - miglior editor visuale (WYSIWYG) sul mercato, squadra di sviluppo attenta e reattiva
* [FancyTree](https://github.com/mar10/fancytree) - libreria per alberi molto ricca di funzionalità, senza pari. Trilium Notes non sarebbe lo stesso senza di essa.
* [CodeMirror](https://github.com/codemirror/CodeMirror) - editor di codice con supporto per un'enorme quantità di linguaggi.
* [jsPlumb](https://github.com/jsplumb/jsplumb) - libreria per la connettività visuale senza pari. Utilizzata per [mappe relazionali](https://github.com/zadam/trilium/wiki/Relation-map) e [mappe di collegamenti](https://github.com/zadam/trilium/wiki/Link-map).
## 🤝 Supporto
È possibile supportare Trilium attraverso Github Sponsors, [PayPal](https://paypal.me/za4am) o Bitcoin (bitcoin:bc1qv3svjn40v89mnkre5vyvs2xw6y8phaltl385d2).
## 🔑 Licenza
Questo programma è software libero: è possibile redistribuirlo e/o modificarlo nei termini della GNU Affero General Public License come pubblicata dalla Free Software Foundation, sia la versione 3 della Licenza, o (a propria scelta) qualsiasi versione successiva.

View File

@ -1,6 +1,6 @@
# Trilium Notes
[English](https://github.com/zadam/trilium/blob/master/README.md) | [Chinese](https://github.com/zadam/trilium/blob/master/README-ZH_CN.md) | [Russian](https://github.com/zadam/trilium/blob/master/README.ru.md) | [Japanese](https://github.com/zadam/trilium/blob/master/README.ja.md)
[English](https://github.com/zadam/trilium/blob/master/README.md) | [Chinese](https://github.com/zadam/trilium/blob/master/README-ZH_CN.md) | [Russian](https://github.com/zadam/trilium/blob/master/README.ru.md) | [Japanese](https://github.com/zadam/trilium/blob/master/README.ja.md) | [Italian](https://github.com/zadam/trilium/blob/master/README.it.md)
Trilium Notes は、大規模な個人知識ベースの構築に焦点を当てた、階層型ノートアプリケーションです。概要は[スクリーンショット](https://github.com/zadam/trilium/wiki/Screenshot-tour)をご覧ください:

View File

@ -1,8 +1,15 @@
# Trilium Notes
[![Join the chat at https://gitter.im/trilium-notes/Lobby](https://badges.gitter.im/trilium-notes/Lobby.svg)](https://gitter.im/trilium-notes/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [English](https://github.com/zadam/trilium/blob/master/README.md) | [Chinese](https://github.com/zadam/trilium/blob/master/README-ZH_CN.md) | [Russian](https://github.com/zadam/trilium/blob/master/README.ru.md) | [Japanese](https://github.com/zadam/trilium/blob/master/README.ja.md)
## Trilium is in maintenance mode - see details in https://github.com/zadam/trilium/issues/4620
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:
Preliminary disccusions on the successor organization are taking place in [Trilium Next discussions](https://github.com/orgs/TriliumNext/discussions).
[![Join the chat at https://gitter.im/trilium-notes/Lobby](https://badges.gitter.im/trilium-notes/Lobby.svg)](https://gitter.im/trilium-notes/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [English](https://github.com/zadam/trilium/blob/master/README.md) | [Chinese](https://github.com/zadam/trilium/blob/master/README-ZH_CN.md) | [Russian](https://github.com/zadam/trilium/blob/master/README.ru.md) | [Japanese](https://github.com/zadam/trilium/blob/master/README.ja.md) | [Italian](https://github.com/zadam/trilium/blob/master/README.it.md)
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:
<a href="https://github.com/zadam/trilium/wiki/Screenshot-tour"><img src="https://raw.githubusercontent.com/wiki/zadam/trilium/images/screenshot.png" alt="Trilium Screenshot" width="1000"></a>

View File

@ -1,6 +1,6 @@
# Trilium Notes
[English](https://github.com/zadam/trilium/blob/master/README.md) | [Chinese](https://github.com/zadam/trilium/blob/master/README-ZH_CN.md) | [Russian](https://github.com/zadam/trilium/blob/master/README.ru.md) | [Japanese](https://github.com/zadam/trilium/blob/master/README.ja.md)
[English](https://github.com/zadam/trilium/blob/master/README.md) | [Chinese](https://github.com/zadam/trilium/blob/master/README-ZH_CN.md) | [Russian](https://github.com/zadam/trilium/blob/master/README.ru.md) | [Japanese](https://github.com/zadam/trilium/blob/master/README.ja.md) | [Italian](https://github.com/zadam/trilium/blob/master/README.it.md)
[![Join the chat at https://gitter.im/trilium-notes/Lobby](https://badges.gitter.im/trilium-notes/Lobby.svg)](https://gitter.im/trilium-notes/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
Trilium Notes это приложение для заметок с иерархической структурой, ориентированное на создание больших персональных баз знаний. Для быстрого ознакомления посмотрите [скриншот-тур](https://github.com/zadam/trilium/wiki/Screenshot-tour):

Binary file not shown.

View File

@ -2,49 +2,37 @@
SRC_DIR=./dist/trilium-linux-x64-src
if [ "$1" != "DONTCOPY" ]
then
./bin/copy-trilium.sh $SRC_DIR
fi
[ "$1" != "DONTCOPY" ] && ./bin/copy-trilium.sh "$SRC_DIR"
rm -r $SRC_DIR/src/public/app-dist/*.mobile.*
rm -r "$SRC_DIR"/src/public/app-dist/*.mobile.*
echo "Copying required linux-x64 binaries"
cp -r bin/better-sqlite3/linux-desktop-better_sqlite3.node $SRC_DIR/node_modules/better-sqlite3/build/Release/better_sqlite3.node
cp -r bin/better-sqlite3/linux-desktop-better_sqlite3.node "$SRC_DIR"/node_modules/better-sqlite3/build/Release/better_sqlite3.node
echo "Packaging linux x64 electron build"
./node_modules/.bin/electron-packager $SRC_DIR --asar --out=dist --executable-name=trilium --platform=linux --arch=x64 --overwrite
./node_modules/.bin/electron-packager "$SRC_DIR" --asar --out=dist --executable-name=trilium --platform=linux --arch=x64 --overwrite
BUILD_DIR=./dist/trilium-linux-x64
rm -rf $BUILD_DIR
rm -rf "$BUILD_DIR"
mv "./dist/Trilium Notes-linux-x64" $BUILD_DIR
mv "./dist/Trilium Notes-linux-x64" "$BUILD_DIR"
cp images/app-icons/png/128x128.png $BUILD_DIR/icon.png
cp images/app-icons/png/128x128.png "$BUILD_DIR"/icon.png
cp bin/tpl/anonymize-database.sql "$BUILD_DIR"/
cp bin/tpl/anonymize-database.sql $BUILD_DIR/
cp -r dump-db "$BUILD_DIR"/
rm -rf "$BUILD_DIR"/dump-db/node_modules
cp -r dump-db $BUILD_DIR/
rm -rf $BUILD_DIR/dump-db/node_modules
cp bin/tpl/trilium-portable.sh $BUILD_DIR/
chmod 755 $BUILD_DIR/trilium-portable.sh
cp bin/tpl/trilium-safe-mode.sh $BUILD_DIR/
chmod 755 $BUILD_DIR/trilium-safe-mode.sh
cp bin/tpl/trilium-no-cert-check.sh $BUILD_DIR/
chmod 755 $BUILD_DIR/trilium-no-cert-check.sh
for f in 'trilium-portable' 'trilium-safe-mode' 'trilium-no-cert-check'; do
cp bin/tpl/"$f".sh "$BUILD_DIR"/
chmod 755 "$BUILD_DIR"/"$f".sh
done
echo "Packaging linux x64 electron distribution..."
VERSION=`jq -r ".version" package.json`
cd dist
tar cJf trilium-linux-x64-${VERSION}.tar.xz trilium-linux-x64
cd ..
pushd dist
tar cJf "trilium-linux-x64-${VERSION}.tar.xz" trilium-linux-x64
popd
bin/build-debian.sh

38
bin/build-mac-arm64.sh Executable file
View File

@ -0,0 +1,38 @@
#!/usr/bin/env bash
SRC_DIR=./dist/trilium-mac-arm64-src
if [ "$1" != "DONTCOPY" ]
then
./bin/copy-trilium.sh $SRC_DIR
fi
echo "Copying required mac arm64 binaries"
cp -r bin/better-sqlite3/mac-arm64-better_sqlite3.node $SRC_DIR/node_modules/better-sqlite3/build/Release/better_sqlite3.node
rm -r $SRC_DIR/src/public/app-dist/*.mobile.*
echo "Packaging mac arm64 electron build"
./node_modules/.bin/electron-packager $SRC_DIR --asar --out=dist --executable-name=trilium --platform=darwin --arch=arm64 --overwrite --icon=images/app-icons/mac/icon.icns
BUILD_DIR=./dist/trilium-mac-arm64
rm -rf $BUILD_DIR
# Mac build has by default useless directory level
mv "./dist/Trilium Notes-darwin-arm64" $BUILD_DIR
cp bin/tpl/anonymize-database.sql $BUILD_DIR/
cp -r dump-db $BUILD_DIR/
rm -rf $BUILD_DIR/dump-db/node_modules
echo "Zipping mac arm64 electron distribution..."
VERSION=`jq -r ".version" package.json`
cd dist
rm trilium-mac-arm64-${VERSION}.zip
zip -r9 --symlinks trilium-mac-arm64-${VERSION}.zip trilium-mac-arm64

View File

@ -7,9 +7,9 @@ then
./bin/copy-trilium.sh $SRC_DIR
fi
echo "Copying required mac binaries"
echo "Copying required mac x64 binaries"
cp -r bin/better-sqlite3/mac-better_sqlite3.node $SRC_DIR/node_modules/better-sqlite3/build/Release/better_sqlite3.node
cp -r bin/better-sqlite3/mac-x64-better_sqlite3.node $SRC_DIR/node_modules/better-sqlite3/build/Release/better_sqlite3.node
rm -r $SRC_DIR/src/public/app-dist/*.mobile.*

View File

@ -13,11 +13,14 @@ cp -r $SRC_DIR ./dist/trilium-linux-x64-src
cp -r $SRC_DIR ./dist/trilium-linux-x64-server
cp -r $SRC_DIR ./dist/trilium-windows-x64-src
cp -r $SRC_DIR ./dist/trilium-mac-x64-src
cp -r $SRC_DIR ./dist/trilium-mac-arm64-src
bin/build-win-x64.sh DONTCOPY
bin/build-mac-x64.sh DONTCOPY
bin/build-mac-arm64.sh DONTCOPY
bin/build-linux-x64.sh DONTCOPY
bin/build-server.sh DONTCOPY

View File

@ -4,47 +4,49 @@ if [[ $# -eq 0 ]] ; then
echo "Missing argument of target directory"
exit 1
fi
if ! [[ $(which npm) ]]; then
echo "Missing npm"
exit 1
fi
n exec 18.18.2 npm run webpack
n exec 18.18.2 npm run webpack || npm run webpack
DIR=$1
DIR="$1"
rm -rf $DIR
mkdir $DIR
rm -rf "$DIR"
mkdir -pv "$DIR"
echo "Copying Trilium to build directory $DIR"
cp -r images $DIR/
cp -r libraries $DIR/
cp -r src $DIR/
cp -r db $DIR/
cp -r package.json $DIR/
cp -r package-lock.json $DIR/
cp -r README.md $DIR/
cp -r LICENSE $DIR/
cp -r config-sample.ini $DIR/
cp -r electron.js $DIR/
cp webpack-* $DIR/
for d in 'images' 'libraries' 'src' 'db'; do
cp -r "$d" "$DIR"/
done
for f in 'package.json' 'package-lock.json' 'README.md' 'LICENSE' 'config-sample.ini' 'electron.js'; do
cp "$f" "$DIR"/
done
cp webpack-* "$DIR"/ # here warning because there is no 'webpack-*', but webpack.config.js only
# run in subshell (so we return to original dir)
(cd $DIR && n exec 18.18.2 npm install --only=prod)
if [[ -d "$DIR"/node_modules ]]; then
# cleanup of useless files in dependencies
rm -r $DIR/node_modules/image-q/demo
rm -r $DIR/node_modules/better-sqlite3/Release
rm -r $DIR/node_modules/better-sqlite3/deps/sqlite3.tar.gz
rm -r $DIR/node_modules/@jimp/plugin-print/fonts
rm -r $DIR/node_modules/jimp/browser
rm -r $DIR/node_modules/jimp/fonts
for d in 'image-q/demo' 'better-sqlite3/Release' 'better-sqlite3/deps/sqlite3.tar.gz' '@jimp/plugin-print/fonts' 'jimp/browser' 'jimp/fonts'; do
[[ -e "$DIR"/node_modules/"$d" ]] && rm -rv "$DIR"/node_modules/"$d"
done
# delete all tests (there are often large images as test file for jimp etc.)
find $DIR/node_modules -name test -exec rm -rf {} \;
find $DIR/node_modules -name docs -exec rm -rf {} \;
find $DIR/node_modules -name demo -exec rm -rf {} \;
for d in 'test' 'docs' 'demo'; do
find "$DIR"/node_modules -name "$d" -exec rm -rf {} \;
done
fi
find $DIR/libraries -name "*.map" -type f -delete
cp $DIR/src/public/app/share.js $DIR/src/public/app-dist/
cp -r $DIR/src/public/app/doc_notes $DIR/src/public/app-dist/
d="$DIR"/src/public
[[ -d "$d"/app-dist ]] || mkdir -pv "$d"/app-dist
cp "$d"/app/share.js "$d"/app-dist/
cp -r "$d"/app/doc_notes "$d"/app-dist/
rm -rf $DIR/src/public/app
rm -rf "$d"/app
unset f d DIR

View File

@ -1,6 +1,6 @@
#!/usr/bin/env node
const anonymizationService = require('../src/services/anonymization');
const anonymizationService = require('../src/services/anonymization.js');
const fs = require('fs');
const path = require('path');

View File

@ -48,6 +48,7 @@ LINUX_X64_BUILD=trilium-linux-x64-$VERSION.tar.xz
DEBIAN_X64_BUILD=trilium_${VERSION}_amd64.deb
WINDOWS_X64_BUILD=trilium-windows-x64-$VERSION.zip
MAC_X64_BUILD=trilium-mac-x64-$VERSION.zip
MAC_ARM64_BUILD=trilium-mac-arm64-$VERSION.zip
SERVER_BUILD=trilium-linux-x64-server-$VERSION.tar.xz
echo "Creating release in GitHub"
@ -68,4 +69,5 @@ gh release create "$TAG" \
"dist/$LINUX_X64_BUILD" \
"dist/$WINDOWS_X64_BUILD" \
"dist/$MAC_X64_BUILD" \
"dist/$MAC_ARM64_BUILD" \
"dist/$SERVER_BUILD"

Binary file not shown.

View File

@ -1,6 +1,6 @@
module.exports = () => {
const sql = require("../../src/services/sql");
const utils = require("../../src/services/utils");
const sql = require('../../src/services/sql.js');
const utils = require('../../src/services/utils.js');
const existingBlobIds = new Set();

View File

@ -1,9 +1,9 @@
module.exports = () => {
const beccaLoader = require("../../src/becca/becca_loader");
const becca = require("../../src/becca/becca");
const cls = require("../../src/services/cls");
const log = require("../../src/services/log");
const sql = require("../../src/services/sql");
const beccaLoader = require('../../src/becca/becca_loader.js');
const becca = require('../../src/becca/becca.js');
const cls = require('../../src/services/cls.js');
const log = require('../../src/services/log.js');
const sql = require('../../src/services/sql.js');
cls.init(() => {
// emergency disabling of image compression since it appears to make problems in migration to 0.61

View File

@ -0,0 +1,17 @@
-- + is normally replaced by X and / by Y, but this can temporarily cause UNIQUE key exception
-- this might create blob duplicates, but cleanup will eventually take care of it
UPDATE blobs SET blobId = REPLACE(blobId, '+', 'A');
UPDATE blobs SET blobId = REPLACE(blobId, '/', 'B');
UPDATE notes SET blobId = REPLACE(blobId, '+', 'A');
UPDATE notes SET blobId = REPLACE(blobId, '/', 'B');
UPDATE attachments SET blobId = REPLACE(blobId, '+', 'A');
UPDATE attachments SET blobId = REPLACE(blobId, '/', 'B');
UPDATE revisions SET blobId = REPLACE(blobId, '+', 'A');
UPDATE revisions SET blobId = REPLACE(blobId, '/', 'B');
UPDATE entity_changes SET entityId = REPLACE(entityId, '+', 'A') WHERE entityName = 'blobs';
UPDATE entity_changes SET entityId = REPLACE(entityId, '/', 'B') WHERE entityName = 'blobs';

View File

@ -1,7 +1,7 @@
const http = require("http");
const ini = require("ini");
const fs = require("fs");
const dataDir = require("./src/services/data_dir");
const dataDir = require('./src/services/data_dir.js');
const config = ini.parse(fs.readFileSync(dataDir.CONFIG_INI_PATH, 'utf-8'));
if (config.Network.https) {
@ -10,8 +10,8 @@ if (config.Network.https) {
process.exit(0);
}
const port = require('./src/services/port');
const host = require('./src/services/host');
const port = require('./src/services/port.js');
const host = require('./src/services/host.js');
const options = { timeout: 2000 };

View File

@ -2,7 +2,7 @@
const yargs = require('yargs/yargs')
const { hideBin } = require('yargs/helpers')
const dumpService = require("./inc/dump");
const dumpService = require('./inc/dump.js');
yargs(hideBin(process.argv))
.command('$0 <path_to_document> <target_directory>', 'dump the contents of document.db into the target directory', (yargs) => {

View File

@ -1,6 +1,6 @@
const crypto = require("crypto");
const sql = require("./sql");
const decryptService = require("./decrypt");
const sql = require('./sql.js');
const decryptService = require('./decrypt.js');
function getDataKey(password) {
if (!password) {

View File

@ -1,9 +1,9 @@
const fs = require("fs");
const sanitize = require("sanitize-filename");
const sql = require("./sql");
const decryptService = require("./decrypt");
const dataKeyService = require("./data_key");
const extensionService = require("./extension");
const sql = require('./sql.js');
const decryptService = require('./decrypt.js');
const dataKeyService = require('./data_key.js');
const extensionService = require('./extension.js');
function dumpDocument(documentPath, targetPath, options) {
const stats = {

View File

@ -1,10 +1,10 @@
'use strict';
const {app, globalShortcut, BrowserWindow} = require('electron');
const sqlInit = require('./src/services/sql_init');
const appIconService = require('./src/services/app_icon');
const windowService = require('./src/services/window');
const tray = require('./src/services/tray');
const sqlInit = require('./src/services/sql_init.js');
const appIconService = require('./src/services/app_icon.js');
const windowService = require('./src/services/window.js');
const tray = require('./src/services/tray.js');
// Adds debug features like hotkeys for triggering dev tools and reload
require('electron-debug')();
@ -59,4 +59,4 @@ app.on('will-quit', () => {
// this is to disable electron warning spam in the dev console (local development only)
process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true';
require('./src/www');
require('./src/www.js');

View File

@ -1,21 +0,0 @@
The MIT License (MIT)
Copyright (c) 2015-2021 Aniket Suvarna
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 1.2 MiB

View File

@ -5,8 +5,8 @@
}
/*
* CKEditor 5 (v40.1.0) content styles.
* Generated on Mon, 20 Nov 2023 08:41:49 GMT.
* CKEditor 5 (v41.0.0) content styles.
* Generated on Fri, 26 Jan 2024 10:23:49 GMT.
* For more information, check out https://ckeditor.com/docs/ckeditor5/latest/installation/advanced/content-styles.html
*/
@ -42,18 +42,6 @@
overflow-wrap: break-word;
position: relative;
}
/* @ckeditor/ckeditor5-table/theme/tablecaption.css */
.ck-content .table > figcaption {
display: table-caption;
caption-side: top;
word-break: break-word;
text-align: center;
color: var(--ck-color-selector-caption-text);
background-color: var(--ck-color-selector-caption-background);
padding: .6em;
font-size: .75em;
outline-offset: -1px;
}
/* @ckeditor/ckeditor5-table/theme/table.css */
.ck-content .table {
margin: 0.9em auto;
@ -87,12 +75,17 @@
.ck-content[dir="ltr"] .table th {
text-align: left;
}
/* @ckeditor/ckeditor5-media-embed/theme/mediaembed.css */
.ck-content .media {
clear: both;
margin: 0.9em 0;
display: block;
min-width: 15em;
/* @ckeditor/ckeditor5-table/theme/tablecaption.css */
.ck-content .table > figcaption {
display: table-caption;
caption-side: top;
word-break: break-word;
text-align: center;
color: var(--ck-color-selector-caption-text);
background-color: var(--ck-color-selector-caption-background);
padding: .6em;
font-size: .75em;
outline-offset: -1px;
}
/* @ckeditor/ckeditor5-page-break/theme/pagebreak.css */
.ck-content .page-break {
@ -130,6 +123,13 @@
-ms-user-select: none;
user-select: none;
}
/* @ckeditor/ckeditor5-media-embed/theme/mediaembed.css */
.ck-content .media {
clear: both;
margin: 0.9em 0;
display: block;
min-width: 15em;
}
/* @ckeditor/ckeditor5-list/theme/todolist.css */
.ck-content .todo-list {
list-style: none;
@ -280,6 +280,42 @@
.ck-editor__editable.ck-content .todo-list .todo-list__label.todo-list__label_without-description input[type=checkbox] {
position: absolute;
}
/* @ckeditor/ckeditor5-list/theme/list.css */
.ck-content ol {
list-style-type: decimal;
}
/* @ckeditor/ckeditor5-list/theme/list.css */
.ck-content ol ol {
list-style-type: lower-latin;
}
/* @ckeditor/ckeditor5-list/theme/list.css */
.ck-content ol ol ol {
list-style-type: lower-roman;
}
/* @ckeditor/ckeditor5-list/theme/list.css */
.ck-content ol ol ol ol {
list-style-type: upper-latin;
}
/* @ckeditor/ckeditor5-list/theme/list.css */
.ck-content ol ol ol ol ol {
list-style-type: upper-roman;
}
/* @ckeditor/ckeditor5-list/theme/list.css */
.ck-content ul {
list-style-type: disc;
}
/* @ckeditor/ckeditor5-list/theme/list.css */
.ck-content ul ul {
list-style-type: circle;
}
/* @ckeditor/ckeditor5-list/theme/list.css */
.ck-content ul ul ul {
list-style-type: square;
}
/* @ckeditor/ckeditor5-list/theme/list.css */
.ck-content ul ul ul ul {
list-style-type: square;
}
/* @ckeditor/ckeditor5-image/theme/image.css */
.ck-content .image {
display: table;
@ -318,17 +354,6 @@
flex-shrink: 1;
max-width: 100%;
}
/* @ckeditor/ckeditor5-image/theme/imagecaption.css */
.ck-content .image > figcaption {
display: table-caption;
caption-side: bottom;
word-break: break-word;
color: var(--ck-color-image-caption-text);
background-color: var(--ck-color-image-caption-background);
padding: .6em;
font-size: .75em;
outline-offset: -1px;
}
/* @ckeditor/ckeditor5-image/theme/imageresize.css */
.ck-content img.image_resized {
height: auto;
@ -347,67 +372,16 @@
.ck-content .image.image_resized > figcaption {
display: block;
}
/* @ckeditor/ckeditor5-highlight/theme/highlight.css */
.ck-content .marker-yellow {
background-color: var(--ck-highlight-marker-yellow);
}
/* @ckeditor/ckeditor5-highlight/theme/highlight.css */
.ck-content .marker-green {
background-color: var(--ck-highlight-marker-green);
}
/* @ckeditor/ckeditor5-highlight/theme/highlight.css */
.ck-content .marker-pink {
background-color: var(--ck-highlight-marker-pink);
}
/* @ckeditor/ckeditor5-highlight/theme/highlight.css */
.ck-content .marker-blue {
background-color: var(--ck-highlight-marker-blue);
}
/* @ckeditor/ckeditor5-highlight/theme/highlight.css */
.ck-content .pen-red {
color: var(--ck-highlight-pen-red);
background-color: transparent;
}
/* @ckeditor/ckeditor5-highlight/theme/highlight.css */
.ck-content .pen-green {
color: var(--ck-highlight-pen-green);
background-color: transparent;
}
/* @ckeditor/ckeditor5-list/theme/list.css */
.ck-content ol {
list-style-type: decimal;
}
/* @ckeditor/ckeditor5-list/theme/list.css */
.ck-content ol ol {
list-style-type: lower-latin;
}
/* @ckeditor/ckeditor5-list/theme/list.css */
.ck-content ol ol ol {
list-style-type: lower-roman;
}
/* @ckeditor/ckeditor5-list/theme/list.css */
.ck-content ol ol ol ol {
list-style-type: upper-latin;
}
/* @ckeditor/ckeditor5-list/theme/list.css */
.ck-content ol ol ol ol ol {
list-style-type: upper-roman;
}
/* @ckeditor/ckeditor5-list/theme/list.css */
.ck-content ul {
list-style-type: disc;
}
/* @ckeditor/ckeditor5-list/theme/list.css */
.ck-content ul ul {
list-style-type: circle;
}
/* @ckeditor/ckeditor5-list/theme/list.css */
.ck-content ul ul ul {
list-style-type: square;
}
/* @ckeditor/ckeditor5-list/theme/list.css */
.ck-content ul ul ul ul {
list-style-type: square;
/* @ckeditor/ckeditor5-image/theme/imagecaption.css */
.ck-content .image > figcaption {
display: table-caption;
caption-side: bottom;
word-break: break-word;
color: var(--ck-color-image-caption-text);
background-color: var(--ck-color-image-caption-background);
padding: .6em;
font-size: .75em;
outline-offset: -1px;
}
/* @ckeditor/ckeditor5-image/theme/imagestyle.css */
.ck-content .image-style-block-align-left,
@ -470,6 +444,32 @@
.ck-content .image-inline.image-style-align-right {
margin-left: var(--ck-inline-image-style-spacing);
}
/* @ckeditor/ckeditor5-highlight/theme/highlight.css */
.ck-content .marker-yellow {
background-color: var(--ck-highlight-marker-yellow);
}
/* @ckeditor/ckeditor5-highlight/theme/highlight.css */
.ck-content .marker-green {
background-color: var(--ck-highlight-marker-green);
}
/* @ckeditor/ckeditor5-highlight/theme/highlight.css */
.ck-content .marker-pink {
background-color: var(--ck-highlight-marker-pink);
}
/* @ckeditor/ckeditor5-highlight/theme/highlight.css */
.ck-content .marker-blue {
background-color: var(--ck-highlight-marker-blue);
}
/* @ckeditor/ckeditor5-highlight/theme/highlight.css */
.ck-content .pen-red {
color: var(--ck-highlight-pen-red);
background-color: transparent;
}
/* @ckeditor/ckeditor5-highlight/theme/highlight.css */
.ck-content .pen-green {
color: var(--ck-highlight-pen-green);
background-color: transparent;
}
/* @ckeditor/ckeditor5-block-quote/theme/blockquote.css */
.ck-content blockquote {
overflow: hidden;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,195 +0,0 @@
/*jslint browser: true*/
/*jslint jquery: true*/
/*
* jQuery Hotkeys Plugin
* Copyright 2010, John Resig
* Dual licensed under the MIT or GPL Version 2 licenses.
*
* Based upon the plugin by Tzury Bar Yochay:
* http://github.com/tzuryby/hotkeys
*
* Original idea by:
* Binny V A, http://www.openjs.com/scripts/events/keyboard_shortcuts/
*/
/*
* One small change is: now keys are passed by object { keys: '...' }
* Might be useful, when you want to pass some other data to your handler
*/
(function(jQuery) {
jQuery.hotkeys = {
version: "0.8",
specialKeys: {
8: "backspace",
9: "tab",
10: "return",
13: "return",
16: "shift",
17: "ctrl",
18: "alt",
19: "pause",
20: "capslock",
27: "esc",
32: "space",
33: "pageup",
34: "pagedown",
35: "end",
36: "home",
37: "left",
38: "up",
39: "right",
40: "down",
45: "insert",
46: "del",
59: ";",
61: "=",
96: "0",
97: "1",
98: "2",
99: "3",
100: "4",
101: "5",
102: "6",
103: "7",
104: "8",
105: "9",
106: "*",
107: "+",
109: "-",
110: ".",
111: "/",
112: "f1",
113: "f2",
114: "f3",
115: "f4",
116: "f5",
117: "f6",
118: "f7",
119: "f8",
120: "f9",
121: "f10",
122: "f11",
123: "f12",
144: "numlock",
145: "scroll",
173: "-",
186: ";",
187: "=",
188: ",",
189: "-",
190: ".",
191: "/",
192: "`",
219: "[",
220: "\\",
221: "]",
222: "'"
},
shiftNums: {
"`": "~",
"1": "!",
"2": "@",
"3": "#",
"4": "$",
"5": "%",
"6": "^",
"7": "&",
"8": "*",
"9": "(",
"0": ")",
"-": "_",
"=": "+",
";": ": ",
"'": "\"",
",": "<",
".": ">",
"/": "?",
"\\": "|"
},
// excludes: button, checkbox, file, hidden, image, password, radio, reset, search, submit, url
textAcceptingInputTypes: [
"text", "password", "number", "email", "url", "range", "date", "month", "week", "time", "datetime",
"datetime-local", "search", "color", "tel"],
options: {
filterTextInputs: true
}
};
function keyHandler(handleObj) {
if (typeof handleObj.data === "string") {
handleObj.data = {
keys: handleObj.data
};
}
// Only care when a possible input has been specified
if (!handleObj.data || !handleObj.data.keys || typeof handleObj.data.keys !== "string") {
return;
}
var origHandler = handleObj.handler,
keys = handleObj.data.keys.toLowerCase().split(" ");
handleObj.handler = function(event) {
if (jQuery.hotkeys.options.filterTextInputs &&
event.target.tagName != 'WEBVIEW' &&
jQuery.inArray(event.target.type, jQuery.hotkeys.textAcceptingInputTypes) > -1) {
return;
}
var special = event.type !== "keypress" && jQuery.hotkeys.specialKeys[event.which],
character = String.fromCharCode(event.which).toLowerCase(),
modif = "",
possible = {};
jQuery.each(["alt", "ctrl", "shift"], function(index, specialKey) {
if (event[specialKey + 'Key'] && special !== specialKey) {
modif += specialKey + '+';
}
});
// metaKey is triggered off ctrlKey erronously
if (event.metaKey && !event.ctrlKey && special !== "meta") {
modif += "meta+";
}
if (event.metaKey && special !== "meta" && modif.indexOf("alt+ctrl+shift+") > -1) {
modif = modif.replace("alt+ctrl+shift+", "hyper+");
}
if (special) {
possible[modif + special] = true;
}
else {
possible[modif + character] = true;
possible[modif + jQuery.hotkeys.shiftNums[character]] = true;
// "$" can be triggered as "Shift+4" or "Shift+$" or just "$"
if (modif === "shift+") {
possible[jQuery.hotkeys.shiftNums[character]] = true;
}
}
for (var i = 0, l = keys.length; i < l; i++) {
if (possible[keys[i]]) {
return origHandler.apply(this, arguments);
}
}
};
}
jQuery.each(["keydown", "keyup", "keypress"], function() {
jQuery.event.special[this] = {
add: keyHandler
};
});
})(jQuery || this.jQuery || window.jQuery);

10704
libraries/jquery.js vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1641
libraries/mermaid.min.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -1,335 +0,0 @@
/*
* printThis v1.15.0
* @desc Printing plug-in for jQuery
* @author Jason Day
*
* Resources (based on):
* - jPrintArea: http://plugins.jquery.com/project/jPrintArea
* - jqPrint: https://github.com/permanenttourist/jquery.jqprint
* - Ben Nadal: http://www.bennadel.com/blog/1591-Ask-Ben-Print-Part-Of-A-Web-Page-With-jQuery.htm
*
* Licensed under the MIT licence:
* http://www.opensource.org/licenses/mit-license.php
*
* (c) Jason Day 2015-2018
*
* Usage:
*
* $("#mySelector").printThis({
* debug: false, // show the iframe for debugging
* importCSS: true, // import parent page css
* importStyle: false, // import style tags
* printContainer: true, // grab outer container as well as the contents of the selector
* loadCSS: "path/to/my.css", // path to additional css file - use an array [] for multiple
* pageTitle: "", // add title to print page
* removeInline: false, // remove all inline styles from print elements
* removeInlineSelector: "body *", // custom selectors to filter inline styles. removeInline must be true
* printDelay: 333, // variable print delay
* header: null, // prefix to html
* footer: null, // postfix to html
* base: false, // preserve the BASE tag, or accept a string for the URL
* formValues: true, // preserve input/form values
* canvas: false, // copy canvas elements
* doctypeString: '...', // enter a different doctype for older markup
* removeScripts: false, // remove script tags from print content
* copyTagClasses: false // copy classes from the html & body tag
* beforePrintEvent: null, // callback function for printEvent in iframe
* beforePrint: null, // function called before iframe is filled
* afterPrint: null // function called before iframe is removed
* });
*
* Notes:
* - the loadCSS will load additional CSS (with or without @media print) into the iframe, adjusting layout
*/
;
(function($) {
function appendContent($el, content) {
if (!content) return;
// Simple test for a jQuery element
$el.append(content.jquery ? content.clone() : content);
}
function appendBody($body, $element, opt) {
// Clone for safety and convenience
// Calls clone(withDataAndEvents = true) to copy form values.
var $content = $element.clone(opt.formValues);
if (opt.formValues) {
// Copy original select and textarea values to their cloned counterpart
// Makes up for inability to clone select and textarea values with clone(true)
copyValues($element, $content, 'select, textarea');
}
if (opt.removeScripts) {
$content.find('script').remove();
}
if (opt.printContainer) {
// grab $.selector as container
$content.appendTo($body);
} else {
// otherwise just print interior elements of container
$content.each(function() {
$(this).children().appendTo($body)
});
}
}
// Copies values from origin to clone for passed in elementSelector
function copyValues(origin, clone, elementSelector) {
var $originalElements = origin.find(elementSelector);
clone.find(elementSelector).each(function(index, item) {
$(item).val($originalElements.eq(index).val());
});
}
var opt;
$.fn.printThis = function(options) {
opt = $.extend({}, $.fn.printThis.defaults, options);
var $element = this instanceof jQuery ? this : $(this);
var strFrameName = "printThis-" + (new Date()).getTime();
if (window.location.hostname !== document.domain && navigator.userAgent.match(/msie/i)) {
// Ugly IE hacks due to IE not inheriting document.domain from parent
// checks if document.domain is set by comparing the host name against document.domain
var iframeSrc = "javascript:document.write(\"<head><script>document.domain=\\\"" + document.domain + "\\\";</s" + "cript></head><body></body>\")";
var printI = document.createElement('iframe');
printI.name = "printIframe";
printI.id = strFrameName;
printI.className = "MSIE";
document.body.appendChild(printI);
printI.src = iframeSrc;
} else {
// other browsers inherit document.domain, and IE works if document.domain is not explicitly set
var $frame = $("<iframe id='" + strFrameName + "' name='printIframe' />");
$frame.appendTo("body");
}
var $iframe = $("#" + strFrameName);
// show frame if in debug mode
if (!opt.debug) $iframe.css({
position: "absolute",
width: "0px",
height: "0px",
left: "-600px",
top: "-600px"
});
// before print callback
if (typeof opt.beforePrint === "function") {
opt.beforePrint();
}
// $iframe.ready() and $iframe.load were inconsistent between browsers
setTimeout(function() {
// Add doctype to fix the style difference between printing and render
function setDocType($iframe, doctype){
var win, doc;
win = $iframe.get(0);
win = win.contentWindow || win.contentDocument || win;
doc = win.document || win.contentDocument || win;
doc.open();
doc.write(doctype);
doc.close();
}
if (opt.doctypeString){
setDocType($iframe, opt.doctypeString);
}
var $doc = $iframe.contents(),
$head = $doc.find("head"),
$body = $doc.find("body"),
$base = $('base'),
baseURL;
// add base tag to ensure elements use the parent domain
if (opt.base === true && $base.length > 0) {
// take the base tag from the original page
baseURL = $base.attr('href');
} else if (typeof opt.base === 'string') {
// An exact base string is provided
baseURL = opt.base;
} else {
// Use the page URL as the base
baseURL = document.location.protocol + '//' + document.location.host;
}
$head.append('<base href="' + baseURL + '">');
// import page stylesheets
if (opt.importCSS) $("link[rel=stylesheet]").each(function() {
var href = $(this).attr("href");
if (href) {
var media = $(this).attr("media") || "all";
$head.append("<link type='text/css' rel='stylesheet' href='" + href + "' media='" + media + "'>");
}
});
// import style tags
if (opt.importStyle) $("style").each(function() {
$head.append(this.outerHTML);
});
// add title of the page
if (opt.pageTitle) $head.append("<title>" + opt.pageTitle + "</title>");
// import additional stylesheet(s)
if (opt.loadCSS) {
if ($.isArray(opt.loadCSS)) {
jQuery.each(opt.loadCSS, function(index, value) {
$head.append("<link type='text/css' rel='stylesheet' href='" + this + "'>");
});
} else {
$head.append("<link type='text/css' rel='stylesheet' href='" + opt.loadCSS + "'>");
}
}
var pageHtml = $('html')[0];
// CSS VAR in html tag when dynamic apply e.g. document.documentElement.style.setProperty("--foo", bar);
$doc.find('html').prop('style', pageHtml.style.cssText);
// copy 'root' tag classes
var tag = opt.copyTagClasses;
if (tag) {
tag = tag === true ? 'bh' : tag;
if (tag.indexOf('b') !== -1) {
$body.addClass($('body')[0].className);
}
if (tag.indexOf('h') !== -1) {
$doc.find('html').addClass(pageHtml.className);
}
}
// print header
appendContent($body, opt.header);
if (opt.canvas) {
// add canvas data-ids for easy access after cloning.
var canvasId = 0;
// .addBack('canvas') adds the top-level element if it is a canvas.
$element.find('canvas').addBack('canvas').each(function(){
$(this).attr('data-printthis', canvasId++);
});
}
appendBody($body, $element, opt);
if (opt.canvas) {
// Re-draw new canvases by referencing the originals
$body.find('canvas').each(function(){
var cid = $(this).data('printthis'),
$src = $('[data-printthis="' + cid + '"]');
this.getContext('2d').drawImage($src[0], 0, 0);
// Remove the markup from the original
if ($.isFunction($.fn.removeAttr)) {
$src.removeAttr('data-printthis');
} else {
$.each($src, function(i, el) {
el.removeAttribute('data-printthis')
});
}
});
}
// remove inline styles
if (opt.removeInline) {
// Ensure there is a selector, even if it's been mistakenly removed
var selector = opt.removeInlineSelector || '*';
// $.removeAttr available jQuery 1.7+
if ($.isFunction($.removeAttr)) {
$body.find(selector).removeAttr("style");
} else {
$body.find(selector).attr("style", "");
}
}
// print "footer"
appendContent($body, opt.footer);
// attach event handler function to beforePrint event
function attachOnBeforePrintEvent($iframe, beforePrintHandler) {
var win = $iframe.get(0);
win = win.contentWindow || win.contentDocument || win;
if (typeof beforePrintHandler === "function") {
if ('matchMedia' in win) {
win.matchMedia('print').addListener(function(mql) {
if(mql.matches) beforePrintHandler();
});
} else {
win.onbeforeprint = beforePrintHandler;
}
}
}
attachOnBeforePrintEvent($iframe, opt.beforePrint);
setTimeout(function() {
if ($iframe.hasClass("MSIE")) {
// check if the iframe was created with the ugly hack
// and perform another ugly hack out of neccessity
window.frames["printIframe"].focus();
$head.append("<script> window.print(); </s" + "cript>");
} else {
// proper method
if (document.queryCommandSupported("print")) {
$iframe[0].contentWindow.document.execCommand("print", false, null);
} else {
$iframe[0].contentWindow.focus();
$iframe[0].contentWindow.print();
}
}
// remove iframe after print
if (!opt.debug) {
setTimeout(function() {
$iframe.remove();
}, 1000);
}
// after print callback
if (typeof opt.afterPrint === "function") {
opt.afterPrint();
}
}, opt.printDelay);
}, 333);
};
// defaults
$.fn.printThis.defaults = {
debug: false, // show the iframe for debugging
importCSS: true, // import parent page css
importStyle: false, // import style tags
printContainer: true, // print outer container/$.selector
loadCSS: "", // path to additional css file - use an array [] for multiple
pageTitle: "", // add title to print page
removeInline: false, // remove inline styles from print elements
removeInlineSelector: "*", // custom selectors to filter inline styles. removeInline must be true
printDelay: 333, // variable print delay
header: null, // prefix to html
footer: null, // postfix to html
base: false, // preserve the BASE tag or accept a string for the URL
formValues: true, // preserve input/form values
canvas: false, // copy canvas content
doctypeString: '<!DOCTYPE html>', // enter a different doctype for older markup
removeScripts: false, // remove script tags from print content
copyTagClasses: false, // copy classes from the html & body tag
beforePrintEvent: null, // callback function for printEvent in iframe
beforePrint: null, // function called before iframe is filled
afterPrint: null // function called before iframe is removed
};
})(jQuery);

File diff suppressed because one or more lines are too long

10996
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -2,24 +2,24 @@
"name": "trilium",
"productName": "Trilium Notes",
"description": "Trilium Notes",
"version": "0.62.6",
"version": "0.63.6",
"license": "AGPL-3.0-only",
"main": "electron.js",
"bin": {
"trilium": "./src/www"
"trilium": "src/www.js"
},
"repository": {
"type": "git",
"url": "https://github.com/zadam/trilium.git"
},
"scripts": {
"start-server": "cross-env TRILIUM_SAFE_MODE=1 TRILIUM_DATA_DIR=./data TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 nodemon ./src/www",
"start-server-no-dir": "cross-env TRILIUM_SAFE_MODE=1 TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 nodemon ./src/www",
"qstart-server": "npm run qswitch-server && TRILIUM_SAFE_MODE=1 TRILIUM_DATA_DIR=./data TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 nodemon ./src/www",
"start-server": "cross-env TRILIUM_SAFE_MODE=1 TRILIUM_DATA_DIR=./data TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 nodemon src/www.js",
"start-server-no-dir": "cross-env TRILIUM_SAFE_MODE=1 TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 nodemon src/www.js",
"qstart-server": "npm run qswitch-server && TRILIUM_SAFE_MODE=1 TRILIUM_DATA_DIR=./data TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 nodemon src/www.js",
"start-electron": "cross-env TRILIUM_SAFE_MODE=1 TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev electron --inspect=5858 .",
"start-electron-no-dir": "cross-env TRILIUM_SAFE_MODE=1 TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 electron --inspect=5858 .",
"qstart-electron": "npm run qswitch-electron && TRILIUM_SAFE_MODE=1 TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev electron --inspect=5858 .",
"start-test-server": "npm run qswitch-server; rm -rf ./data-test; cross-env TRILIUM_SAFE_MODE=1 TRILIUM_DATA_DIR=./data-test TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev TRILIUM_PORT=9999 node ./src/www",
"start-test-server": "npm run qswitch-server; rm -rf ./data-test; cross-env TRILIUM_SAFE_MODE=1 TRILIUM_DATA_DIR=./data-test TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev TRILIUM_PORT=9999 node src/www.js",
"switch-server": "rm -rf ./node_modules/better-sqlite3 && npm install",
"switch-electron": "./node_modules/.bin/electron-rebuild",
"qswitch-server": "rm -rf ./node_modules/better-sqlite3/bin ; mkdir -p ./node_modules/better-sqlite3/build ; cp ./bin/better-sqlite3/linux-server-better_sqlite3.node ./node_modules/better-sqlite3/build/better_sqlite3.node",
@ -31,19 +31,18 @@
"test-jasmine": "TRILIUM_DATA_DIR=~/trilium/data-test jasmine",
"test-es6": "node -r esm spec-es6/attribute_parser.spec.js ",
"test": "npm run test-jasmine && npm run test-es6",
"postinstall": "rimraf ./node_modules/canvas",
"lint": "eslint . --cache",
"prepare": "husky install || echo 'Husky install failed, expected on flatpak build'"
"postinstall": "rimraf ./node_modules/canvas"
},
"dependencies": {
"@braintree/sanitize-url": "6.0.4",
"@electron/remote": "2.1.0",
"@excalidraw/excalidraw": "0.16.1",
"archiver": "6.0.1",
"async-mutex": "0.4.0",
"axios": "1.6.2",
"@electron/remote": "2.1.2",
"@excalidraw/excalidraw": "0.17.3",
"archiver": "7.0.0",
"async-mutex": "0.4.1",
"axios": "1.6.7",
"better-sqlite3": "8.4.0",
"chokidar": "3.5.3",
"boxicons": "2.1.4",
"chokidar": "3.6.0",
"cls-hooked": "4.2.2",
"compression": "1.7.4",
"cookie-parser": "1.4.6",
@ -53,33 +52,39 @@
"debounce": "1.2.1",
"ejs": "3.1.9",
"electron-debug": "3.2.0",
"electron-dl": "3.5.1",
"electron-dl": "3.5.2",
"electron-window-state": "5.0.3",
"escape-html": "1.0.3",
"express": "4.18.2",
"express": "4.18.3",
"express-partial-content": "1.0.2",
"express-rate-limit": "7.1.4",
"express-session": "1.17.3",
"fs-extra": "11.1.1",
"express-rate-limit": "7.2.0",
"express-session": "1.18.0",
"force-graph": "1.43.5",
"fs-extra": "11.2.0",
"helmet": "7.1.0",
"html": "1.0.0",
"html2plaintext": "2.1.4",
"http-proxy-agent": "7.0.0",
"https-proxy-agent": "7.0.2",
"http-proxy-agent": "7.0.2",
"https-proxy-agent": "7.0.4",
"image-type": "4.1.0",
"ini": "3.0.1",
"is-animated": "2.0.2",
"is-svg": "4.3.2",
"jimp": "0.22.10",
"jimp": "0.22.12",
"joplin-turndown-plugin-gfm": "1.0.12",
"jsdom": "22.1.0",
"jquery": "3.7.1",
"jquery-hotkeys": "0.2.2",
"jsdom": "24.0.0",
"katex": "0.16.9",
"marked": "9.1.6",
"marked": "12.0.0",
"mermaid": "10.9.0",
"mime-types": "2.1.35",
"multer": "1.4.5-lts.1",
"node-abi": "3.51.0",
"node-abi": "3.56.0",
"normalize-strings": "1.1.1",
"open": "8.4.1",
"panzoom": "9.4.3",
"print-this": "2.0.0",
"rand-token": "1.0.1",
"react": "18.2.0",
"react-dom": "18.2.0",
@ -87,50 +92,38 @@
"rimraf": "5.0.5",
"safe-compare": "1.1.4",
"sanitize-filename": "1.6.3",
"sanitize-html": "2.11.0",
"sanitize-html": "2.12.1",
"sax": "1.3.0",
"semver": "7.5.4",
"semver": "7.6.0",
"serve-favicon": "2.5.0",
"session-file-store": "1.5.0",
"split.js": "1.6.5",
"stream-throttle": "0.1.3",
"striptags": "3.2.0",
"tmp": "0.2.1",
"tree-kill": "^1.2.2",
"tmp": "0.2.3",
"tree-kill": "1.2.2",
"turndown": "7.1.2",
"unescape": "1.0.1",
"ws": "8.14.2",
"ws": "8.16.0",
"xml2js": "0.6.2",
"yauzl": "2.10.0"
"yauzl": "3.1.2"
},
"devDependencies": {
"cross-env": "7.0.3",
"electron": "25.9.8",
"electron-builder": "24.6.4",
"electron-builder": "24.13.3",
"electron-packager": "17.1.2",
"electron-rebuild": "3.2.9",
"eslint": "8.54.0",
"eslint-config-airbnb-base": "15.0.0",
"eslint-config-prettier": "9.0.0",
"eslint-plugin-import": "2.29.0",
"eslint-plugin-jsonc": "2.10.0",
"eslint-plugin-prettier": "5.0.1",
"esm": "3.2.25",
"husky": "8.0.3",
"jasmine": "5.1.0",
"jsdoc": "4.0.2",
"jsonc-eslint-parser": "2.4.0",
"lint-staged": "15.1.0",
"lorem-ipsum": "2.0.8",
"nodemon": "3.0.1",
"prettier": "3.1.0",
"nodemon": "3.1.0",
"rcedit": "4.0.1",
"webpack": "5.89.0",
"webpack": "5.90.3",
"webpack-cli": "5.1.4"
},
"optionalDependencies": {
"electron-installer-debian": "3.2.0"
},
"lint-staged": {
"*.js": "eslint --cache --fix"
}
}

View File

@ -1,7 +1,7 @@
const {
describeEtapi, postEtapi,
putEtapiContent
} = require("../support/etapi");
} = require('../support/etapi.js');
const {getEtapi} = require("../support/etapi.js");
describeEtapi("app_info", () => {

View File

@ -1,7 +1,7 @@
const {
describeEtapi, postEtapi,
getEtapi,
} = require("../support/etapi");
} = require('../support/etapi.js');
const {putEtapiContent} = require("../support/etapi.js");
describeEtapi("backup", () => {

View File

@ -1,7 +1,7 @@
const {
describeEtapi, postEtapi,
postEtapiContent,
} = require("../support/etapi");
} = require('../support/etapi.js');
const fs = require("fs");
const path = require("path");
const {getEtapiContent} = require("../support/etapi.js");

View File

@ -7,7 +7,7 @@ const {
getEtapiContent,
patchEtapi, putEtapi,
putEtapiContent
} = require("../support/etapi");
} = require('../support/etapi.js');
describeEtapi("notes", () => {
it("create", async () => {

View File

@ -1,7 +1,7 @@
const BNote = require('../../src/becca/entities/bnote');
const BBranch = require('../../src/becca/entities/bbranch');
const BAttribute = require('../../src/becca/entities/battribute');
const becca = require('../../src/becca/becca');
const BNote = require('../../src/becca/entities/bnote.js');
const BBranch = require('../../src/becca/entities/bbranch.js');
const BAttribute = require('../../src/becca/entities/battribute.js');
const becca = require('../../src/becca/becca.js');
const randtoken = require('rand-token').generator({source: 'crypto'});
/** @returns {BNote} */

View File

@ -1,4 +1,4 @@
const lex = require('../../src/services/search/services/lex');
const lex = require('../../src/services/search/services/lex.js');
describe("Lexer fulltext", () => {
it("simple lexing", () => {

View File

@ -1,4 +1,4 @@
const handleParens = require('../../src/services/search/services/handle_parens');
const handleParens = require('../../src/services/search/services/handle_parens.js');
describe("Parens handler", () => {
it("handles parens", () => {

View File

@ -1,5 +1,5 @@
const SearchContext = require("../../src/services/search/search_context");
const parse = require('../../src/services/search/services/parse');
const SearchContext = require('../../src/services/search/search_context.js');
const parse = require('../../src/services/search/services/parse.js');
function tokens(toks, cur = 0) {
return toks.map(arg => {

View File

@ -1,10 +1,10 @@
const searchService = require('../../src/services/search/services/search');
const BNote = require('../../src/becca/entities/bnote');
const BBranch = require('../../src/becca/entities/bbranch');
const SearchContext = require('../../src/services/search/search_context');
const dateUtils = require('../../src/services/date_utils');
const becca = require('../../src/becca/becca');
const {NoteBuilder, findNoteByTitle, note} = require('./becca_mocking');
const searchService = require('../../src/services/search/services/search.js');
const BNote = require('../../src/becca/entities/bnote.js');
const BBranch = require('../../src/becca/entities/bbranch.js');
const SearchContext = require('../../src/services/search/search_context.js');
const dateUtils = require('../../src/services/date_utils.js');
const becca = require('../../src/becca/becca.js');
const {NoteBuilder, findNoteByTitle, note} = require('./becca_mocking.js');
describe("Search", () => {
let rootNote;

View File

@ -1,7 +1,7 @@
const {note} = require('./becca_mocking');
const ValueExtractor = require('../../src/services/search/value_extractor');
const becca = require('../../src/becca/becca');
const SearchContext = require("../../src/services/search/search_context");
const {note} = require('./becca_mocking.js');
const ValueExtractor = require('../../src/services/search/value_extractor.js');
const becca = require('../../src/becca/becca.js');
const SearchContext = require('../../src/services/search/search_context.js');
const dsc = new SearchContext();

View File

@ -1,6 +1,6 @@
const anonymizationService = require('./services/anonymization');
const sqlInit = require('./services/sql_init');
require('./becca/entity_constructor');
const anonymizationService = require('./services/anonymization.js');
const sqlInit = require('./services/sql_init.js');
require('./becca/entity_constructor.js');
sqlInit.dbReady.then(async () => {
try {

View File

@ -4,11 +4,11 @@ const favicon = require('serve-favicon');
const cookieParser = require('cookie-parser');
const helmet = require('helmet');
const compression = require('compression');
const sessionParser = require('./routes/session_parser');
const utils = require('./services/utils');
const sessionParser = require('./routes/session_parser.js');
const utils = require('./services/utils.js');
require('./services/handlers');
require('./becca/becca_loader');
require('./services/handlers.js');
require('./becca/becca_loader.js');
const app = express();
@ -37,21 +37,21 @@ app.use(`/robots.txt`, express.static(path.join(__dirname, 'public/robots.txt'))
app.use(sessionParser);
app.use(favicon(`${__dirname}/../images/app-icons/win/icon.ico`));
require('./routes/assets').register(app);
require('./routes/routes').register(app);
require('./routes/custom').register(app);
require('./routes/error_handlers').register(app);
require('./routes/assets.js').register(app);
require('./routes/routes.js').register(app);
require('./routes/custom.js').register(app);
require('./routes/error_handlers.js').register(app);
// triggers sync timer
require('./services/sync');
require('./services/sync.js');
// triggers backup timer
require('./services/backup');
require('./services/backup.js');
// trigger consistency checks timer
require('./services/consistency_checks');
require('./services/consistency_checks.js');
require('./services/scheduler');
require('./services/scheduler.js');
if (utils.isElectron()) {
require('@electron/remote/main').initialize();

View File

@ -1,8 +1,8 @@
"use strict";
const sql = require("../services/sql");
const NoteSet = require("../services/search/note_set");
const NotFoundError = require("../errors/not_found_error");
const sql = require('../services/sql.js');
const NoteSet = require('../services/search/note_set.js');
const NotFoundError = require('../errors/not_found_error.js');
/**
* Becca is a backend cache of all notes, branches, and attributes.
@ -148,7 +148,7 @@ class Becca {
getRevision(revisionId) {
const row = sql.getRow("SELECT * FROM revisions WHERE revisionId = ?", [revisionId]);
const BRevision = require("./entities/brevision"); // avoiding circular dependency problems
const BRevision = require('./entities/brevision.js'); // avoiding circular dependency problems
return row ? new BRevision(row) : null;
}
@ -163,7 +163,7 @@ class Becca {
WHERE attachmentId = ? AND isDeleted = 0`
: `SELECT * FROM attachments WHERE attachmentId = ? AND isDeleted = 0`;
const BAttachment = require("./entities/battachment"); // avoiding circular dependency problems
const BAttachment = require('./entities/battachment.js'); // avoiding circular dependency problems
return sql.getRows(query, [attachmentId])
.map(row => new BAttachment(row))[0];
@ -180,7 +180,7 @@ class Becca {
/** @returns {BAttachment[]} */
getAttachments(attachmentIds) {
const BAttachment = require("./entities/battachment"); // avoiding circular dependency problems
const BAttachment = require('./entities/battachment.js'); // avoiding circular dependency problems
return sql.getManyRows("SELECT * FROM attachments WHERE attachmentId IN (???) AND isDeleted = 0", attachmentIds)
.map(row => new BAttachment(row));
}
@ -189,7 +189,7 @@ class Becca {
getBlob(entity) {
const row = sql.getRow("SELECT *, LENGTH(content) AS contentLength FROM blobs WHERE blobId = ?", [entity.blobId]);
const BBlob = require("./entities/bblob"); // avoiding circular dependency problems
const BBlob = require('./entities/bblob.js'); // avoiding circular dependency problems
return row ? new BBlob(row) : null;
}
@ -238,7 +238,7 @@ class Becca {
getRecentNotesFromQuery(query, params = []) {
const rows = sql.getRows(query, params);
const BRecentNote = require("./entities/brecent_note"); // avoiding circular dependency problems
const BRecentNote = require('./entities/brecent_note.js'); // avoiding circular dependency problems
return rows.map(row => new BRecentNote(row));
}
@ -246,7 +246,7 @@ class Becca {
getRevisionsFromQuery(query, params = []) {
const rows = sql.getRows(query, params);
const BRevision = require("./entities/brevision"); // avoiding circular dependency problems
const BRevision = require('./entities/brevision.js'); // avoiding circular dependency problems
return rows.map(row => new BRevision(row));
}

View File

@ -1,24 +1,24 @@
"use strict";
const sql = require('../services/sql');
const eventService = require('../services/events');
const becca = require('./becca');
const sqlInit = require('../services/sql_init');
const log = require('../services/log');
const BNote = require('./entities/bnote');
const BBranch = require('./entities/bbranch');
const BAttribute = require('./entities/battribute');
const BOption = require('./entities/boption');
const BEtapiToken = require("./entities/betapi_token");
const cls = require("../services/cls");
const entityConstructor = require("../becca/entity_constructor");
const sql = require('../services/sql.js');
const eventService = require('../services/events.js');
const becca = require('./becca.js');
const sqlInit = require('../services/sql_init.js');
const log = require('../services/log.js');
const BNote = require('./entities/bnote.js');
const BBranch = require('./entities/bbranch.js');
const BAttribute = require('./entities/battribute.js');
const BOption = require('./entities/boption.js');
const BEtapiToken = require('./entities/betapi_token.js');
const cls = require('../services/cls.js');
const entityConstructor = require('../becca/entity_constructor.js');
const beccaLoaded = new Promise((res, rej) => {
sqlInit.dbReady.then(() => {
cls.init(() => {
load();
require('../services/options_init').initStartupOptions();
require('../services/options_init.js').initStartupOptions();
res();
});
@ -71,7 +71,7 @@ function load() {
function reload(reason) {
load();
require('../services/ws').reloadFrontend(reason || "becca reloaded");
require('../services/ws.js').reloadFrontend(reason || "becca reloaded");
}
eventService.subscribeBeccaLoader([eventService.ENTITY_CHANGE_SYNCED], ({entityName, entityRow}) => {

View File

@ -1,8 +1,8 @@
"use strict";
const becca = require('./becca');
const cls = require('../services/cls');
const log = require('../services/log');
const becca = require('./becca.js');
const cls = require('../services/cls.js');
const log = require('../services/log.js');
function isNotePathArchived(notePath) {
const noteId = notePath[notePath.length - 1];

View File

@ -1,14 +1,14 @@
"use strict";
const utils = require('../../services/utils');
const sql = require('../../services/sql');
const entityChangesService = require('../../services/entity_changes');
const eventService = require("../../services/events");
const dateUtils = require("../../services/date_utils");
const cls = require("../../services/cls");
const log = require("../../services/log");
const protectedSessionService = require("../../services/protected_session");
const blobService = require("../../services/blob");
const utils = require('../../services/utils.js');
const sql = require('../../services/sql.js');
const entityChangesService = require('../../services/entity_changes.js');
const eventService = require('../../services/events.js');
const dateUtils = require('../../services/date_utils.js');
const cls = require('../../services/cls.js');
const log = require('../../services/log.js');
const protectedSessionService = require('../../services/protected_session.js');
const blobService = require('../../services/blob.js');
let becca = null;
@ -34,7 +34,7 @@ class AbstractBeccaEntity {
*/
get becca() {
if (!becca) {
becca = require('../becca');
becca = require('../becca.js');
}
return becca;

View File

@ -1,14 +1,15 @@
"use strict";
const utils = require('../../services/utils');
const dateUtils = require('../../services/date_utils');
const AbstractBeccaEntity = require("./abstract_becca_entity");
const sql = require("../../services/sql");
const protectedSessionService = require("../../services/protected_session");
const log = require("../../services/log");
const utils = require('../../services/utils.js');
const dateUtils = require('../../services/date_utils.js');
const AbstractBeccaEntity = require('./abstract_becca_entity.js');
const sql = require('../../services/sql.js');
const protectedSessionService = require('../../services/protected_session.js');
const log = require('../../services/log.js');
const attachmentRoleToNoteTypeMapping = {
'image': 'image'
'image': 'image',
'file': 'file'
};
/**
@ -37,7 +38,7 @@ class BAttachment extends AbstractBeccaEntity {
/** @type {string} */
this.attachmentId = row.attachmentId;
/**
/**
* either noteId or revisionId to which this attachment belongs
* @type {string}
*/
@ -153,7 +154,7 @@ class BAttachment extends AbstractBeccaEntity {
throw new Error(`Cannot convert protected attachment outside of protected session`);
}
const noteService = require('../../services/notes');
const noteService = require('../../services/notes.js');
const { note, branch } = noteService.createNewNote({
parentNoteId: this.ownerId,

View File

@ -1,11 +1,11 @@
"use strict";
const BNote = require('./bnote');
const AbstractBeccaEntity = require("./abstract_becca_entity");
const sql = require("../../services/sql");
const dateUtils = require("../../services/date_utils");
const promotedAttributeDefinitionParser = require("../../services/promoted_attribute_definition_parser");
const {sanitizeAttributeName} = require("../../services/sanitize_attribute_name");
const BNote = require('./bnote.js');
const AbstractBeccaEntity = require('./abstract_becca_entity.js');
const sql = require('../../services/sql.js');
const dateUtils = require('../../services/date_utils.js');
const promotedAttributeDefinitionParser = require('../../services/promoted_attribute_definition_parser.js');
const {sanitizeAttributeName} = require('../../services/sanitize_attribute_name.js');
/**

View File

@ -1,12 +1,12 @@
"use strict";
const BNote = require('./bnote');
const AbstractBeccaEntity = require("./abstract_becca_entity");
const dateUtils = require("../../services/date_utils");
const utils = require("../../services/utils");
const TaskContext = require("../../services/task_context");
const cls = require("../../services/cls");
const log = require("../../services/log");
const BNote = require('./bnote.js');
const AbstractBeccaEntity = require('./abstract_becca_entity.js');
const dateUtils = require('../../services/date_utils.js');
const utils = require('../../services/utils.js');
const TaskContext = require('../../services/task_context.js');
const cls = require('../../services/cls.js');
const log = require('../../services/log.js');
/**
* Branch represents a relationship between a child note and its parent note. Trilium allows a note to have multiple
@ -161,7 +161,7 @@ class BBranch extends AbstractBeccaEntity {
if (parentBranches.length === 1 && parentBranches[0] === this) {
// needs to be run before branches and attributes are deleted and thus attached relations disappear
const handlers = require("../../services/handlers");
const handlers = require('../../services/handlers.js');
handlers.runAttachedRelations(note, 'runOnNoteDeletion', note);
}
}

View File

@ -1,7 +1,7 @@
"use strict";
const dateUtils = require('../../services/date_utils');
const AbstractBeccaEntity = require("./abstract_becca_entity");
const dateUtils = require('../../services/date_utils.js');
const AbstractBeccaEntity = require('./abstract_becca_entity.js');
/**
* EtapiToken is an entity representing token used to authenticate against Trilium REST API from client applications.

View File

@ -1,17 +1,17 @@
"use strict";
const protectedSessionService = require('../../services/protected_session');
const log = require('../../services/log');
const sql = require('../../services/sql');
const utils = require('../../services/utils');
const dateUtils = require('../../services/date_utils');
const AbstractBeccaEntity = require("./abstract_becca_entity");
const BRevision = require("./brevision");
const BAttachment = require("./battachment");
const TaskContext = require("../../services/task_context");
const protectedSessionService = require('../../services/protected_session.js');
const log = require('../../services/log.js');
const sql = require('../../services/sql.js');
const utils = require('../../services/utils.js');
const dateUtils = require('../../services/date_utils.js');
const AbstractBeccaEntity = require('./abstract_becca_entity.js');
const BRevision = require('./brevision.js');
const BAttachment = require('./battachment.js');
const TaskContext = require('../../services/task_context.js');
const dayjs = require("dayjs");
const utc = require('dayjs/plugin/utc');
const eventService = require("../../services/events");
const eventService = require('../../services/events.js');
dayjs.extend(utc);
const LABEL = 'label';
@ -903,7 +903,7 @@ class BNote extends AbstractBeccaEntity {
}
try {
const searchService = require("../../services/search/services/search");
const searchService = require('../../services/search/services/search.js');
const {searchResultNoteIds} = searchService.searchFromNote(this);
const becca = this.becca;
@ -1303,7 +1303,7 @@ class BNote extends AbstractBeccaEntity {
}
}
else {
const BAttribute = require("./battribute");
const BAttribute = require('./battribute.js');
new BAttribute({
noteId: this.noteId,
@ -1343,7 +1343,7 @@ class BNote extends AbstractBeccaEntity {
* @returns {BAttribute}
*/
addAttribute(type, name, value = "", isInheritable = false, position = null) {
const BAttribute = require("./battribute");
const BAttribute = require('./battribute.js');
return new BAttribute({
noteId: this.noteId,
@ -1448,7 +1448,7 @@ class BNote extends AbstractBeccaEntity {
removeRelation(name, value) { return this.removeAttribute(RELATION, name, value); }
searchNotesInSubtree(searchString) {
const searchService = require("../../services/search/services/search");
const searchService = require('../../services/search/services/search.js');
return searchService.searchNotes(searchString);
}
@ -1462,7 +1462,7 @@ class BNote extends AbstractBeccaEntity {
* @returns {{success: boolean, message: string, branchId: string, notePath: string}}
*/
cloneTo(parentNoteId) {
const cloningService = require("../../services/cloning");
const cloningService = require('../../services/cloning.js');
const branch = this.becca.getNote(parentNoteId).getParentBranches()[0];
@ -1537,7 +1537,7 @@ class BNote extends AbstractBeccaEntity {
parentNote.setContent(fixedContent);
const noteService = require("../../services/notes");
const noteService = require('../../services/notes.js');
noteService.asyncPostProcessContent(parentNote, fixedContent); // to mark an unused attachment for deletion
this.deleteNote();
@ -1565,7 +1565,7 @@ class BNote extends AbstractBeccaEntity {
}
// needs to be run before branches and attributes are deleted and thus attached relations disappear
const handlers = require("../../services/handlers");
const handlers = require('../../services/handlers.js');
handlers.runAttachedRelations(this, 'runOnNoteDeletion', this);
taskContext.noteDeletionHandlerTriggered = true;

View File

@ -1,7 +1,7 @@
"use strict";
const dateUtils = require('../../services/date_utils');
const AbstractBeccaEntity = require("./abstract_becca_entity");
const dateUtils = require('../../services/date_utils.js');
const AbstractBeccaEntity = require('./abstract_becca_entity.js');
/**
* Option represents a name-value pair, either directly configurable by the user or some system property.

View File

@ -1,7 +1,7 @@
"use strict";
const dateUtils = require('../../services/date_utils');
const AbstractBeccaEntity = require("./abstract_becca_entity");
const dateUtils = require('../../services/date_utils.js');
const AbstractBeccaEntity = require('./abstract_becca_entity.js');
/**
* RecentNote represents recently visited note.

View File

@ -1,12 +1,12 @@
"use strict";
const protectedSessionService = require('../../services/protected_session');
const utils = require('../../services/utils');
const dateUtils = require('../../services/date_utils');
const becca = require('../becca');
const AbstractBeccaEntity = require("./abstract_becca_entity");
const sql = require("../../services/sql");
const BAttachment = require("./battachment");
const protectedSessionService = require('../../services/protected_session.js');
const utils = require('../../services/utils.js');
const dateUtils = require('../../services/date_utils.js');
const becca = require('../becca.js');
const AbstractBeccaEntity = require('./abstract_becca_entity.js');
const sql = require('../../services/sql.js');
const BAttachment = require('./battachment.js');
/**
* Revision represents a snapshot of note's title and content at some point in the past.
@ -161,6 +161,13 @@ class BRevision extends AbstractBeccaEntity {
return this.getAttachments().filter(attachment => attachment.title === title)[0];
}
/**
* Revisions are not soft-deletable, they are immediately hard-deleted (erased).
*/
eraseRevision() {
require("../../services/erase.js").eraseRevisions([this.revisionId]);
}
beforeSaving() {
super.beforeSaving();

View File

@ -1,12 +1,12 @@
const BAttachment = require("./entities/battachment");
const BAttribute = require('./entities/battribute');
const BBlob = require("./entities/bblob");
const BBranch = require('./entities/bbranch');
const BEtapiToken = require('./entities/betapi_token');
const BNote = require('./entities/bnote');
const BOption = require('./entities/boption');
const BRecentNote = require('./entities/brecent_note');
const BRevision = require('./entities/brevision');
const BAttachment = require('./entities/battachment.js');
const BAttribute = require('./entities/battribute.js');
const BBlob = require('./entities/bblob.js');
const BBranch = require('./entities/bbranch.js');
const BEtapiToken = require('./entities/betapi_token.js');
const BNote = require('./entities/bnote.js');
const BOption = require('./entities/boption.js');
const BRecentNote = require('./entities/brecent_note.js');
const BRevision = require('./entities/brevision.js');
const ENTITY_NAME_TO_ENTITY = {
"attachments": BAttachment,

View File

@ -1,7 +1,7 @@
const becca = require('./becca');
const log = require('../services/log');
const beccaService = require('./becca_service');
const dateUtils = require('../services/date_utils');
const becca = require('./becca.js');
const log = require('../services/log.js');
const beccaService = require('./becca_service.js');
const dateUtils = require('../services/date_utils.js');
const {JSDOM} = require("jsdom");
const DEBUG = false;
@ -35,7 +35,7 @@ const IGNORED_ATTR_NAMES = [
function filterUrlValue(value) {
return value
.replace(/https?:\/\//ig, "")
.replace(/www\./ig, "")
.replace(/www.js\./ig, "")
.replace(/(\.net|\.com|\.org|\.info|\.edu)/ig, "");
}

View File

@ -1,5 +1,5 @@
const appInfo = require('../services/app_info');
const eu = require("./etapi_utils");
const appInfo = require('../services/app_info.js');
const eu = require('./etapi_utils.js');
function register(router) {
eu.route(router, 'get', '/etapi/app-info', (req, res, next) => {

View File

@ -1,8 +1,8 @@
const becca = require("../becca/becca");
const eu = require("./etapi_utils");
const mappers = require("./mappers");
const v = require("./validators");
const utils = require("../services/utils");
const becca = require('../becca/becca.js');
const eu = require('./etapi_utils.js');
const mappers = require('./mappers.js');
const v = require('./validators.js');
const utils = require('../services/utils.js');
function register(router) {
const ALLOWED_PROPERTIES_FOR_CREATE_ATTACHMENT = {

View File

@ -1,8 +1,8 @@
const becca = require("../becca/becca");
const eu = require("./etapi_utils");
const mappers = require("./mappers");
const attributeService = require("../services/attributes");
const v = require("./validators");
const becca = require('../becca/becca.js');
const eu = require('./etapi_utils.js');
const mappers = require('./mappers.js');
const attributeService = require('../services/attributes.js');
const v = require('./validators.js');
function register(router) {
eu.route(router, 'get', '/etapi/attributes/:attributeId', (req, res, next) => {

View File

@ -1,7 +1,7 @@
const becca = require("../becca/becca");
const eu = require("./etapi_utils");
const passwordEncryptionService = require("../services/encryption/password_encryption");
const etapiTokenService = require("../services/etapi_tokens");
const becca = require('../becca/becca.js');
const eu = require('./etapi_utils.js');
const passwordEncryptionService = require('../services/encryption/password_encryption.js');
const etapiTokenService = require('../services/etapi_tokens.js');
function register(router, loginMiddleware) {
eu.NOT_AUTHENTICATED_ROUTE(router, 'post', '/etapi/auth/login', loginMiddleware, (req, res, next) => {

View File

@ -1,5 +1,5 @@
const eu = require("./etapi_utils");
const backupService = require("../services/backup");
const eu = require('./etapi_utils.js');
const backupService = require('../services/backup.js');
function register(router) {
eu.route(router, 'put', '/etapi/backup/:backupName', async (req, res, next) => {

View File

@ -1,9 +1,9 @@
const becca = require("../becca/becca");
const eu = require("./etapi_utils");
const mappers = require("./mappers");
const BBranch = require("../becca/entities/bbranch");
const entityChangesService = require("../services/entity_changes");
const v = require("./validators");
const becca = require('../becca/becca.js');
const eu = require('./etapi_utils.js');
const mappers = require('./mappers.js');
const BBranch = require('../becca/entities/bbranch.js');
const entityChangesService = require('../services/entity_changes.js');
const v = require('./validators.js');
function register(router) {
eu.route(router, 'get', '/etapi/branches/:branchId', (req, res, next) => {

View File

@ -1,9 +1,9 @@
const cls = require("../services/cls");
const sql = require("../services/sql");
const log = require("../services/log");
const becca = require("../becca/becca");
const etapiTokenService = require("../services/etapi_tokens");
const config = require("../services/config");
const cls = require('../services/cls.js');
const sql = require('../services/sql.js');
const log = require('../services/log.js');
const becca = require('../becca/becca.js');
const etapiTokenService = require('../services/etapi_tokens.js');
const config = require('../services/config.js');
const GENERIC_CODE = "GENERIC";
const noAuthentication = config.General && config.General.noAuthentication === true;

View File

@ -1,14 +1,14 @@
const becca = require("../becca/becca");
const utils = require("../services/utils");
const eu = require("./etapi_utils");
const mappers = require("./mappers");
const noteService = require("../services/notes");
const TaskContext = require("../services/task_context");
const v = require("./validators");
const searchService = require("../services/search/services/search");
const SearchContext = require("../services/search/search_context");
const zipExportService = require("../services/export/zip");
const zipImportService = require("../services/import/zip");
const becca = require('../becca/becca.js');
const utils = require('../services/utils.js');
const eu = require('./etapi_utils.js');
const mappers = require('./mappers.js');
const noteService = require('../services/notes.js');
const TaskContext = require('../services/task_context.js');
const v = require('./validators.js');
const searchService = require('../services/search/services/search.js');
const SearchContext = require('../services/search/search_context.js');
const zipExportService = require('../services/export/zip.js');
const zipImportService = require('../services/import/zip.js');
function register(router) {
eu.route(router, 'get', '/etapi/notes', (req, res, next) => {

View File

@ -1,7 +1,7 @@
const specialNotesService = require("../services/special_notes");
const dateNotesService = require("../services/date_notes");
const eu = require("./etapi_utils");
const mappers = require("./mappers");
const specialNotesService = require('../services/special_notes.js');
const dateNotesService = require('../services/date_notes.js');
const eu = require('./etapi_utils.js');
const mappers = require('./mappers.js');
const getDateInvalidError = date => new eu.EtapiError(400, "DATE_INVALID", `Date "${date}" is not valid.`);
const getMonthInvalidError = month => new eu.EtapiError(400, "MONTH_INVALID", `Month "${month}" is not valid.`);
@ -74,4 +74,4 @@ function register(router) {
module.exports = {
register
};
};

View File

@ -1,5 +1,5 @@
const noteTypeService = require("../services/note_types");
const dateUtils = require("../services/date_utils");
const noteTypeService = require('../services/note_types.js');
const dateUtils = require('../services/date_utils.js');
function mandatory(obj) {
if (obj === undefined ) {
@ -64,7 +64,7 @@ function isNoteId(obj) {
return;
}
const becca = require('../becca/becca');
const becca = require('../becca/becca.js');
if (typeof obj !== 'string') {
return `'${obj}' is not a valid noteId`;

View File

@ -0,0 +1,44 @@
import utils from "../services/utils.js";
import contextMenu from "./context_menu.js";
import imageService from "../services/image.js";
const PROP_NAME = "imageContextMenuInstalled";
function setupContextMenu($image) {
if (!utils.isElectron() || $image.prop(PROP_NAME)) {
return;
}
$image.prop(PROP_NAME, true);
$image.on('contextmenu', e => {
e.preventDefault();
contextMenu.show({
x: e.pageX,
y: e.pageY,
items: [
{
title: "Copy reference to clipboard",
command: "copyImageReferenceToClipboard",
uiIcon: "bx bx-empty"
},
{title: "Copy image to clipboard", command: "copyImageToClipboard", uiIcon: "bx bx-empty"},
],
selectMenuItemHandler: ({command}) => {
if (command === 'copyImageReferenceToClipboard') {
imageService.copyImageReferenceToClipboard($image);
} else if (command === 'copyImageToClipboard') {
const webContents = utils.dynamicRequire('@electron/remote').getCurrentWebContents();
utils.dynamicRequire('electron');
webContents.copyImageAt(e.pageX, e.pageY);
} else {
throw new Error(`Unrecognized command '${command}'`);
}
}
});
});
}
export default {
setupContextMenu
};

View File

@ -107,6 +107,13 @@ async function deleteNotes(branchIdsToDelete, forceDeleteAllClones = false) {
return false;
}
try {
await activateParentNotePath();
}
catch (e) {
console.error(e);
}
const taskId = utils.randomString(10);
let counter = 0;
@ -134,6 +141,16 @@ async function deleteNotes(branchIdsToDelete, forceDeleteAllClones = false) {
return true;
}
async function activateParentNotePath() {
// this is not perfect, maybe we should find the next/previous sibling, but that's more complex
const activeContext = appContext.tabManager.getActiveContext();
const parentNotePathArr = activeContext.notePathArray.slice(0, -1);
if (parentNotePathArr.length > 0) {
activeContext.setNote(parentNotePathArr.join("/"));
}
}
async function moveNodeUpInHierarchy(node) {
if (hoistedNoteService.isHoistedNode(node)
|| hoistedNoteService.isTopLevelNode(node)

View File

@ -9,6 +9,7 @@ import linkService from "./link.js";
import treeService from "./tree.js";
import FNote from "../entities/fnote.js";
import FAttachment from "../entities/fattachment.js";
import imageContextMenuService from "../menus/image_context_menu.js";
let idCounter = 1;
@ -148,6 +149,8 @@ function renderImage(entity, $renderedContent, options = {}) {
});
});
}
imageContextMenuService.setupContextMenu($img);
}
function renderFile(entity, type, $renderedContent) {

View File

@ -48,11 +48,11 @@ async function checkNoteAccess(notePath, noteContext) {
const hoistedNoteId = noteContext.hoistedNoteId;
if (!resolvedNotePath.includes(hoistedNoteId) && !resolvedNotePath.includes('_hidden')) {
if (!resolvedNotePath.includes(hoistedNoteId) && (!resolvedNotePath.includes('_hidden') || resolvedNotePath.includes('_lbBookmarks'))) {
const requestedNote = await froca.getNote(treeService.getNoteIdFromUrl(resolvedNotePath));
const hoistedNote = await froca.getNote(hoistedNoteId);
if (!hoistedNote.hasAncestor('_hidden')
if ((!hoistedNote.hasAncestor('_hidden') || resolvedNotePath.includes('_lbBookmarks'))
&& !await dialogService.confirm(`Requested note '${requestedNote.title}' is outside of hoisted note '${hoistedNote.title}' subtree and you must unhoist to access the note. Do you want to proceed with unhoisting?`)) {
return false;
}

View File

@ -28,14 +28,14 @@ const ESLINT = {js: ["libraries/eslint.js"]};
const RELATION_MAP = {
js: [
"libraries/jsplumb.js",
"libraries/panzoom.js"
"node_modules/panzoom/dist/panzoom.min.js"
],
css: [
"stylesheets/relation_map.css"
]
};
const PRINT_THIS = {js: ["libraries/printThis.js"]};
const PRINT_THIS = {js: ["node_modules/print-this/printThis.js"]};
const CALENDAR_WIDGET = {css: ["stylesheets/calendar.css"]};
@ -51,11 +51,11 @@ const WHEEL_ZOOM = {
};
const FORCE_GRAPH = {
js: [ "libraries/force-graph.min.js"]
js: [ "node_modules/force-graph/dist/force-graph.min.js"]
};
const MERMAID = {
js: [ "libraries/mermaid.min.js" ]
js: [ "node_modules/mermaid/dist/mermaid.min.js" ]
}
const EXCALIDRAW = {

View File

@ -4,6 +4,7 @@ import froca from "./froca.js";
import attributeRenderer from "./attribute_renderer.js";
import libraryLoader from "./library_loader.js";
import treeService from "./tree.js";
import utils from "./utils.js";
const TPL = `
<div class="note-list">
@ -215,7 +216,11 @@ class NoteListRenderer {
if (highlightedTokens.length > 0) {
await libraryLoader.requireLibrary(libraryLoader.MARKJS);
this.highlightRegex = new RegExp(highlightedTokens.join("|"), 'gi');
const regex = highlightedTokens
.map(token => utils.escapeRegExp(token))
.join("|");
this.highlightRegex = new RegExp(regex, 'gi');
} else {
this.highlightRegex = null;
}

View File

@ -487,12 +487,14 @@ function areObjectsEqual () {
}
function copyHtmlToClipboard(content) {
const clipboardItem = new ClipboardItem({
'text/html': new Blob([content], {type: 'text/html'}),
'text/plain': new Blob([content], {type: 'text/plain'})
});
navigator.clipboard.write([clipboardItem]);
function listener(e) {
e.clipboardData.setData("text/html", content);
e.clipboardData.setData("text/plain", content);
e.preventDefault();
}
document.addEventListener("copy", listener);
document.execCommand("copy");
document.removeEventListener("copy", listener);
}
/**

View File

@ -200,7 +200,7 @@ export default class AttributeEditorWidget extends NoteContextAwareWidget {
this.attributeDetailWidget.hide();
});
this.$editor.on('blur', () => this.save());
this.$editor.on('blur', () => setTimeout(() => this.save(), 100)); // Timeout to fix https://github.com/zadam/trilium/issues/4160
this.$addNewAttributeButton = this.$widget.find('.add-new-attribute-button');
this.$addNewAttributeButton.on('click', e => this.addNewAttribute(e));

View File

@ -8,10 +8,13 @@ export default class RightPaneContainer extends FlexContainer {
this.id('right-pane');
this.css('height', '100%');
this.collapsible();
this.rightPaneHidden = false;
}
isEnabled() {
return super.isEnabled()
&& !this.rightPaneHidden
&& this.children.length > 0
&& !!this.children.find(ch => ch.isEnabled() && ch.canBeShown());
}
@ -44,4 +47,10 @@ export default class RightPaneContainer extends FlexContainer {
splitService.setupRightPaneResizer();
}
}
toggleRightPaneEvent() {
this.rightPaneHidden = !this.rightPaneHidden;
this.reEvaluateRightPaneVisibilityCommand();
}
}

View File

@ -1091,7 +1091,9 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
return;
}
const nodeCtx = this.#getActiveNodeCtx();
const activeNode = this.getActiveNode();
const activeNodeFocused = activeNode?.hasFocus();
const activeNotePath = activeNode ? treeService.getNotePath(activeNode) : null;
const refreshCtx = {
noteIdsToUpdate: new Set(),
@ -1108,7 +1110,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
await this.#executeTreeUpdates(refreshCtx, loadResults);
await this.#setActiveNode(nodeCtx, movedActiveNode, parentsOfAddedNodes);
await this.#setActiveNode(activeNotePath, activeNodeFocused, movedActiveNode, parentsOfAddedNodes);
if (refreshCtx.noteIdsToReload.size > 0 || refreshCtx.noteIdsToUpdate.size > 0) {
// workaround for https://github.com/mar10/fancytree/issues/1054
@ -1257,73 +1259,42 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
}
}
#getActiveNodeCtx() {
const nodeCtx = {
activeNotePath: null,
activeNodeFocused: null,
nextNotePath: null
};
const activeNode = this.getActiveNode();
nodeCtx.activeNodeFocused = activeNode?.hasFocus();
nodeCtx.activeNotePath = activeNode ? treeService.getNotePath(activeNode) : null;
const nextNode = activeNode ? (activeNode.getNextSibling() || activeNode.getPrevSibling() || activeNode.getParent()) : null;
nodeCtx.nextNotePath = nextNode ? treeService.getNotePath(nextNode) : null;
return nodeCtx;
}
async #setActiveNode(nodeCtx, movedActiveNode, parentsOfAddedNodes) {
async #setActiveNode(activeNotePath, activeNodeFocused, movedActiveNode, parentsOfAddedNodes) {
if (movedActiveNode) {
for (const parentNode of parentsOfAddedNodes) {
const foundNode = (parentNode.getChildren() || []).find(child => child.data.noteId === movedActiveNode.data.noteId);
if (foundNode) {
nodeCtx.activeNotePath = treeService.getNotePath(foundNode);
activeNotePath = treeService.getNotePath(foundNode);
break;
}
}
}
if (!nodeCtx.activeNotePath) {
if (!activeNotePath) {
return;
}
let node = await this.expandToNote(nodeCtx.activeNotePath, false);
if (node && node.data.noteId !== treeService.getNoteIdFromUrl(nodeCtx.activeNotePath)) {
let node = await this.expandToNote(activeNotePath, false);
if (node && node.data.noteId !== treeService.getNoteIdFromUrl(activeNotePath)) {
// if the active note has been moved elsewhere then it won't be found by the path,
// so we switch to the alternative of trying to find it by noteId
const notesById = this.getNodesByNoteId(treeService.getNoteIdFromUrl(nodeCtx.activeNotePath));
const notesById = this.getNodesByNoteId(treeService.getNoteIdFromUrl(activeNotePath));
// if there are multiple clones, then we'd rather not activate anyone
node = notesById.length === 1 ? notesById[0] : null;
}
if (node) {
if (nodeCtx.activeNodeFocused) {
// needed by Firefox: https://github.com/zadam/trilium/issues/1865
this.tree.$container.focus();
}
await node.setActive(true, {noEvents: true, noFocus: !nodeCtx.activeNodeFocused});
} else {
// this is used when the original note has been deleted, and we want to move the focus to the note above/below
node = await this.expandToNote(nodeCtx.nextNotePath, false);
if (node) {
// FIXME: this is conceptually wrong
// here note tree is responsible for updating global state of the application
// this should be done by NoteContext / TabManager and note tree should only listen to
// changes in active note and just set the "active" state
// We don't await since that can bring up infinite cycles when e.g. custom widget does some backend requests which wait for max sync ID processed
appContext.tabManager.getActiveContext().setNote(nodeCtx.nextNotePath).then(() => {
const newActiveNode = this.getActiveNode();
// return focus if the previously active node was also focused
if (newActiveNode && nodeCtx.activeNodeFocused) {
newActiveNode.setFocus(true);
}
});
}
if (!node) {
return;
}
if (activeNodeFocused) {
// needed by Firefox: https://github.com/zadam/trilium/issues/1865
this.tree.$container.focus();
}
await node.setActive(true, {noEvents: true, noFocus: !activeNodeFocused});
}
sortChildren(node) {

Some files were not shown because too many files have changed in this diff Show More