From d3ec9f022c6aecaa95caa2cc5691bc6235c50f01 Mon Sep 17 00:00:00 2001 From: Nriver <6752679+Nriver@users.noreply.github.com> Date: Fri, 10 Mar 2023 14:35:36 +0800 Subject: [PATCH 01/46] add natural sort for notes, introduce new label #sortNatural --- .../app/widgets/dialogs/sort_child_notes.js | 14 +++++++++++++- src/routes/api/notes.js | 6 +++--- src/services/builtin_attributes.js | 1 + src/services/handlers.js | 4 ++-- src/services/tree.js | 16 ++++++++++++---- 5 files changed, 31 insertions(+), 10 deletions(-) diff --git a/src/public/app/widgets/dialogs/sort_child_notes.js b/src/public/app/widgets/dialogs/sort_child_notes.js index 65440efe4..ccb12544a 100644 --- a/src/public/app/widgets/dialogs/sort_child_notes.js +++ b/src/public/app/widgets/dialogs/sort_child_notes.js @@ -65,6 +65,17 @@ const TPL = ` + +
+ +
Natural Sort
+ +
+ +
`; From cd72ea524e52290181195ceb01c20bb57da29b6d Mon Sep 17 00:00:00 2001 From: zadam Date: Thu, 23 Mar 2023 23:47:28 +0100 Subject: [PATCH 08/46] promoted and inherited attributes should be shown grouped based on the owning note, #3761 --- src/public/app/entities/fnote.js | 9 ++++++++- .../ribbon_widgets/inherited_attribute_list.js | 13 ++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/public/app/entities/fnote.js b/src/public/app/entities/fnote.js index 1f44a97bf..70594d647 100644 --- a/src/public/app/entities/fnote.js +++ b/src/public/app/entities/fnote.js @@ -706,7 +706,14 @@ class FNote { }); // attrs are not resorted if position changes after initial load - promotedAttrs.sort((a, b) => a.position < b.position ? -1 : 1); + promotedAttrs.sort((a, b) => { + if (a.noteId === b.noteId) { + return a.position < b.position ? -1 : 1; + } else { + // inherited promoted attributes should stay grouped: https://github.com/zadam/trilium/issues/3761 + return a.noteId < b.noteId ? -1 : 1; + } + }); return promotedAttrs; } diff --git a/src/public/app/widgets/ribbon_widgets/inherited_attribute_list.js b/src/public/app/widgets/ribbon_widgets/inherited_attribute_list.js index e434c20a6..01031686e 100644 --- a/src/public/app/widgets/ribbon_widgets/inherited_attribute_list.js +++ b/src/public/app/widgets/ribbon_widgets/inherited_attribute_list.js @@ -92,7 +92,18 @@ export default class InheritedAttributesWidget extends NoteContextAwareWidget { } getInheritedAttributes(note) { - return note.getAttributes().filter(attr => attr.noteId !== this.noteId); + const attrs = note.getAttributes().filter(attr => attr.noteId !== this.noteId); + + attrs.sort((a, b) => { + if (a.noteId === b.noteId) { + return a.position < b.position ? -1 : 1; + } else { + // inherited attributes should stay grouped: https://github.com/zadam/trilium/issues/3761 + return a.noteId < b.noteId ? -1 : 1; + } + }); + + return attrs; } entitiesReloadedEvent({loadResults}) { From 874b6c71a306accf5433fa90076f43a657042e8a Mon Sep 17 00:00:00 2001 From: MeIchthys <10717998+meichthys@users.noreply.github.com> Date: Fri, 24 Mar 2023 11:29:16 -0400 Subject: [PATCH 09/46] Add bottom border to note-book-header --- src/public/app/services/note_list_renderer.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/public/app/services/note_list_renderer.js b/src/public/app/services/note_list_renderer.js index 72e79ae24..b22fdc827 100644 --- a/src/public/app/services/note_list_renderer.js +++ b/src/public/app/services/note_list_renderer.js @@ -62,7 +62,9 @@ const TPL = ` } .note-book-header { + border-bottom: 1px solid var(--main-border-color); margin-bottom: 0; + padding-bottom: .5rem; word-break: break-all; } From fa6d1879ddeda9d690da52ecddb5ff3c2d4393fb Mon Sep 17 00:00:00 2001 From: MeIchthys <10717998+meichthys@users.noreply.github.com> Date: Fri, 24 Mar 2023 14:46:09 -0400 Subject: [PATCH 10/46] Move .tree-actions left to accomodate wider windows scrollbar --- src/public/app/widgets/note_tree.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/public/app/widgets/note_tree.js b/src/public/app/widgets/note_tree.js index 43d2ee8f8..b9974676f 100644 --- a/src/public/app/widgets/note_tree.js +++ b/src/public/app/widgets/note_tree.js @@ -49,7 +49,7 @@ const TPL = ` display: flex; align-items: flex-end; justify-content: flex-end; - right: 11.77px; + right: 17px; } button.tree-floating-button { From 8a4caaf6fb6f0e12d049ed86b65812c7ee50f5b0 Mon Sep 17 00:00:00 2001 From: MeIchthys <10717998+meichthys@users.noreply.github.com> Date: Fri, 24 Mar 2023 15:17:17 -0400 Subject: [PATCH 11/46] Add border to tree-actions section and adjust padding --- src/public/app/widgets/note_tree.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/public/app/widgets/note_tree.js b/src/public/app/widgets/note_tree.js index b9974676f..7837672d2 100644 --- a/src/public/app/widgets/note_tree.js +++ b/src/public/app/widgets/note_tree.js @@ -41,7 +41,6 @@ const TPL = ` } .tree-actions { - padding: 4px 0; background-color: var(--launcher-pane-background-color); z-index: 100; position: absolute; @@ -50,12 +49,14 @@ const TPL = ` align-items: flex-end; justify-content: flex-end; right: 17px; + border-radius: 7px; + border: 1px solid var(--main-border-color); } button.tree-floating-button { + margin: 1px; font-size: 1.5em; padding: 5px; - margin-right: 5px; max-height: 34px; color: var(--launcher-pane-text-color); background-color: var(--button-background-color); From 6d6221636c4e68f58092120ef63ea79757d16b65 Mon Sep 17 00:00:00 2001 From: Ikko Eltociear Ashimine Date: Sun, 26 Mar 2023 20:25:17 +0900 Subject: [PATCH 12/46] Add Japanese README --- README.ja.md | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 README.ja.md diff --git a/README.ja.md b/README.ja.md new file mode 100644 index 000000000..d5285722c --- /dev/null +++ b/README.ja.md @@ -0,0 +1,83 @@ +# 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 Notes は、大規模な個人知識ベースの構築に焦点を当てた、階層型ノートアプリケーションです。概要は[スクリーンショット](https://github.com/zadam/trilium/wiki/Screenshot-tour)をご覧ください: + +Trilium Screenshot + +ウクライナは現在、ロシアの侵略から自国を守っています。[ウクライナ軍や人道的な慈善団体への寄付](https://standforukraine.com/)をご検討ください。 + +

+ drawing + Trilium Notes supports Ukraine! +

+ +## 🎁 特徴 + +* ノートは、任意の深さのツリーに配置できます。単一のノートをツリー内の複数の場所に配置できます ([cloning](https://github.com/zadam/trilium/wiki/Cloning-notes) を参照) +* マークダウン[オートフォーマット](https://github.com/zadam/trilium/wiki/Text-notes#autoformat)による、表、画像、[数学](https://github.com/zadam/trilium/wiki/Text-notes#math-support)などの豊富な WYSIWYG ノート編集機能 +* シンタックスハイライトを含む[ソースコード付きノート](https://github.com/zadam/trilium/wiki/Code-notes)の編集をサポート +* [ノート間のナビゲーション](https://github.com/zadam/trilium/wiki/Note-navigation)、全文検索、[ノートホイスト](https://github.com/zadam/trilium/wiki/Note-hoisting)が高速かつ簡単に行えます +* シームレスな[ノートのバージョン管理](https://github.com/zadam/trilium/wiki/Note-revisions) +* ノート[属性](https://github.com/zadam/trilium/wiki/Attributes)は、ノート整理、クエリ、高度な[スクリプト](https://github.com/zadam/trilium/wiki/Scripts)に使用できます +* 自己ホスト型同期サーバーとの[同期](https://github.com/zadam/trilium/wiki/Synchronization) + * [同期サーバーをホストするサードパーティ・サービス](https://trilium.cc/paid-hosting)があります +* 公開インターネットへのノートの[共有](https://github.com/zadam/trilium/wiki/Sharing)(公開) +* ノートごとの粒度を持つ強力な[ノート暗号化](https://github.com/zadam/trilium/wiki/Protected-notes) +* 組み込みの Excalidraw を使用した図のスケッチ (ノート タイプ"キャンバス") +* ノートとその関係を可視化するための[関係図](https://github.com/zadam/trilium/wiki/Relation-map)と[リンクマップ](https://github.com/zadam/trilium/wiki/Link-map) +* [スクリプティング](https://github.com/zadam/trilium/wiki/Scripts) - [高度なショーケース](https://github.com/zadam/trilium/wiki/Advanced-showcases)を参照 +* 自動化のための [REST API](https://github.com/zadam/trilium/wiki/ETAPI) +* ユーザビリティとパフォーマンスの両方で 100 000 ノート以上に拡張可能 +* スマートフォンとタブレット向けのタッチ最適化[モバイルフロントエンド](https://github.com/zadam/trilium/wiki/Mobile-frontend) +* [ナイトテーマ](https://github.com/zadam/trilium/wiki/Themes) +* [Evernote](https://github.com/zadam/trilium/wiki/Evernote-import) と [Markdown のインポートとエクスポート](https://github.com/zadam/trilium/wiki/Markdown) +* Web コンテンツを簡単に保存するための [Web クリッパー](https://github.com/zadam/trilium/wiki/Web-clipper) + +サードパーティのテーマ、スクリプト、プラグインなどは、 [awesome-trilium](https://github.com/Nriver/awesome-trilium) をチェックしてください。 + +## 🏗 ビルド + +Trilium は、デスクトップアプリケーション(Linux、Windows)またはサーバー上でホストされるウェブアプリケーション(Linux)として提供されます。 Mac OS のデスクトップビルドも利用可能ですが、 [unsupported](https://github.com/zadam/trilium/wiki/FAQ#mac-os-support) となっています。 + +* デスクトップで Trilium を使用したい場合は、 [latest release](https://github.com/zadam/trilium/releases/latest) からお使いのプラットフォームのバイナリリリースをダウンロードし、パッケージを解凍して ``trilium`` の実行ファイルを実行してください。 +* サーバーに Trilium をインストールする場合は、[このページ](https://github.com/zadam/trilium/wiki/Server-installation)に従ってください。 + * 現在、対応(動作確認)しているブラウザは、最近の Chrome と Firefox のみです。 + +Trilium は Flatpak としても提供されます: + +[](https://flathub.org/apps/details/com.github.zadam.trilium) + +## 📝 ドキュメント + +[ドキュメントページの全リストはwikiをご覧ください。](https://github.com/zadam/trilium/wiki/) + +また、[個人的な知識基盤のパターン](https://github.com/zadam/trilium/wiki/Patterns-of-personal-knowledge-base)を読むと、 Trilium の使い方のヒントを得ることができます。 + +## 💻 コントリビュート + +ブラウザベースの開発環境を使用 + +[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/zadam/trilium) + +または、ローカルにクローンして実行 +``` +npm install +npm run start-server +``` + +## 📢 シャウトアウト + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - 市場で最高の WYSIWYG エディター、非常にインタラクティブで聞き上手なチーム +* [FancyTree](https://github.com/mar10/fancytree) - 真の競争相手がいない、非常に機能豊富なツリーライブラリです。 Trilium Notes は、これなしでは成り立たないでしょう。 +* [CodeMirror](https://github.com/codemirror/CodeMirror) - 膨大な数の言語をサポートするコードエディタ +* [jsPlumb](https://github.com/jsplumb/jsplumb) - 競合のないビジュアルコネクティビティライブラリです。[関係図](https://github.com/zadam/trilium/wiki/Relation-map)、[リンク図](https://github.com/zadam/trilium/wiki/Link-map)で使用。 + +## 🤝 サポート + +GitHub スポンサー、[PayPal](https://paypal.me/za4am)もしくは Bitcoin (bitcoin:bc1qv3svjn40v89mnkre5vyvs2xw6y8phaltl385d2) にて Trilium をサポートすることができます。 + +## 🔑 ライセンス + +このプログラムはフリーソフトウェアです:フリーソフトウェア財団が発行した GNU Affero General Public License のバージョン3、またはそれ以降のバージョンのいずれかに従って、再配布および/または改変することができます。 From 5a32a7ce185167afab0c25586ffaeb1955b0970b Mon Sep 17 00:00:00 2001 From: Ikko Eltociear Ashimine Date: Sun, 26 Mar 2023 20:33:59 +0900 Subject: [PATCH 13/46] minor fix --- README.ja.md | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.ja.md b/README.ja.md index d5285722c..621e3e0ff 100644 --- a/README.ja.md +++ b/README.ja.md @@ -1,6 +1,6 @@ # 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) +[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 Notes は、大規模な個人知識ベースの構築に焦点を当てた、階層型ノートアプリケーションです。概要は[スクリーンショット](https://github.com/zadam/trilium/wiki/Screenshot-tour)をご覧ください: diff --git a/README.md b/README.md index d2806af64..23b5caa7d 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ npm run start-server ## 🤝 Support -You can support Trilum using GitHub Sponsors, [PayPal](https://paypal.me/za4am) or Bitcoin (bitcoin:bc1qv3svjn40v89mnkre5vyvs2xw6y8phaltl385d2). +You can support Trilium using GitHub Sponsors, [PayPal](https://paypal.me/za4am) or Bitcoin (bitcoin:bc1qv3svjn40v89mnkre5vyvs2xw6y8phaltl385d2). ## 🔑 License From cf904a874e68a6baccafc303c642bc2bfd406c16 Mon Sep 17 00:00:00 2001 From: Ikko Eltociear Ashimine Date: Sun, 26 Mar 2023 20:34:46 +0900 Subject: [PATCH 14/46] Add links --- README-ZH_CN.md | 2 +- README.md | 2 +- README.ru.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README-ZH_CN.md b/README-ZH_CN.md index a31caa2a1..47d93a3da 100644 --- a/README-ZH_CN.md +++ b/README-ZH_CN.md @@ -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) +[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) [![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)以快速了解: diff --git a/README.md b/README.md index 23b5caa7d..d8cd45f14 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # 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) +[![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 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: diff --git a/README.ru.md b/README.ru.md index 794e6c4b2..f79341e79 100644 --- a/README.ru.md +++ b/README.ru.md @@ -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) +[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) [![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): From a099876088ca923b12571749c6118bb8ffd764ea Mon Sep 17 00:00:00 2001 From: zadam Date: Sun, 26 Mar 2023 20:50:37 +0200 Subject: [PATCH 15/46] fix escaping in sql console results --- package-lock.json | 5 ++--- src/public/app/widgets/sql_result.js | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index dbd019d3b..8117a4a56 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,11 @@ { "name": "trilium", - "version": "0.59.1", + "version": "0.59.2", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "trilium", - "version": "0.59.1", + "version": "0.59.2", "hasInstallScript": true, "license": "AGPL-3.0-only", "dependencies": { diff --git a/src/public/app/widgets/sql_result.js b/src/public/app/widgets/sql_result.js index 142dc79e3..4224e714b 100644 --- a/src/public/app/widgets/sql_result.js +++ b/src/public/app/widgets/sql_result.js @@ -60,7 +60,7 @@ export default class SqlResultWidget extends NoteContextAwareWidget { const $row = $(""); for (const key in result) { - $row.append($("").html(key)); + $row.append($("").text(key)); } $table.append($row); @@ -69,7 +69,7 @@ export default class SqlResultWidget extends NoteContextAwareWidget { const $row = $(""); for (const key in result) { - $row.append($("").html(result[key])); + $row.append($("").text(result[key])); } $table.append($row); From 53b4f0e0d5f15e9c0f54d9acfe9b9dfd07377d4a Mon Sep 17 00:00:00 2001 From: Matt Date: Sun, 26 Mar 2023 19:29:52 +0000 Subject: [PATCH 16/46] Add svg icons --- images/icon-black.svg | 12 ++++++++++++ images/icon-color.svg | 12 ++++++++++++ images/icon-grey.svg | 12 ++++++++++++ src/public/app/widgets/buttons/global_menu.js | 4 ++-- src/public/stylesheets/theme-dark.css | 2 +- 5 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 images/icon-black.svg create mode 100644 images/icon-color.svg create mode 100644 images/icon-grey.svg diff --git a/images/icon-black.svg b/images/icon-black.svg new file mode 100644 index 000000000..f3427da82 --- /dev/null +++ b/images/icon-black.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/images/icon-color.svg b/images/icon-color.svg new file mode 100644 index 000000000..bd266dab6 --- /dev/null +++ b/images/icon-color.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/images/icon-grey.svg b/images/icon-grey.svg new file mode 100644 index 000000000..92bc0906e --- /dev/null +++ b/images/icon-grey.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/public/app/widgets/buttons/global_menu.js b/src/public/app/widgets/buttons/global_menu.js index 8108655b7..73fa681d3 100644 --- a/src/public/app/widgets/buttons/global_menu.js +++ b/src/public/app/widgets/buttons/global_menu.js @@ -16,7 +16,7 @@ const TPL = ` } .global-menu-button { - background-image: url("${window.glob.assetPath}/images/icon-black.png"); + background-image: url("${window.glob.assetPath}/images/icon-black.svg"); background-repeat: no-repeat; background-position: 50% 45%; width: 100%; @@ -25,7 +25,7 @@ const TPL = ` } .global-menu-button:hover { - background-image: url("${window.glob.assetPath}/images/icon-color.png"); + background-image: url("${window.glob.assetPath}/images/icon-color.svg"); border: 0; } diff --git a/src/public/stylesheets/theme-dark.css b/src/public/stylesheets/theme-dark.css index e8b1de4b3..535282c30 100644 --- a/src/public/stylesheets/theme-dark.css +++ b/src/public/stylesheets/theme-dark.css @@ -72,7 +72,7 @@ } body .global-menu-button { - background-image: url("../images/icon-grey.png"); + background-image: url("../images/icon-grey.svg"); } body ::-webkit-calendar-picker-indicator { From 9881e6de3e4966af39ec6245562dca6ac7b25eaa Mon Sep 17 00:00:00 2001 From: zadam Date: Sun, 26 Mar 2023 23:09:15 +0200 Subject: [PATCH 17/46] fix hangup on highlighting empty tokens, closes #3772 --- src/services/search/services/search.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/services/search/services/search.js b/src/services/search/services/search.js index beb0555d1..d682af090 100644 --- a/src/services/search/services/search.js +++ b/src/services/search/services/search.js @@ -299,7 +299,9 @@ function highlightSearchResults(searchResults, highlightedTokens) { // which would make the resulting HTML string invalid. // { and } are used for marking and tag (to avoid matches on single 'b' character) // < and > are used for marking and - highlightedTokens = highlightedTokens.map(token => token.replace('/[<\{\}]/g', '')); + highlightedTokens = highlightedTokens + .map(token => token.replace('/[<\{\}]/g', '')) + .filter(token => !!token?.trim()); // sort by the longest, so we first highlight the longest matches highlightedTokens.sort((a, b) => a.length > b.length ? -1 : 1); From 79a6baca6f4137f82bcf378df37a623c943e468c Mon Sep 17 00:00:00 2001 From: zadam Date: Sun, 26 Mar 2023 23:23:13 +0200 Subject: [PATCH 18/46] adjust logo sizing/positioning --- src/public/app/widgets/buttons/global_menu.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/public/app/widgets/buttons/global_menu.js b/src/public/app/widgets/buttons/global_menu.js index 73fa681d3..7d38e87b4 100644 --- a/src/public/app/widgets/buttons/global_menu.js +++ b/src/public/app/widgets/buttons/global_menu.js @@ -18,7 +18,8 @@ const TPL = ` .global-menu-button { background-image: url("${window.glob.assetPath}/images/icon-black.svg"); background-repeat: no-repeat; - background-position: 50% 45%; + background-position: 50% 80%; + background-size: 45px; width: 100%; height: 100%; position: relative; From 3192531d4c3243c30f6c20bf8f1719ffae1f8a54 Mon Sep 17 00:00:00 2001 From: zadam Date: Mon, 27 Mar 2023 22:49:41 +0200 Subject: [PATCH 19/46] don't trigger menu items on right click, #3764 --- src/public/app/menus/context_menu.js | 5 +++++ src/public/app/widgets/type_widgets/relation_map.js | 6 +----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/public/app/menus/context_menu.js b/src/public/app/menus/context_menu.js index ba42cc345..19b5f6433 100644 --- a/src/public/app/menus/context_menu.js +++ b/src/public/app/menus/context_menu.js @@ -99,11 +99,16 @@ class ContextMenu { const $item = $("
  • ") .addClass("dropdown-item") .append($link) + .on('contextmenu', e => false) // important to use mousedown instead of click since the former does not change focus // (especially important for focused text for spell check) .on('mousedown', e => { e.stopPropagation(); + if (e.which !== 1) { // only left click triggers menu items + return false; + } + this.hide(); if (item.handler) { diff --git a/src/public/app/widgets/type_widgets/relation_map.js b/src/public/app/widgets/type_widgets/relation_map.js index aa9d68a06..696ad250d 100644 --- a/src/public/app/widgets/type_widgets/relation_map.js +++ b/src/public/app/widgets/type_widgets/relation_map.js @@ -470,11 +470,7 @@ export default class RelationMapTypeWidget extends TypeWidget { async createNoteBox(noteId, title, x, y) { const $link = await linkService.createNoteLink(noteId, {title}); - $link.mousedown(e => { - console.log(e); - - linkService.goToLink(e); - }); + $link.mousedown(e => linkService.goToLink(e)); const note = await froca.getNote(noteId); From 45a74a046c4dab51b881bdfaa40c7efd3f562af8 Mon Sep 17 00:00:00 2001 From: zadam Date: Mon, 27 Mar 2023 23:03:27 +0200 Subject: [PATCH 20/46] release 0.59.3 --- src/services/build.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/build.js b/src/services/build.js index 8b4a403e6..b8402c31e 100644 --- a/src/services/build.js +++ b/src/services/build.js @@ -1 +1 @@ -module.exports = { buildDate:"2023-03-14T21:15:08+01:00", buildRevision: "d8e9086bdeb721db795783b5d92395a9bd6882c9" }; +module.exports = { buildDate:"", buildRevision: "9881e6de3e4966af39ec6245562dca6ac7b25eaa" }; From ed52919f9ebe7f2f91d3add6b0fa4d3f4d06b908 Mon Sep 17 00:00:00 2001 From: zadam Date: Mon, 27 Mar 2023 23:06:14 +0200 Subject: [PATCH 21/46] release 0.59.3 --- package.json | 2 +- src/services/build.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 5d7c9d49b..343cc0ad8 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "trilium", "productName": "Trilium Notes", "description": "Trilium Notes", - "version": "0.59.2", + "version": "0.59.3", "license": "AGPL-3.0-only", "main": "electron.js", "bin": { diff --git a/src/services/build.js b/src/services/build.js index 8b4a403e6..cea5cf6a6 100644 --- a/src/services/build.js +++ b/src/services/build.js @@ -1 +1 @@ -module.exports = { buildDate:"2023-03-14T21:15:08+01:00", buildRevision: "d8e9086bdeb721db795783b5d92395a9bd6882c9" }; +module.exports = { buildDate:"2023-03-27T23:06:14+02:00", buildRevision: "9881e6de3e4966af39ec6245562dca6ac7b25eaa" }; From d354c91d7cb4dbc4a3b7c4f18039ea40b9e81173 Mon Sep 17 00:00:00 2001 From: zadam Date: Wed, 29 Mar 2023 22:40:50 +0200 Subject: [PATCH 22/46] sort icons by how much they are used, #3784 --- src/public/app/widgets/icon_list.js | 16 +++++++++ src/public/app/widgets/note_icon.js | 52 ++++++++++++++++++----------- src/routes/api/other.js | 29 ++++++++++++++++ src/routes/routes.js | 2 ++ 4 files changed, 79 insertions(+), 20 deletions(-) create mode 100644 src/routes/api/other.js diff --git a/src/public/app/widgets/icon_list.js b/src/public/app/widgets/icon_list.js index 1ad713b10..32fe21a95 100644 --- a/src/public/app/widgets/icon_list.js +++ b/src/public/app/widgets/icon_list.js @@ -11175,6 +11175,22 @@ const icons = [ } ]; +function getIconClass(icon) { + if (icon.type_of_icon === 'LOGO') { + return `bxl-${icon.name}`; + } + else if (icon.type_of_icon === 'SOLID') { + return `bxs-${icon.name}`; + } + else { + return `bx-${icon.name}`; + } +} + +for (const icon of icons) { + icon.className = getIconClass(icon); +} + export default { categories, icons diff --git a/src/public/app/widgets/note_icon.js b/src/public/app/widgets/note_icon.js index 20bdeed79..ba2bbb683 100644 --- a/src/public/app/widgets/note_icon.js +++ b/src/public/app/widgets/note_icon.js @@ -1,5 +1,6 @@ import NoteContextAwareWidget from "./note_context_aware_widget.js"; import attributeService from "../services/attributes.js"; +import server from "../services/server.js"; const TPL = ` @@ -95,8 +104,9 @@ export default class SortChildNotesDialog extends BasicWidget { const sortDirection = this.$form.find("input[name='sort-direction']:checked").val(); const foldersFirst = this.$form.find("input[name='sort-folders-first']").is(":checked"); const sortNatural = this.$form.find("input[name='sort-natural']").is(":checked"); + const sortLocale = this.$form.find("input[name='sort-locale']").val(); - await server.put(`notes/${this.parentNoteId}/sort-children`, {sortBy, sortDirection, foldersFirst, sortNatural}); + await server.put(`notes/${this.parentNoteId}/sort-children`, {sortBy, sortDirection, foldersFirst, sortNatural, sortLocale}); utils.closeActiveDialog(); }); diff --git a/src/routes/api/notes.js b/src/routes/api/notes.js index e019ddb8b..8ce603f37 100644 --- a/src/routes/api/notes.js +++ b/src/routes/api/notes.js @@ -94,13 +94,13 @@ function undeleteNote(req) { function sortChildNotes(req) { const noteId = req.params.noteId; - const {sortBy, sortDirection, foldersFirst, sortNatural} = req.body; + const {sortBy, sortDirection, foldersFirst, sortNatural, sortLocale} = req.body; - log.info(`Sorting '${noteId}' children with ${sortBy} ${sortDirection}, foldersFirst=${foldersFirst}, sortNatural=${sortNatural}`); + log.info(`Sorting '${noteId}' children with ${sortBy} ${sortDirection}, foldersFirst=${foldersFirst}, sortNatural=${sortNatural}, sortLocale=${sortLocale}`); const reverse = sortDirection === 'desc'; - treeService.sortNotes(noteId, sortBy, reverse, foldersFirst, sortNatural); + treeService.sortNotes(noteId, sortBy, reverse, foldersFirst, sortNatural, sortLocale); } function protectNote(req) { diff --git a/src/services/builtin_attributes.js b/src/services/builtin_attributes.js index b05ef66e5..6ab9b8a52 100644 --- a/src/services/builtin_attributes.js +++ b/src/services/builtin_attributes.js @@ -43,6 +43,7 @@ module.exports = [ { type: 'label', name: 'sortDirection' }, { type: 'label', name: 'sortFoldersFirst' }, { type: 'label', name: 'sortNatural' }, + { type: 'label', name: 'sortLocale' }, { type: 'label', name: 'top' }, { type: 'label', name: 'fullContentWidth' }, { type: 'label', name: 'shareHiddenFromTree' }, diff --git a/src/services/handlers.js b/src/services/handlers.js index e0902d8bc..75f5563b3 100644 --- a/src/services/handlers.js +++ b/src/services/handlers.js @@ -46,7 +46,7 @@ eventService.subscribe([ eventService.ENTITY_CHANGED, eventService.ENTITY_DELETE if (entityName === 'attributes') { runAttachedRelations(entity.getNote(), 'runOnAttributeChange', entity); - if (entity.type === 'label' && ['sorted', 'sortDirection', 'sortFoldersFirst', 'sortNatural'].includes(entity.name)) { + if (entity.type === 'label' && ['sorted', 'sortDirection', 'sortFoldersFirst', 'sortNatural', 'sortLocale'].includes(entity.name)) { handleSortedAttribute(entity); } else if (entity.type === 'label') { handleMaybeSortingLabel(entity); @@ -101,7 +101,7 @@ eventService.subscribe(eventService.ENTITY_CREATED, ({ entityName, entity }) => noteService.duplicateSubtreeWithoutRoot(templateNote.noteId, note.noteId); } } - else if (entity.type === 'label' && ['sorted', 'sortDirection', 'sortFoldersFirst', 'sortNatural'].includes(entity.name)) { + else if (entity.type === 'label' && ['sorted', 'sortDirection', 'sortFoldersFirst', 'sortNatural', 'sortLocale'].includes(entity.name)) { handleSortedAttribute(entity); } else if (entity.type === 'label') { diff --git a/src/services/tree.js b/src/services/tree.js index bf537c985..1038e8772 100644 --- a/src/services/tree.js +++ b/src/services/tree.js @@ -123,11 +123,16 @@ function loadSubtreeNoteIds(parentNoteId, subtreeNoteIds) { } } -function sortNotes(parentNoteId, customSortBy = 'title', reverse = false, foldersFirst = false, sortNatural = false) { +function sortNotes(parentNoteId, customSortBy = 'title', reverse = false, foldersFirst = false, sortNatural = false, sortLocale) { if (!customSortBy) { customSortBy = 'title'; } + if (!sortLocale) { + // sortLocale can not be empty string or null value, default value must be set to undefined. + sortLocale = undefined; + } + sql.transactional(() => { const notes = becca.getNote(parentNoteId).getChildNotes(); @@ -157,8 +162,8 @@ function sortNotes(parentNoteId, customSortBy = 'title', reverse = false, folder // alphabetical sort return b === null || b === undefined || a < b ? -1 : 1; } else { - // alphanumeric sort, or natural sort - return a.localeCompare(b, undefined, {numeric: true, sensitivity: 'base'}); + // natural sort + return a.localeCompare(b, sortLocale, {numeric: true, sensitivity: 'base'}); } } @@ -233,7 +238,9 @@ function sortNotesIfNeeded(parentNoteId) { const sortFoldersFirst = sortFoldersFirstLabel && sortFoldersFirstLabel.value.toLowerCase() !== "false"; const sortNaturalLabel = parentNote.getLabel('sortNatural'); const sortNatural = sortNaturalLabel && sortNaturalLabel.value.toLowerCase() !== "false"; - sortNotes(parentNoteId, sortedLabel.value, sortReversed, sortFoldersFirst, sortNatural); + const sortLocale = parentNote.getLabelValue('sortLocale'); + + sortNotes(parentNoteId, sortedLabel.value, sortReversed, sortFoldersFirst, sortNatural, sortLocale); } /** From d100b0dc07ad9c0caf4ce950c8b9c0358f30cf93 Mon Sep 17 00:00:00 2001 From: zadam Date: Mon, 3 Apr 2023 21:08:32 +0200 Subject: [PATCH 26/46] allow #newNotesOnTop=false to negate previous setting, closes #3796 --- package-lock.json | 4 ++-- src/becca/entities/bnote.js | 14 ++++++++++++++ src/public/app/entities/fnote.js | 14 ++++++++++++++ src/services/notes.js | 2 +- 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8117a4a56..f6fd5eaef 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { "name": "trilium", - "version": "0.59.2", + "version": "0.59.3", "lockfileVersion": 2, "requires": true, "packages": { "": { - "version": "0.59.2", + "version": "0.59.3", "hasInstallScript": true, "license": "AGPL-3.0-only", "dependencies": { diff --git a/src/becca/entities/bnote.js b/src/becca/entities/bnote.js index 07ebd612f..960b35234 100644 --- a/src/becca/entities/bnote.js +++ b/src/becca/entities/bnote.js @@ -532,6 +532,20 @@ class BNote extends AbstractBeccaEntity { */ hasLabel(name, value) { return this.hasAttribute(LABEL, name, value); } + /** + * @param {string} name - label name + * @returns {boolean} true if label exists (including inherited) and does not have "false" value. + */ + isLabelTruthy(name) { + const label = this.getLabel(name); + + if (!label) { + return false; + } + + return label && label.value !== 'false'; + } + /** * @param {string} name - label name * @param {string} [value] - label value diff --git a/src/public/app/entities/fnote.js b/src/public/app/entities/fnote.js index 70594d647..1066a9341 100644 --- a/src/public/app/entities/fnote.js +++ b/src/public/app/entities/fnote.js @@ -595,6 +595,20 @@ class FNote { */ hasLabel(name) { return this.hasAttribute(LABEL, name); } + /** + * @param {string} name - label name + * @returns {boolean} true if label exists (including inherited) and does not have "false" value. + */ + isLabelTruthy(name) { + const label = this.getLabel(name); + + if (!label) { + return false; + } + + return label && label.value !== 'false'; + } + /** * @param {string} name - relation name * @returns {boolean} true if relation exists (excluding inherited) diff --git a/src/services/notes.js b/src/services/notes.js index 6dfa34cb0..3da2f56fc 100644 --- a/src/services/notes.js +++ b/src/services/notes.js @@ -23,7 +23,7 @@ const ValidationError = require("../errors/validation_error"); const noteTypesService = require("./note_types"); function getNewNotePosition(parentNote) { - if (parentNote.hasLabel('newNotesOnTop')) { + if (parentNote.isLabelTruthy('newNotesOnTop')) { const minNotePos = parentNote.getChildBranches() .reduce((min, note) => Math.min(min, note.notePosition), 0); From c44be53673391e7289b7209df0669e1986a20802 Mon Sep 17 00:00:00 2001 From: zadam Date: Wed, 5 Apr 2023 22:07:08 +0200 Subject: [PATCH 27/46] awaiting on triggered events/commands in the frontend API, fixes #3799 --- src/public/app/services/frontend_script_api.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/public/app/services/frontend_script_api.js b/src/public/app/services/frontend_script_api.js index c985d8997..98d4e8460 100644 --- a/src/public/app/services/frontend_script_api.js +++ b/src/public/app/services/frontend_script_api.js @@ -65,7 +65,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain await ws.waitForMaxKnownEntityChangeId(); await appContext.tabManager.getActiveContext().setNote(notePath); - appContext.triggerEvent('focusAndSelectTitle'); + await appContext.triggerEvent('focusAndSelectTitle'); }; /** @@ -82,7 +82,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain await appContext.tabManager.openContextWithNote(notePath, { activate }); if (activate) { - appContext.triggerEvent('focusAndSelectTitle'); + await appContext.triggerEvent('focusAndSelectTitle'); } }; @@ -100,10 +100,10 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain const subContexts = appContext.tabManager.getActiveContext().getSubContexts(); const {ntxId} = subContexts[subContexts.length - 1]; - appContext.triggerCommand("openNewNoteSplit", {ntxId, notePath}); + await appContext.triggerCommand("openNewNoteSplit", {ntxId, notePath}); if (activate) { - appContext.triggerEvent('focusAndSelectTitle'); + await appContext.triggerEvent('focusAndSelectTitle'); } }; From 6612a3a550a2c870941b0ba6d2f3f72d334c6a0e Mon Sep 17 00:00:00 2001 From: soulsands <407221377@qq.com> Date: Thu, 6 Apr 2023 20:59:09 +0800 Subject: [PATCH 28/46] fix: correct note-map resizing --- src/public/app/widgets/note_map.js | 9 ++++++++- src/public/app/widgets/ribbon_widgets/note_map.js | 13 ++++++++++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/public/app/widgets/note_map.js b/src/public/app/widgets/note_map.js index ccd659683..80ccf194c 100644 --- a/src/public/app/widgets/note_map.js +++ b/src/public/app/widgets/note_map.js @@ -55,7 +55,14 @@ export default class NoteMapWidget extends NoteContextAwareWidget { this.$container = this.$widget.find(".note-map-container"); this.$styleResolver = this.$widget.find('.style-resolver'); - window.addEventListener('resize', () => this.setDimensions(), false); + + try { + new ResizeObserver(() => this.setDimensions()).observe(this.$container[0]) + } catch (error) { + window.addEventListener('resize', () => this.setDimensions(), false); + } + + this.$widget.find(".map-type-switcher button").on("click", async e => { const type = $(e.target).closest("button").attr("data-type"); diff --git a/src/public/app/widgets/ribbon_widgets/note_map.js b/src/public/app/widgets/ribbon_widgets/note_map.js index 26405b281..ffcf36e56 100644 --- a/src/public/app/widgets/ribbon_widgets/note_map.js +++ b/src/public/app/widgets/ribbon_widgets/note_map.js @@ -87,8 +87,8 @@ export default class NoteMapRibbonWidget extends NoteContextAwareWidget { this.noteMapWidget.setDimensions(); }); - window.addEventListener('resize', () => { - if (!this.graph) { // no graph has been even rendered + const handleResize = () => { + if (!this.noteMapWidget.graph) { // no graph has been even rendered return; } @@ -98,7 +98,14 @@ export default class NoteMapRibbonWidget extends NoteContextAwareWidget { else if (this.openState === 'small') { this.setSmallSize(); } - }, false); + } + + try { + new ResizeObserver(handleResize).observe(this.$widget[0]) + } catch (error) { + window.addEventListener('resize', handleResize, false); + } + } setSmallSize() { From 8229a97ffbef2fdb4cda5ca13091e46a7d8a1a78 Mon Sep 17 00:00:00 2001 From: zadam Date: Thu, 6 Apr 2023 21:20:19 +0200 Subject: [PATCH 29/46] capitalizing ribbon widget names #3806 --- src/public/app/widgets/ribbon_widgets/promoted_attributes.js | 2 +- src/public/app/widgets/ribbon_widgets/search_definition.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/public/app/widgets/ribbon_widgets/promoted_attributes.js b/src/public/app/widgets/ribbon_widgets/promoted_attributes.js index ac5286795..586780a20 100644 --- a/src/public/app/widgets/ribbon_widgets/promoted_attributes.js +++ b/src/public/app/widgets/ribbon_widgets/promoted_attributes.js @@ -60,7 +60,7 @@ export default class PromotedAttributesWidget extends NoteContextAwareWidget { return { show: true, activate: true, - title: "Promoted attributes", + title: "Promoted Attributes", icon: "bx bx-table" }; } diff --git a/src/public/app/widgets/ribbon_widgets/search_definition.js b/src/public/app/widgets/ribbon_widgets/search_definition.js index 4ca8e17d9..baa6dfdd9 100644 --- a/src/public/app/widgets/ribbon_widgets/search_definition.js +++ b/src/public/app/widgets/ribbon_widgets/search_definition.js @@ -180,7 +180,7 @@ export default class SearchDefinitionWidget extends NoteContextAwareWidget { return { show: this.isEnabled(), activate: true, - title: 'Search parameters', + title: 'Search Parameters', icon: 'bx bx-search' }; } From 32e9fd291d0907aaafd56cde6d61111d477142b7 Mon Sep 17 00:00:00 2001 From: zadam Date: Thu, 6 Apr 2023 21:25:13 +0200 Subject: [PATCH 30/46] promotes attributes tab should be always visible when available, fixes #3806 --- src/public/app/layouts/desktop_layout.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/public/app/layouts/desktop_layout.js b/src/public/app/layouts/desktop_layout.js index 3040a4ac3..17dcc99a7 100644 --- a/src/public/app/layouts/desktop_layout.js +++ b/src/public/app/layouts/desktop_layout.js @@ -128,6 +128,10 @@ export default class DesktopLayout { ) .child( new RibbonContainer() + // order of the widgets matter. Some of these want to "activate" themselves + // when visible, when this happens to multiple of them, the first one "wins". + // promoted attributes should always win. + .ribbon(new PromotedAttributesWidget()) .ribbon(new ScriptExecutorWidget()) .ribbon(new SearchDefinitionWidget()) .ribbon(new EditedNotesWidget()) @@ -135,7 +139,6 @@ export default class DesktopLayout { .ribbon(new NotePropertiesWidget()) .ribbon(new FilePropertiesWidget()) .ribbon(new ImagePropertiesWidget()) - .ribbon(new PromotedAttributesWidget()) .ribbon(new BasicPropertiesWidget()) .ribbon(new OwnedAttributeListWidget()) .ribbon(new InheritedAttributesWidget()) From 517f1992a1d4b64ddf132a97f61b2b01b93af720 Mon Sep 17 00:00:00 2001 From: zadam Date: Thu, 6 Apr 2023 21:30:37 +0200 Subject: [PATCH 31/46] remove fallback resize window handlers, such old browsers are not supported --- src/public/app/widgets/note_map.js | 9 +-------- src/public/app/widgets/ribbon_widgets/note_map.js | 7 +------ src/public/app/widgets/tab_row.js | 9 +-------- 3 files changed, 3 insertions(+), 22 deletions(-) diff --git a/src/public/app/widgets/note_map.js b/src/public/app/widgets/note_map.js index 80ccf194c..ad6fd4377 100644 --- a/src/public/app/widgets/note_map.js +++ b/src/public/app/widgets/note_map.js @@ -55,14 +55,7 @@ export default class NoteMapWidget extends NoteContextAwareWidget { this.$container = this.$widget.find(".note-map-container"); this.$styleResolver = this.$widget.find('.style-resolver'); - - try { - new ResizeObserver(() => this.setDimensions()).observe(this.$container[0]) - } catch (error) { - window.addEventListener('resize', () => this.setDimensions(), false); - } - - + new ResizeObserver(() => this.setDimensions()).observe(this.$container[0]) this.$widget.find(".map-type-switcher button").on("click", async e => { const type = $(e.target).closest("button").attr("data-type"); diff --git a/src/public/app/widgets/ribbon_widgets/note_map.js b/src/public/app/widgets/ribbon_widgets/note_map.js index ffcf36e56..5b1348827 100644 --- a/src/public/app/widgets/ribbon_widgets/note_map.js +++ b/src/public/app/widgets/ribbon_widgets/note_map.js @@ -100,12 +100,7 @@ export default class NoteMapRibbonWidget extends NoteContextAwareWidget { } } - try { - new ResizeObserver(handleResize).observe(this.$widget[0]) - } catch (error) { - window.addEventListener('resize', handleResize, false); - } - + new ResizeObserver(handleResize).observe(this.$widget[0]) } setSmallSize() { diff --git a/src/public/app/widgets/tab_row.js b/src/public/app/widgets/tab_row.js index cf21ab9e0..55a5da24c 100644 --- a/src/public/app/widgets/tab_row.js +++ b/src/public/app/widgets/tab_row.js @@ -280,14 +280,7 @@ export default class TabRowWidget extends BasicWidget { this.layoutTabs(); }; - // ResizeObserver exists only in FF69 - if (typeof ResizeObserver !== "undefined") { - new ResizeObserver(resizeListener).observe(this.$widget[0]); - } - else { - // for older firefox - window.addEventListener('resize', resizeListener); - } + new ResizeObserver(resizeListener).observe(this.$widget[0]); this.tabEls.forEach((tabEl) => this.setTabCloseEvent(tabEl)); } From e871edc8f347e6add552abe67d94a68793558802 Mon Sep 17 00:00:00 2001 From: zadam Date: Thu, 6 Apr 2023 23:05:03 +0200 Subject: [PATCH 32/46] fix click events propagating from context menu being closed, fixes #3805 --- src/public/app/menus/context_menu.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/public/app/menus/context_menu.js b/src/public/app/menus/context_menu.js index 19b5f6433..c87127803 100644 --- a/src/public/app/menus/context_menu.js +++ b/src/public/app/menus/context_menu.js @@ -147,7 +147,9 @@ class ContextMenu { // "contextmenu" event also triggers "click" event which depending on the timing can close just opened context menu // we might filter out right clicks, but then it's better if even right clicks close the context menu if (Date.now() - this.dateContextMenuOpenedMs > 300) { - this.$widget.hide(); + // seems like if we hide the menu immediately, some clicks can get propagated to the underlying component + // see https://github.com/zadam/trilium/pull/3805 for details + setTimeout(() => this.$widget.hide(), 100); } } } From 24866a3e2532a497dc6215052264946e8be447c1 Mon Sep 17 00:00:00 2001 From: zadam Date: Thu, 6 Apr 2023 23:05:03 +0200 Subject: [PATCH 33/46] fix click events propagating from context menu being closed, fixes #3805 (cherry picked from commit e871edc8f347e6add552abe67d94a68793558802) --- src/public/app/menus/context_menu.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/public/app/menus/context_menu.js b/src/public/app/menus/context_menu.js index ba42cc345..627510ca7 100644 --- a/src/public/app/menus/context_menu.js +++ b/src/public/app/menus/context_menu.js @@ -142,7 +142,9 @@ class ContextMenu { // "contextmenu" event also triggers "click" event which depending on the timing can close just opened context menu // we might filter out right clicks, but then it's better if even right clicks close the context menu if (Date.now() - this.dateContextMenuOpenedMs > 300) { - this.$widget.hide(); + // seems like if we hide the menu immediately, some clicks can get propagated to the underlying component + // see https://github.com/zadam/trilium/pull/3805 for details + setTimeout(() => this.$widget.hide(), 100); } } } From 869522853773634b7cee194de3cc52cc4a288469 Mon Sep 17 00:00:00 2001 From: soulsands <407221377@qq.com> Date: Fri, 7 Apr 2023 19:51:34 +0800 Subject: [PATCH 34/46] perf: add persistent http cache in prod --- src/app.js | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/app.js b/src/app.js index c77189fef..c876fceab 100644 --- a/src/app.js +++ b/src/app.js @@ -5,12 +5,13 @@ const favicon = require('serve-favicon'); const cookieParser = require('cookie-parser'); const helmet = require('helmet'); const session = require('express-session'); -const compression = require('compression') +const compression = require('compression'); const FileStore = require('session-file-store')(session); const sessionSecret = require('./services/session_secret'); const dataDir = require('./services/data_dir'); const utils = require('./services/utils'); const assetPath = require('./services/asset_path'); +const env = require('./services/env'); require('./services/handlers'); require('./becca/becca_loader'); @@ -30,27 +31,37 @@ app.use(helmet({ crossOriginEmbedderPolicy: false })); +const persistentCacheStatic = (root, options) => { + if (!env.isDev()) { + options = { + maxAge: '1y', + ...options + }; + } + return express.static(root, options); +}; + app.use(express.text({limit: '500mb'})); app.use(express.json({limit: '500mb'})); app.use(express.raw({limit: '500mb'})); app.use(express.urlencoded({extended: false})); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public/root'))); -app.use(`/${assetPath}/app`, express.static(path.join(__dirname, 'public/app'))); -app.use(`/${assetPath}/app-dist`, express.static(path.join(__dirname, 'public/app-dist'))); -app.use(`/${assetPath}/fonts`, express.static(path.join(__dirname, 'public/fonts'))); +app.use(`/${assetPath}/app`, persistentCacheStatic(path.join(__dirname, 'public/app'))); +app.use(`/${assetPath}/app-dist`, persistentCacheStatic(path.join(__dirname, 'public/app-dist'))); +app.use(`/${assetPath}/fonts`, persistentCacheStatic(path.join(__dirname, 'public/fonts'))); app.use(`/assets/vX/fonts`, express.static(path.join(__dirname, 'public/fonts'))); -app.use(`/${assetPath}/stylesheets`, express.static(path.join(__dirname, 'public/stylesheets'))); +app.use(`/${assetPath}/stylesheets`, persistentCacheStatic(path.join(__dirname, 'public/stylesheets'))); app.use(`/assets/vX/stylesheets`, express.static(path.join(__dirname, 'public/stylesheets'))); -app.use(`/${assetPath}/libraries`, express.static(path.join(__dirname, '..', 'libraries'))); +app.use(`/${assetPath}/libraries`, persistentCacheStatic(path.join(__dirname, '..', 'libraries'))); app.use(`/assets/vX/libraries`, express.static(path.join(__dirname, '..', 'libraries'))); // excalidraw-view mode in shared notes -app.use(`/${assetPath}/node_modules/react/umd/react.production.min.js`, express.static(path.join(__dirname, '..', 'node_modules/react/umd/react.production.min.js'))); -app.use(`/${assetPath}/node_modules/react-dom/umd/react-dom.production.min.js`, express.static(path.join(__dirname, '..', 'node_modules/react-dom/umd/react-dom.production.min.js'))); +app.use(`/${assetPath}/node_modules/react/umd/react.production.min.js`, persistentCacheStatic(path.join(__dirname, '..', 'node_modules/react/umd/react.production.min.js'))); +app.use(`/${assetPath}/node_modules/react-dom/umd/react-dom.production.min.js`, persistentCacheStatic(path.join(__dirname, '..', 'node_modules/react-dom/umd/react-dom.production.min.js'))); // expose whole dist folder since complete assets are needed in edit and share app.use(`/node_modules/@excalidraw/excalidraw/dist/`, express.static(path.join(__dirname, '..', 'node_modules/@excalidraw/excalidraw/dist/'))); -app.use(`/${assetPath}/node_modules/@excalidraw/excalidraw/dist/`, express.static(path.join(__dirname, '..', 'node_modules/@excalidraw/excalidraw/dist/'))); -app.use(`/${assetPath}/images`, express.static(path.join(__dirname, '..', 'images'))); +app.use(`/${assetPath}/node_modules/@excalidraw/excalidraw/dist/`, persistentCacheStatic(path.join(__dirname, '..', 'node_modules/@excalidraw/excalidraw/dist/'))); +app.use(`/${assetPath}/images`, persistentCacheStatic(path.join(__dirname, '..', 'images'))); app.use(`/assets/vX/images`, express.static(path.join(__dirname, '..', 'images'))); app.use(`/manifest.webmanifest`, express.static(path.join(__dirname, 'public/manifest.webmanifest'))); app.use(`/robots.txt`, express.static(path.join(__dirname, 'public/robots.txt'))); @@ -61,7 +72,7 @@ const sessionParser = session({ cookie: { // path: "/", httpOnly: true, - maxAge: 24 * 60 * 60 * 1000 // in milliseconds + maxAge: 24 * 60 * 60 * 1000 // in milliseconds }, name: 'trilium.sid', store: new FileStore({ From 293573a0cd759f43966f892c178b76245f7d3456 Mon Sep 17 00:00:00 2001 From: zadam Date: Fri, 7 Apr 2023 21:45:27 +0200 Subject: [PATCH 35/46] don't update attribute detail while composing CJK characters, fixes #3812 --- .../attribute_widgets/attribute_detail.js | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/public/app/widgets/attribute_widgets/attribute_detail.js b/src/public/app/widgets/attribute_widgets/attribute_detail.js index 488f3709b..80efc31ba 100644 --- a/src/public/app/widgets/attribute_widgets/attribute_detail.js +++ b/src/public/app/widgets/attribute_widgets/attribute_detail.js @@ -285,7 +285,11 @@ export default class AttributeDetailWidget extends NoteContextAwareWidget { this.$title = this.$widget.find('.attr-detail-title'); this.$inputName = this.$widget.find('.attr-input-name'); - this.$inputName.on('keyup', () => this.userEditedAttribute()); + this.$inputName.on('input', ev => { + if (!ev.originalEvent?.isComposing) { // https://github.com/zadam/trilium/pull/3812 + this.userEditedAttribute(); + } + }); this.$inputName.on('change', () => this.userEditedAttribute()); this.$inputName.on('autocomplete:closed', () => this.userEditedAttribute()); @@ -299,7 +303,11 @@ export default class AttributeDetailWidget extends NoteContextAwareWidget { this.$rowValue = this.$widget.find('.attr-row-value'); this.$inputValue = this.$widget.find('.attr-input-value'); - this.$inputValue.on('keyup', () => this.userEditedAttribute()); + this.$inputValue.on('input', ev => { + if (!ev.originalEvent?.isComposing) { // https://github.com/zadam/trilium/pull/3812 + this.userEditedAttribute(); + } + }); this.$inputValue.on('change', () => this.userEditedAttribute()); this.$inputValue.on('autocomplete:closed', () => this.userEditedAttribute()); this.$inputValue.on('focus', () => { @@ -328,7 +336,11 @@ export default class AttributeDetailWidget extends NoteContextAwareWidget { this.$rowInverseRelation = this.$widget.find('.attr-row-inverse-relation'); this.$inputInverseRelation = this.$widget.find('.attr-input-inverse-relation'); - this.$inputInverseRelation.on('keyup', () => this.userEditedAttribute()); + this.$inputInverseRelation.on('input', ev => { + if (!ev.originalEvent?.isComposing) { // https://github.com/zadam/trilium/pull/3812 + this.userEditedAttribute(); + } + }); this.$rowTargetNote = this.$widget.find('.attr-row-target-note'); this.$inputTargetNote = this.$widget.find('.attr-input-target-note'); From cec4dfa6c39e6354bfd368415f006df2e105f0ab Mon Sep 17 00:00:00 2001 From: soulsands <407221377@qq.com> Date: Sat, 8 Apr 2023 14:56:37 +0800 Subject: [PATCH 36/46] fix:don't break words for CJK text --- .../app/widgets/ribbon_widgets/promoted_attributes.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/public/app/widgets/ribbon_widgets/promoted_attributes.js b/src/public/app/widgets/ribbon_widgets/promoted_attributes.js index ac5286795..bbaa0d4d6 100644 --- a/src/public/app/widgets/ribbon_widgets/promoted_attributes.js +++ b/src/public/app/widgets/ribbon_widgets/promoted_attributes.js @@ -29,6 +29,9 @@ const TPL = ` .promoted-attribute-cell div.input-group { margin-left: 10px; } + .promoted-attribute-cell strong { + word-break:keep-all; + } @@ -54,7 +57,7 @@ export default class PromotedAttributesWidget extends NoteContextAwareWidget { const promotedDefAttrs = note.getPromotedDefinitionAttributes(); if (promotedDefAttrs.length === 0) { - return { show: false }; + return {show: false}; } return { @@ -144,7 +147,7 @@ export default class PromotedAttributesWidget extends NoteContextAwareWidget { return; } - attributeValues = attributeValues.map(attribute => ({ value: attribute })); + attributeValues = attributeValues.map(attribute => ({value: attribute})); $input.autocomplete({ appendTo: document.querySelector('body'), @@ -164,7 +167,7 @@ export default class PromotedAttributesWidget extends NoteContextAwareWidget { } }]); - $input.on('autocomplete:selected', e => this.promotedAttributeChanged(e)) + $input.on('autocomplete:selected', e => this.promotedAttributeChanged(e)); }); } else if (definition.labelType === 'number') { From 306e7abb47864f01435581701d9772da5ea0a265 Mon Sep 17 00:00:00 2001 From: soulsands <407221377@qq.com> Date: Sat, 8 Apr 2023 18:41:18 +0800 Subject: [PATCH 37/46] feat: add Microsoft YaHei font (for Chinese) --- src/public/app/widgets/type_widgets/options/appearance/fonts.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/public/app/widgets/type_widgets/options/appearance/fonts.js b/src/public/app/widgets/type_widgets/options/appearance/fonts.js index d208ccb65..1986f790f 100644 --- a/src/public/app/widgets/type_widgets/options/appearance/fonts.js +++ b/src/public/app/widgets/type_widgets/options/appearance/fonts.js @@ -24,6 +24,7 @@ const FONT_FAMILIES = [ { value: "Bradley Hand", label: "Bradley Hand" }, { value: "Luminari", label: "Luminari" }, { value: "Comic Sans MS", label: "Comic Sans MS" }, + { value: "Microsoft YaHei", label: "Microsoft YaHei" }, ]; const TPL = ` From ab7a07a318d09a9f69bccbb7d8bc63ebbdbeaa61 Mon Sep 17 00:00:00 2001 From: soulsands <407221377@qq.com> Date: Sat, 8 Apr 2023 19:51:39 +0800 Subject: [PATCH 38/46] fix: remove extra params --- src/etapi/special_notes.js | 10 +++++----- src/services/search/services/parse.js | 4 ++-- src/services/sql.js | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/etapi/special_notes.js b/src/etapi/special_notes.js index 3cc38260b..7e1e2a6f5 100644 --- a/src/etapi/special_notes.js +++ b/src/etapi/special_notes.js @@ -20,7 +20,7 @@ function register(router) { const {date} = req.params; if (!isValidDate(date)) { - throw getDateInvalidError(res, date); + throw getDateInvalidError(date); } const note = specialNotesService.getInboxNote(date); @@ -31,7 +31,7 @@ function register(router) { const {date} = req.params; if (!isValidDate(date)) { - throw getDateInvalidError(res, date); + throw getDateInvalidError(date); } const note = dateNotesService.getDayNote(date); @@ -42,7 +42,7 @@ function register(router) { const {date} = req.params; if (!isValidDate(date)) { - throw getDateInvalidError(res, date); + throw getDateInvalidError(date); } const note = dateNotesService.getWeekNote(date); @@ -53,7 +53,7 @@ function register(router) { const {month} = req.params; if (!/[0-9]{4}-[0-9]{2}/.test(month)) { - throw getMonthInvalidError(res, month); + throw getMonthInvalidError(month); } const note = dateNotesService.getMonthNote(month); @@ -64,7 +64,7 @@ function register(router) { const {year} = req.params; if (!/[0-9]{4}/.test(year)) { - throw getYearInvalidError(res, year); + throw getYearInvalidError(year); } const note = dateNotesService.getYearNote(year); diff --git a/src/services/search/services/parse.js b/src/services/search/services/parse.js index 6332f7728..1580caa37 100644 --- a/src/services/search/services/parse.js +++ b/src/services/search/services/parse.js @@ -155,7 +155,7 @@ function getExpression(tokens, searchContext, level = 0) { i++; - return new NoteContentFulltextExp(operator.token, {tokens: [tokens[i].token], raw }); + return new NoteContentFulltextExp(operator.token, {tokens: [tokens[i].token], raw}); } if (tokens[i].token === 'parents') { @@ -389,7 +389,7 @@ function getExpression(tokens, searchContext, level = 0) { else if (token === 'note') { i++; - expressions.push(parseNoteProperty(tokens)); + expressions.push(parseNoteProperty()); continue; } diff --git a/src/services/sql.js b/src/services/sql.js index 71af2394f..1b20eaff2 100644 --- a/src/services/sql.js +++ b/src/services/sql.js @@ -217,7 +217,7 @@ function wrap(query, func) { // in these cases error should be simply ignored. console.log(e.message); - return null + return null; } throw e; @@ -281,7 +281,7 @@ function fillParamList(paramIds, truncate = true) { } // doing it manually to avoid this showing up on the sloq query list - const s = stmt(`INSERT INTO param_list VALUES ${paramIds.map(paramId => `(?)`).join(',')}`, paramIds); + const s = stmt(`INSERT INTO param_list VALUES ${paramIds.map(paramId => `(?)`).join(',')}`); s.run(paramIds); } From 49d1c5140e1ecdd376fafb9aff8ce9b171887cb5 Mon Sep 17 00:00:00 2001 From: soulsands <407221377@qq.com> Date: Sat, 8 Apr 2023 19:54:59 +0800 Subject: [PATCH 39/46] fix: equal --- src/services/attributes.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/services/attributes.js b/src/services/attributes.js index d123829d5..5dffc5c7f 100644 --- a/src/services/attributes.js +++ b/src/services/attributes.js @@ -7,7 +7,7 @@ const BAttribute = require('../becca/entities/battribute'); const {formatAttrForSearch} = require("./attribute_formatter"); const BUILTIN_ATTRIBUTES = require("./builtin_attributes"); -const ATTRIBUTE_TYPES = [ 'label', 'relation' ]; +const ATTRIBUTE_TYPES = ['label', 'relation']; /** @returns {BNote[]} */ function getNotesWithLabel(name, value = undefined) { @@ -122,7 +122,7 @@ function isAttributeType(type) { function isAttributeDangerous(type, name) { return BUILTIN_ATTRIBUTES.some(attr => - attr.type === attr.type && + attr.type === type && attr.name.toLowerCase() === name.trim().toLowerCase() && attr.isDangerous ); From 50043f889bf5ac69f66f6863da906d4f91811537 Mon Sep 17 00:00:00 2001 From: soulsands <407221377@qq.com> Date: Sat, 8 Apr 2023 20:00:42 +0800 Subject: [PATCH 40/46] fix: remove duplication --- src/becca/similarity.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/becca/similarity.js b/src/becca/similarity.js index dadfb1ce5..2e7750100 100644 --- a/src/becca/similarity.js +++ b/src/becca/similarity.js @@ -2,7 +2,7 @@ const becca = require('./becca'); const log = require('../services/log'); const beccaService = require('./becca_service'); const dateUtils = require('../services/date_utils'); -const { JSDOM } = require("jsdom"); +const {JSDOM} = require("jsdom"); const DEBUG = false; @@ -168,7 +168,6 @@ function trimMime(mime) { } mimeCache[mime] = str; - mimeCache[mime] = str; } return mimeCache[mime]; @@ -224,8 +223,8 @@ function splitToWords(text) { */ function hasConnectingRelation(sourceNote, targetNote) { return sourceNote.getAttributes().find(attr => attr.type === 'relation' - && ['includenotelink', 'imagelink'].includes(attr.name) - && attr.value === targetNote.noteId); + && ['includenotelink', 'imagelink'].includes(attr.name) + && attr.value === targetNote.noteId); } async function findSimilarNotes(noteId) { @@ -301,7 +300,7 @@ async function findSimilarNotes(noteId) { for (const branch of parentNote.getParentBranches()) { score += gatherRewards(branch.prefix, 0.3) - + gatherAncestorRewards(branch.parentNote); + + gatherAncestorRewards(branch.parentNote); } } } @@ -314,7 +313,7 @@ async function findSimilarNotes(noteId) { function computeScore(candidateNote) { let score = gatherRewards(trimMime(candidateNote.mime)) - + gatherAncestorRewards(candidateNote); + + gatherAncestorRewards(candidateNote); if (candidateNote.isDecrypted) { score += gatherRewards(candidateNote.title); @@ -382,7 +381,7 @@ async function findSimilarNotes(noteId) { score += 1; } else if (utcDateCreated.substr(0, 10) === dateLimits.minDate.substr(0, 10) - || utcDateCreated.substr(0, 10) === dateLimits.maxDate.substr(0, 10)) { + || utcDateCreated.substr(0, 10) === dateLimits.maxDate.substr(0, 10)) { if (displayRewards) { console.log("Adding reward for same day of creation"); } From 181ddce88759495c9fb300e5b64d60b08a04b5b3 Mon Sep 17 00:00:00 2001 From: soulsands <407221377@qq.com> Date: Sat, 8 Apr 2023 20:49:25 +0800 Subject: [PATCH 41/46] =?UTF-8?q?fix:=E3=80=80remove=20misleading=20await?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/public/app/services/branches.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/public/app/services/branches.js b/src/public/app/services/branches.js index b94c95b2a..c414cf257 100644 --- a/src/public/app/services/branches.js +++ b/src/public/app/services/branches.js @@ -10,7 +10,7 @@ async function moveBeforeBranch(branchIdsToMove, beforeBranchId) { branchIdsToMove = filterRootNote(branchIdsToMove); branchIdsToMove = filterSearchBranches(branchIdsToMove); - const beforeBranch = await froca.getBranch(beforeBranchId); + const beforeBranch = froca.getBranch(beforeBranchId); if (['root', '_lbRoot', '_lbAvailableLaunchers', '_lbVisibleLaunchers'].includes(beforeBranch.noteId)) { toastService.showError('Cannot move notes here.'); @@ -31,7 +31,7 @@ async function moveAfterBranch(branchIdsToMove, afterBranchId) { branchIdsToMove = filterRootNote(branchIdsToMove); branchIdsToMove = filterSearchBranches(branchIdsToMove); - const afterNote = await froca.getBranch(afterBranchId).getNote(); + const afterNote = froca.getBranch(afterBranchId).getNote(); const forbiddenNoteIds = [ 'root', @@ -59,7 +59,7 @@ async function moveAfterBranch(branchIdsToMove, afterBranchId) { } async function moveToParentNote(branchIdsToMove, newParentBranchId) { - const newParentBranch = await froca.getBranch(newParentBranchId); + const newParentBranch = froca.getBranch(newParentBranchId); if (newParentBranch.noteId === '_lbRoot') { toastService.showError('Cannot move notes here.'); @@ -165,7 +165,7 @@ function filterRootNote(branchIds) { const hoistedNoteId = hoistedNoteService.getHoistedNoteId(); return branchIds.filter(branchId => { - const branch = froca.getBranch(branchId); + const branch = froca.getBranch(branchId); return branch.noteId !== 'root' && branch.noteId !== hoistedNoteId; From a0ac603260353072ed1ae56b173b8fbdfda53297 Mon Sep 17 00:00:00 2001 From: soulsands <407221377@qq.com> Date: Sat, 8 Apr 2023 21:07:48 +0800 Subject: [PATCH 42/46] fix:Remove duplicates in character class --- src/public/app/services/utils.js | 10 +++++----- src/services/attribute_formatter.js | 6 +++--- src/services/search/services/search.js | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/public/app/services/utils.js b/src/public/app/services/utils.js index 49edcf5ec..e0ef2d767 100644 --- a/src/public/app/services/utils.js +++ b/src/public/app/services/utils.js @@ -29,7 +29,7 @@ function formatTimeWithSeconds(date) { // this is producing local time! function formatDate(date) { -// return padNum(date.getDate()) + ". " + padNum(date.getMonth() + 1) + ". " + date.getFullYear(); + // return padNum(date.getDate()) + ". " + padNum(date.getMonth() + 1) + ". " + date.getFullYear(); // instead of european format we'll just use ISO as that's pretty unambiguous return formatDateISO(date); @@ -45,7 +45,7 @@ function formatDateTime(date) { } function localNowDateTime() { - return dayjs().format('YYYY-MM-DD HH:mm:ss.SSSZZ') + return dayjs().format('YYYY-MM-DD HH:mm:ss.SSSZZ'); } function now() { @@ -101,7 +101,7 @@ async function stopWatch(what, func) { } function formatValueWithWhitespace(val) { - return /[^\w_-]/.test(val) ? `"${val}"` : val; + return /[^\w-]/.test(val) ? `"${val}"` : val; } function formatLabel(label) { @@ -318,7 +318,7 @@ function initHelpDropdown($el) { initHelpButtons($dropdownMenu); } -const wikiBaseUrl = "https://github.com/zadam/trilium/wiki/" +const wikiBaseUrl = "https://github.com/zadam/trilium/wiki/"; function openHelp(e) { window.open(wikiBaseUrl + $(e.target).attr("data-help-page"), '_blank'); @@ -329,7 +329,7 @@ function initHelpButtons($el) { // so we do it manually $el.on("click", e => { if ($(e.target).attr("data-help-page")) { - openHelp(e) + openHelp(e); } }); } diff --git a/src/services/attribute_formatter.js b/src/services/attribute_formatter.js index 8891a7813..c8a9c1de6 100644 --- a/src/services/attribute_formatter.js +++ b/src/services/attribute_formatter.js @@ -1,4 +1,4 @@ -"use strict" +"use strict"; function formatAttrForSearch(attr, searchWithValue) { let searchStr = ''; @@ -28,7 +28,7 @@ function formatAttrForSearch(attr, searchWithValue) { } function formatValue(val) { - if (!/[^\w_]/.test(val)) { + if (!/[^\w]/.test(val)) { return val; } else if (!val.includes('"')) { @@ -47,4 +47,4 @@ function formatValue(val) { module.exports = { formatAttrForSearch -} +}; diff --git a/src/services/search/services/search.js b/src/services/search/services/search.js index 4b4f2110e..f1adc72d7 100644 --- a/src/services/search/services/search.js +++ b/src/services/search/services/search.js @@ -73,7 +73,7 @@ function searchFromRelation(note, relationName) { return []; } - const result = scriptService.executeNote(scriptNote, { originEntity: note }); + const result = scriptService.executeNote(scriptNote, {originEntity: note}); if (!Array.isArray(result)) { log.info(`Result from ${scriptNote.noteId} is not an array.`); @@ -288,7 +288,7 @@ function searchNotesForAutocomplete(query) { noteTitle: beccaService.getNoteTitle(result.noteId), notePathTitle: result.notePathTitle, highlightedNotePathTitle: result.highlightedNotePathTitle - } + }; }); } @@ -370,7 +370,7 @@ function formatAttribute(attr) { let label = `#${utils.escapeHtml(attr.name)}`; if (attr.value) { - const val = /[^\w_-]/.test(attr.value) ? `"${attr.value}"` : attr.value; + const val = /[^\w-]/.test(attr.value) ? `"${attr.value}"` : attr.value; label += `=${utils.escapeHtml(val)}`; } From 745e120a0bc61c19eee597575718106d51270081 Mon Sep 17 00:00:00 2001 From: soulsands <407221377@qq.com> Date: Sat, 8 Apr 2023 21:13:37 +0800 Subject: [PATCH 43/46] fix: remove unused variable --- src/public/app/services/import.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/public/app/services/import.js b/src/public/app/services/import.js index dfc91c0df..7e5fc43b6 100644 --- a/src/public/app/services/import.js +++ b/src/public/app/services/import.js @@ -10,7 +10,6 @@ export async function uploadFiles(parentNoteId, files, options) { } const taskId = utils.randomString(10); - let noteId; let counter = 0; for (const file of files) { @@ -25,19 +24,19 @@ export async function uploadFiles(parentNoteId, files, options) { formData.append(key, options[key]); } - ({noteId} = await $.ajax({ + await $.ajax({ url: `${baseApiUrl}notes/${parentNoteId}/import`, headers: await server.getHeaders(), data: formData, dataType: 'json', type: 'POST', timeout: 60 * 60 * 1000, - error: function(xhr) { + error: function (xhr) { toastService.showError(`Import failed: ${xhr.responseText}`); }, contentType: false, // NEEDED, DON'T REMOVE THIS processData: false, // NEEDED, DON'T REMOVE THIS - })); + }); } } @@ -74,4 +73,4 @@ ws.subscribeToMessages(async message => { export default { uploadFiles -} +}; From 839b172b92629f295b3761af2b3e28835113cadc Mon Sep 17 00:00:00 2001 From: zadam Date: Sun, 9 Apr 2023 22:45:31 +0200 Subject: [PATCH 44/46] fix duplicating subtree with internal links, closes #3813 --- src/becca/entities/battribute.js | 2 +- src/becca/entities/bnote.js | 6 +++--- src/services/notes.js | 5 +++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/becca/entities/battribute.js b/src/becca/entities/battribute.js index ca14a90c0..49b9fa258 100644 --- a/src/becca/entities/battribute.js +++ b/src/becca/entities/battribute.js @@ -96,7 +96,7 @@ class BAttribute extends AbstractBeccaEntity { } if (this.type === 'relation' && !(this.value in this.becca.notes)) { - throw new Error(`Cannot save relation '${this.name}' of note '${this.noteId}' since it target not existing note '${this.value}'.`); + throw new Error(`Cannot save relation '${this.name}' of note '${this.noteId}' since it targets not existing note '${this.value}'.`); } } diff --git a/src/becca/entities/bnote.js b/src/becca/entities/bnote.js index 960b35234..2e9febadb 100644 --- a/src/becca/entities/bnote.js +++ b/src/becca/entities/bnote.js @@ -97,7 +97,7 @@ class BNote extends AbstractBeccaEntity { * @private */ this.parents = []; /** @type {BNote[]} - * @private*/ + * @private */ this.children = []; /** @type {BAttribute[]} * @private */ @@ -107,11 +107,11 @@ class BNote extends AbstractBeccaEntity { * @private */ this.__attributeCache = null; /** @type {BAttribute[]|null} - * @private*/ + * @private */ this.inheritableAttributeCache = null; /** @type {BAttribute[]} - * @private*/ + * @private */ this.targetRelations = []; this.becca.addNote(this.noteId, this); diff --git a/src/services/notes.js b/src/services/notes.js index 3da2f56fc..d526372d2 100644 --- a/src/services/notes.js +++ b/src/services/notes.js @@ -841,7 +841,7 @@ function duplicateSubtree(origNoteId, newParentNoteId) { throw new Error('Duplicating root is not possible'); } - log.info(`Duplicating ${origNoteId} subtree into ${newParentNoteId}`); + log.info(`Duplicating '${origNoteId}' subtree into '${newParentNoteId}'`); const origNote = becca.notes[origNoteId]; // might be null if orig note is not in the target newParentNoteId @@ -919,7 +919,8 @@ function duplicateSubtreeInner(origNote, origBranch, newParentNoteId, noteIdMapp attr.value = noteIdMapping[attr.value]; } - attr.save(); + // the relation targets may not be created yet, the mapping is pre-generated + attr.save({skipValidation: true}); } for (const childBranch of origNote.getChildBranches()) { From ee60652746f4e770a12f2575ac7eff9493f3168a Mon Sep 17 00:00:00 2001 From: zadam Date: Sun, 9 Apr 2023 23:08:24 +0200 Subject: [PATCH 45/46] eslint config --- .eslintrc.js | 16 + .idea/inspectionProfiles/Project_Default.xml | 2 +- .idea/jsLinters/eslint.xml | 6 + package-lock.json | 1190 +++++++++++++++++- package.json | 1 + src/routes/api/options.js | 2 +- src/services/backend_script_api.js | 2 +- src/services/script.js | 2 +- src/services/search/services/lex.js | 1 + 9 files changed, 1216 insertions(+), 6 deletions(-) create mode 100644 .eslintrc.js create mode 100644 .idea/jsLinters/eslint.xml diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 000000000..c554a263c --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,16 @@ +module.exports = { + "env": { + "browser": true, + "commonjs": true, + "es2021": true, + "node": true + }, + "extends": "eslint:recommended", + "overrides": [ + ], + "parserOptions": { + "ecmaVersion": "latest" + }, + "rules": { + } +} diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml index 84795bdad..22cdf9bd9 100644 --- a/.idea/inspectionProfiles/Project_Default.xml +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -1,7 +1,7 @@