Compare commits

...

151 commits

Author SHA1 Message Date
Daniel
f1c91863b9
🔖 Release v3.3.2
Some checks failed
Release Docker Image / build (push) Has been cancelled
Signed-off-by: Daniel <845765@qq.com>
2025-09-09 18:15:27 +08:00
Daniel
8a9e746891
🎨 Clean code
Signed-off-by: Daniel <845765@qq.com>
2025-09-09 18:11:49 +08:00
Jeffrey Chen
517f5c8453
🎨 Hide the separator line in the top bar plugin menu in publish service (#15809) 2025-09-09 18:08:21 +08:00
Vanessa
88431279bf 🎨 https://github.com/siyuan-note/siyuan/issues/15806 2025-09-09 17:32:35 +08:00
Vanessa
dc656d83a2 🎨 https://github.com/siyuan-note/siyuan/issues/15806 2025-09-09 16:43:39 +08:00
Vanessa
b69fd04137 🎨 https://github.com/siyuan-note/siyuan/issues/15806 2025-09-09 10:18:44 +08:00
Vanessa
ff909fa149 🎨 https://github.com/siyuan-note/siyuan/issues/15805 2025-09-09 10:02:51 +08:00
Vanessa
bfe50d9009 🚨 2025-09-09 09:29:00 +08:00
Daniel
93422c134d
🎨 Add field disabledInPublish to the code snippet to indicate whether it is disabled in the publish service https://github.com/siyuan-note/siyuan/issues/15806
Signed-off-by: Daniel <845765@qq.com>
2025-09-09 09:18:12 +08:00
Daniel
2f70ef43a1
🎨 Clean code
Signed-off-by: Daniel <845765@qq.com>
2025-09-09 09:07:23 +08:00
Daniel
5f6ddb4655
📝 Update changelogs
Signed-off-by: Daniel <845765@qq.com>
2025-09-08 19:41:02 +08:00
Daniel
39c4b3325e
🧑‍💻 Improve kernel API appendBlock, insertBlock and prependBlock https://github.com/siyuan-note/siyuan/issues/15798
Signed-off-by: Daniel <845765@qq.com>
2025-09-08 19:24:41 +08:00
Vanessa
393c53941a
🎨 https://github.com/siyuan-note/siyuan/issues/15801
Signed-off-by: Daniel <845765@qq.com>
2025-09-08 17:39:03 +08:00
Daniel
a4f03191fa
🎨 https://github.com/siyuan-note/siyuan/issues/15777 2025-09-08 10:58:58 +08:00
Vanessa
de9e648e9e 🎨 https://github.com/siyuan-note/siyuan/issues/15782 2025-09-08 10:52:40 +08:00
Vanessa
c1f14a33d9 🎨 https://github.com/siyuan-note/siyuan/pull/15731 2025-09-08 10:06:52 +08:00
Jeffrey Chen
adca241ed5
🎨 Improve slash menu (#15731)
fix https://github.com/siyuan-note/siyuan/issues/12518
2025-09-08 09:57:36 +08:00
Vanessa
006da6bc90 🎨 https://github.com/siyuan-note/siyuan/issues/15782 2025-09-08 09:48:36 +08:00
Vanessa
490234caab 🚨 2025-09-08 09:44:52 +08:00
Daniel
80c357564d
🎨 Regen pnpm-lock.yaml 2025-09-07 21:47:41 +08:00
Daniel
6852a49620
🎨 Improve build script 2025-09-07 21:40:17 +08:00
Daniel
93591ad44e
🐛 Fix NPE https://github.com/siyuan-note/siyuan/issues/15796 2025-09-07 21:05:54 +08:00
Daniel
6510d7dbf0
🧑‍💻 Improve kernel API appendBlock and insertBlock https://github.com/siyuan-note/siyuan/issues/15798 2025-09-07 20:58:38 +08:00
Daniel
29244a1f8c
🧑‍💻 https://github.com/siyuan-note/siyuan/issues/15798 2025-09-07 19:20:44 +08:00
Daniel
a85467751f
⬆️ Upgrade lute 2025-09-07 19:02:52 +08:00
Vanessa
14251d8dae 🎨 https://github.com/siyuan-note/siyuan/pull/15772 2025-09-07 18:40:12 +08:00
Jeffrey Chen
52a4815419
🐛 Improve database date field (#15772)
fix https://github.com/siyuan-note/siyuan/issues/13252 , https://github.com/siyuan-note/siyuan/issues/15747
2025-09-07 18:37:33 +08:00
Vanessa
45a6a190d0 🎨 https://github.com/siyuan-note/siyuan/issues/15185 2025-09-07 18:14:46 +08:00
Vanessa
c1a4aa3128 🐛 https://github.com/siyuan-note/siyuan/issues/15791 2025-09-07 11:01:11 +08:00
Vanessa
0fce405a05 Merge remote-tracking branch 'origin/dev' into dev 2025-09-07 09:59:48 +08:00
Vanessa
fe143bcb12 🎨 https://github.com/siyuan-note/siyuan/issues/8019 2025-09-07 09:59:35 +08:00
Daniel
0ad7c4cf23
🎨 Improve open the user guide https://github.com/siyuan-note/siyuan/issues/15792 2025-09-07 09:35:48 +08:00
Vanessa
c326989391 🎨 https://github.com/siyuan-note/siyuan/issues/8019 2025-09-06 22:47:16 +08:00
Vanessa
468b670bcc 🎨 https://github.com/siyuan-note/siyuan/issues/8019 2025-09-06 22:33:31 +08:00
Vanessa
4e4398ef47 🎨 https://github.com/siyuan-note/siyuan/issues/8019 2025-09-06 18:31:38 +08:00
Vanessa
fc1cbf46aa Merge remote-tracking branch 'origin/dev' into dev 2025-09-06 18:02:31 +08:00
Vanessa
80cccd41b5 🎨 https://github.com/siyuan-note/siyuan/issues/8019 2025-09-06 18:02:18 +08:00
Daniel
68991a6aef
🎨 Copy/Cut folded heading changed to copy/cut Headings and Bottom Blocks and support multiple headings copy/cut https://github.com/siyuan-note/siyuan/issues/8019 2025-09-06 17:30:35 +08:00
Daniel
2a8b47b518
🎨 Copy/Cut folded heading changed to copy/cut Headings and Bottom Blocks and support multiple headings copy/cut https://github.com/siyuan-note/siyuan/issues/8019 2025-09-06 17:15:42 +08:00
Daniel
8ad3cb00ad
🎨 Copy/Cut folded heading changed to copy/cut Headings and Bottom Blocks and support multiple headings copy/cut https://github.com/siyuan-note/siyuan/issues/8019 2025-09-06 17:11:21 +08:00
Daniel
c55c413365
🎨 Copy/Cut folded heading changed to copy/cut Headings and Bottom Blocks and support multiple headings copy/cut https://github.com/siyuan-note/siyuan/issues/8019 2025-09-06 17:10:43 +08:00
Vanessa
4767e399e2 Merge remote-tracking branch 'origin/dev' into dev 2025-09-06 10:22:29 +08:00
Vanessa
5ade06a3b6 🎨 https://github.com/siyuan-note/siyuan/issues/15609 2025-09-06 10:22:16 +08:00
Daniel
8ebb617072
📝 Database rollup field filtering rules support "Any", "All", and "None" https://github.com/siyuan-note/siyuan/issues/15609 2025-09-06 08:43:59 +08:00
Daniel
305bd9dfb0
🎨 Improve duplicating doc/av https://github.com/siyuan-note/siyuan/issues/15786 2025-09-06 08:28:54 +08:00
Vanessa
d2f990a830 🎨 https://github.com/siyuan-note/siyuan/issues/15609 2025-09-05 23:44:46 +08:00
Vanessa
5775aa9734 Merge remote-tracking branch 'origin/dev' into dev 2025-09-05 23:38:13 +08:00
Vanessa
80f1c6c3ec 🎨 https://github.com/siyuan-note/siyuan/issues/15609 2025-09-05 23:37:58 +08:00
Daniel
f220e3627f
📝 Database rollup field filtering rules support "Any", "All", and "None" https://github.com/siyuan-note/siyuan/issues/15609 2025-09-05 23:15:20 +08:00
Daniel
1fb4ed980b
⬆️ Upgrade lute 2025-09-05 22:51:41 +08:00
Daniel
04bf9e9848
🎨 Improve av https://github.com/siyuan-note/siyuan/issues/15775 2025-09-05 17:44:03 +08:00
Daniel
9447f1c5a8
🎨 Clean code 2025-09-05 17:38:46 +08:00
Vanessa
afa74ebb4b 🎨 https://github.com/siyuan-note/siyuan/issues/15771 2025-09-05 17:16:48 +08:00
Jeffrey Chen
17a96ee1b1
🎨 Dragging multiple files into the editor will cause them to be opened by the default program (#15773) 2025-09-05 12:10:44 +08:00
Vanessa
647204eee1 🎨 https://github.com/siyuan-note/siyuan/issues/15733 2025-09-05 12:01:46 +08:00
Vanessa
4eb91f2e40 Merge remote-tracking branch 'origin/dev' into dev 2025-09-05 11:26:31 +08:00
Vanessa
d48e3d5211 🎨 https://github.com/siyuan-note/siyuan/issues/15771 2025-09-05 11:26:18 +08:00
Jeffrey Chen
59265bfc94
📝 Improve text (#15774) 2025-09-05 10:27:07 +08:00
Daniel
16913fb065
⬆️ Upgrade pnpm 2025-09-05 10:16:25 +08:00
Vanessa
65b52a2bc6 🎨 https://github.com/siyuan-note/siyuan/issues/15771 2025-09-05 08:59:52 +08:00
Vanessa
ac6b1d6689 🎨 https://github.com/siyuan-note/siyuan/issues/15768 2025-09-04 21:45:25 +08:00
Vanessa
7ae90058c3 🎨 https://github.com/siyuan-note/siyuan/issues/15771 2025-09-04 20:48:40 +08:00
Daniel
fdfd453e2b
🎨 https://github.com/siyuan-note/siyuan/issues/15748 2025-09-04 19:53:53 +08:00
Vanessa
0aa5624495 Merge remote-tracking branch 'origin/dev' into dev 2025-09-04 19:48:31 +08:00
Vanessa
0b3cef8964 🎨 https://github.com/siyuan-note/siyuan/issues/15748 2025-09-04 19:48:18 +08:00
Daniel
2c5d4d47a4
🎨 https://github.com/siyuan-note/siyuan/issues/15749 2025-09-04 19:38:49 +08:00
Vanessa
3379d29e67 Merge remote-tracking branch 'origin/dev' into dev 2025-09-04 18:24:04 +08:00
Vanessa
ba95f45b92 🎨 https://github.com/siyuan-note/siyuan/issues/15751 2025-09-04 18:23:51 +08:00
Daniel
ed78e67af2
🎨 Clean code 2025-09-04 18:08:45 +08:00
Daniel
ba10d96a10
Revert "🎨 Add tags to the database when binding blocks to the database https://github.com/siyuan-note/siyuan/issues/15757"
This reverts commit 4d8bc1672c.
2025-09-04 18:00:47 +08:00
Daniel
4d8bc1672c
🎨 Add tags to the database when binding blocks to the database https://github.com/siyuan-note/siyuan/issues/15757 2025-09-04 17:43:18 +08:00
Vanessa
e91a37a98b 🎨 https://github.com/siyuan-note/siyuan/issues/15760 2025-09-04 16:38:07 +08:00
Vanessa
f6bd240a85 Merge remote-tracking branch 'origin/dev' into dev 2025-09-04 16:31:24 +08:00
Vanessa
c08f88156f 🎨 https://github.com/siyuan-note/siyuan/issues/15750 2025-09-04 16:31:12 +08:00
Daniel
74826fc0ce
🎨 Improve database performance https://github.com/siyuan-note/siyuan/issues/15764 2025-09-04 16:17:39 +08:00
Daniel
e1bb9874be
🎨 Clean code 2025-09-04 16:15:03 +08:00
Daniel
2b85cb1b6c
🎨 Improve database performance https://github.com/siyuan-note/siyuan/issues/15764 2025-09-04 16:14:38 +08:00
Daniel
cd8c3a41e6
🎨 Clean code 2025-09-04 15:40:23 +08:00
Jeffrey Chen
bdace41d97
📝 Improve User Guide (#15767)
https://github.com/siyuan-note/siyuan/issues/14430
2025-09-04 15:40:06 +08:00
Vanessa
ea2294e901 🎨 https://github.com/siyuan-note/siyuan/issues/15761 2025-09-04 12:11:22 +08:00
Vanessa
868c9d980a Merge remote-tracking branch 'origin/dev' into dev 2025-09-04 10:30:18 +08:00
Vanessa
2d53c81026 Merge remote-tracking branch 'origin/dev' into dev 2025-09-04 10:30:06 +08:00
Daniel
6ff4439be3
🧑‍💻 Add field disabledInPublish to the marketplace package metadata to indicate whether it is disabled in the publishing service https://github.com/siyuan-note/siyuan/issues/11730 2025-09-04 10:29:58 +08:00
Vanessa
d47a8ffe02 🎨 https://github.com/siyuan-note/siyuan/issues/15639 2025-09-04 10:29:54 +08:00
Daniel
9410a70a2b
🎨 Add marketplace package config item minAppVersion https://github.com/siyuan-note/siyuan/issues/8330 2025-09-04 10:22:57 +08:00
Daniel
3c3f34442f
🎨 Improve bazaar package 2025-09-04 10:14:41 +08:00
Daniel
9dc6f56bff
🎨 Improve bazaar package 2025-09-04 10:14:21 +08:00
Vanessa
22fdaa71ef 🎨 https://github.com/siyuan-note/siyuan/issues/15759 2025-09-03 23:44:04 +08:00
Daniel
fd7dba5ed4
🎨 Update text https://github.com/siyuan-note/siyuan/issues/15759 2025-09-03 23:26:43 +08:00
Daniel
d6a33c8c02
⬆️ Upgrade kernel deps 2025-09-03 22:10:26 +08:00
Daniel
6f2b8e47ae
⬆️ Upgrade lute 2025-09-03 21:50:57 +08:00
Vanessa
aa47a93501 Merge remote-tracking branch 'origin/dev' into dev 2025-09-03 21:36:30 +08:00
Vanessa
0b33edd213 🐛 https://github.com/siyuan-note/siyuan/issues/15741 2025-09-03 21:36:17 +08:00
Daniel
fe3ee14417
🎨 After dragging database entries across groups, groups in other views need to be updated https://github.com/siyuan-note/siyuan/issues/15755 2025-09-03 21:30:50 +08:00
Daniel
543ea20686
⬆️ Upgrade lute 2025-09-03 21:15:50 +08:00
Vanessa
f3358cc8b6 🐛 https://github.com/siyuan-note/siyuan/issues/15756 2025-09-03 21:12:56 +08:00
Vanessa
356356d888 🎨 https://github.com/siyuan-note/siyuan/issues/15226 2025-09-03 20:49:12 +08:00
Vanessa
78a7491173 Merge remote-tracking branch 'origin/dev' into dev 2025-09-03 18:28:26 +08:00
Vanessa
042768550d 🎨 https://github.com/siyuan-note/siyuan/issues/15699 2025-09-03 18:26:53 +08:00
Daniel
cfb976eb89
🐛 PDF files with too long file names cannot generate annotated images https://github.com/siyuan-note/siyuan/issues/15739 https://github.com/siyuan-note/siyuan/issues/10666 2025-09-03 17:37:27 +08:00
Jeffrey Chen
1e95b68df6
📝 Improve User Guide (#15753)
fix https://github.com/siyuan-note/siyuan/issues/14983
2025-09-03 16:40:29 +08:00
Daniel
f35a7f8892
🐛 PDF files with too long file names cannot generate annotated images https://github.com/siyuan-note/siyuan/issues/15739 https://github.com/siyuan-note/siyuan/issues/10666 2025-09-03 11:54:42 +08:00
Daniel
2f64492ee7
⬆️ Upgrade lute 2025-09-03 11:54:42 +08:00
Vanessa
125d18a0e1 🎨 https://github.com/siyuan-note/siyuan/issues/15699 1&3 2025-09-03 11:41:55 +08:00
Vanessa
2738b9adb0 🐛 https://github.com/siyuan-note/siyuan/issues/15742 2025-09-03 10:19:04 +08:00
Vanessa
d8bb794437 Merge remote-tracking branch 'origin/dev' into dev 2025-09-03 09:41:54 +08:00
Vanessa
91626c8fb5 🎨 https://github.com/siyuan-note/siyuan/issues/15639 2025-09-03 09:41:42 +08:00
Daniel
a5d268665d
🎨 Improve database date field filtering https://github.com/siyuan-note/siyuan/issues/15744 2025-09-03 08:56:30 +08:00
Daniel
a26c72d293
🎨 Database rollup field filtering rules support "Any", "All", and "None" https://github.com/siyuan-note/siyuan/issues/15609 2025-09-02 22:04:29 +08:00
Daniel
8cefe5ce47
♻️ Improve cache ds 2025-09-02 18:59:53 +08:00
Daniel
04c46b3a56
🎨 Improve database rollup field filtering https://github.com/siyuan-note/siyuan/issues/15740 2025-09-02 18:37:42 +08:00
Vanessa
7b2e48d54e 🎨 https://github.com/siyuan-note/siyuan/issues/15740 2025-09-02 18:36:38 +08:00
Vanessa
8d2e3bfd20 🎨 https://github.com/siyuan-note/siyuan/issues/15737 2025-09-02 17:16:56 +08:00
Vanessa
7f1f354d4e 🎨 https://github.com/siyuan-note/siyuan/issues/15728 2025-09-02 17:01:35 +08:00
Daniel
b699675b97
🔖 Release v3.3.1
Some checks failed
Release Docker Image / build (push) Has been cancelled
2025-09-02 09:31:45 +08:00
Daniel
74dd8c631c
🔖 Release v3.3.1 2025-09-02 09:24:41 +08:00
Daniel
deb7c5c4fe
🎨 Clean code 2025-09-02 09:24:31 +08:00
Vanessa
216308a511 Merge remote-tracking branch 'origin/dev' into dev 2025-09-01 22:43:45 +08:00
Vanessa
4b29bbcaf8 🎨 https://github.com/siyuan-note/siyuan/issues/15736 2025-09-01 22:43:31 +08:00
Daniel
56085829dd
📝 Update changelogs 2025-09-01 22:26:54 +08:00
Daniel
c202671085
📝 Move changelogs v3.2.x 2025-09-01 22:26:53 +08:00
Vanessa
ba2f7272ca Merge remote-tracking branch 'origin/dev' into dev 2025-09-01 22:19:37 +08:00
Vanessa
b371583899 🎨 https://github.com/siyuan-note/siyuan/pull/15610 2025-09-01 22:19:15 +08:00
Daniel
2de55d2e63
🎨 Improve database template field grouping https://github.com/siyuan-note/siyuan/issues/15687 2025-09-01 17:36:32 +08:00
Daniel
afdd605dd1
🎨 Improve database rollup template rendering https://github.com/siyuan-note/siyuan/issues/15722 2025-09-01 17:10:36 +08:00
Vanessa
aeb478a6b8 Merge remote-tracking branch 'origin/dev' into dev 2025-09-01 12:47:27 +08:00
Vanessa
5c60e8d567 🎨 反链面板移除元素后,文档分屏且为空会重复添加空块 2025-09-01 12:47:14 +08:00
Daniel
7952fec7cb
🎨 Improve database rollup template rendering https://github.com/siyuan-note/siyuan/issues/15722 2025-09-01 12:44:36 +08:00
Daniel
50956851c8
🎨 Improve av 2025-09-01 12:15:40 +08:00
Vanessa
e015f72945 https://github.com/siyuan-note/siyuan/issues/15734 2025-09-01 11:13:53 +08:00
Vanessa
22d34c755b Merge remote-tracking branch 'origin/dev' into dev 2025-09-01 11:12:01 +08:00
Vanessa
8a9a8e4548 🐛 https://github.com/siyuan-note/siyuan/issues/14269 2025-09-01 11:10:16 +08:00
Daniel
16d5055b09
🎨 Improve av 2025-09-01 10:36:42 +08:00
Daniel
1cac4ae55b
🎨 Block ref search and global search results display reference counts https://github.com/siyuan-note/siyuan/issues/15721 2025-08-31 13:07:50 +08:00
Vanessa
b8bcf76f75 🎨 https://github.com/siyuan-note/siyuan/pull/15693 2025-08-31 11:47:04 +08:00
Vanessa
be58df4d45 🚨 2025-08-31 11:44:12 +08:00
Vanessa
3404395cfa 🚨 2025-08-31 11:42:49 +08:00
Achuan-2
c8a3ec52d7
dynamic icon use current date as default (#15693)
*  dynamic icon use current date  as default

* 💄add dynamicIconDateEmptyInfo
2025-08-31 11:41:03 +08:00
Vanessa
698586bd4d 🎨 https://github.com/siyuan-note/siyuan/issues/14269 2025-08-31 11:38:30 +08:00
Daniel
c287dd080b
🎨 Improve av https://github.com/siyuan-note/siyuan/issues/15708#issuecomment-3239639795 2025-08-31 10:44:56 +08:00
Daniel
4744429550
🎨 Improve av https://github.com/siyuan-note/siyuan/issues/15708#issuecomment-3239370576 2025-08-31 08:44:38 +08:00
Daniel
ef0e29a6fd
🎨 Improve av 2025-08-31 08:44:26 +08:00
Vanessa
cd65fa9d44 Merge remote-tracking branch 'origin/dev' into dev 2025-08-31 01:07:27 +08:00
Vanessa
d1f95b7df5 🎨 https://github.com/siyuan-note/siyuan/issues/14269 2025-08-31 01:07:13 +08:00
Daniel
74304e9cba
🎨 Block ref search and global search results display reference counts https://github.com/siyuan-note/siyuan/issues/15721 2025-08-30 21:09:16 +08:00
Daniel
ab66716178
🧑‍💻 Add internal kernel API /api/av/getAttributeViewBoundBlockIDs and getAttributeViewItemIDs https://github.com/siyuan-note/siyuan/issues/15708 2025-08-30 19:09:09 +08:00
Daniel
3c8c096d83
🐛 When searching for document tags, keyword highlighting will have extra pound signs https://github.com/siyuan-note/siyuan/issues/15690 2025-08-30 18:41:56 +08:00
Daniel
e4b2ffb188
🎨 Improve av 2025-08-30 17:38:09 +08:00
Daniel
7a2e5782d8
🐛 The update time of the database checkbox field keeps changing https://github.com/siyuan-note/siyuan/issues/15707 2025-08-30 17:26:23 +08:00
Daniel
b51f283e35
🐛 The update time of the database checkbox field keeps changing https://github.com/siyuan-note/siyuan/issues/15707 2025-08-30 17:26:23 +08:00
Jeffrey Chen
d60553983a
📝 Improve the confirmation popup text when deleting bidirectional relation fields in the database (#15720)
fix https://github.com/siyuan-note/siyuan/issues/15702
2025-08-30 09:36:03 +08:00
129 changed files with 3866 additions and 1370 deletions

View file

@ -7,7 +7,7 @@
## NPM dependencies ## NPM dependencies
Install pnpm: `npm install -g pnpm@10.15.0` Install pnpm: `npm install -g pnpm@10.15.1`
<details> <details>
<summary>For China mainland</summary> <summary>For China mainland</summary>

View file

@ -7,7 +7,7 @@
## NPM 依赖 ## NPM 依赖
安装 pnpm`npm install -g pnpm@10.15.0` 安装 pnpm`npm install -g pnpm@10.15.1`
<details> <details>
<summary>适用于中国大陆</summary> <summary>适用于中国大陆</summary>

View file

@ -41,7 +41,7 @@
"reconnectPrompt": "بعد تبديل التطبيقات، سيستغرق الأمر بعض الوقت لاستعادة تشغيل نواة SiYuan. يرجى الانتظار بضع ثوانٍ أو النقر فوق الزر \"إعادة المحاولة\"", "reconnectPrompt": "بعد تبديل التطبيقات، سيستغرق الأمر بعض الوقت لاستعادة تشغيل نواة SiYuan. يرجى الانتظار بضع ثوانٍ أو النقر فوق الزر \"إعادة المحاولة\"",
"relativeFontSize": "نسبة إلى حجم خط المحرر", "relativeFontSize": "نسبة إلى حجم خط المحرر",
"localFileSystem": "نظام الملفات المحلي", "localFileSystem": "نظام الملفات المحلي",
"deviceNotSupport": "الجهاز الحالي غير مدعوم", "mobileNotSupport": "هذه الميزة غير مدعومة حاليًا على الأجهزة المحمولة (الهاتف أو الجهاز اللوحي)",
"second": "ثانية", "second": "ثانية",
"syncInterval": "الفاصل الزمني للمزامنة", "syncInterval": "الفاصل الزمني للمزامنة",
"syncIntervalTip": "مزامنة البيانات تلقائياً بعد أن توقف عن التغيير", "syncIntervalTip": "مزامنة البيانات تلقائياً بعد أن توقف عن التغيير",
@ -53,13 +53,15 @@
"dataRepoAutoPurgeIndexRetentionDays": "عدد أيام حفظ لقطة البيانات", "dataRepoAutoPurgeIndexRetentionDays": "عدد أيام حفظ لقطة البيانات",
"dataRepoAutoPurgeRetentionIndexesDaily": "عدد لقطات البيانات في اليوم", "dataRepoAutoPurgeRetentionIndexesDaily": "عدد لقطات البيانات في اليوم",
"fields": "حقول", "fields": "حقول",
"dynamicEmoji": "أيقونة ديناميكية", "dynamicIcon": "أيقونة ديناميكية",
"dynamicIconDateEmptyInfo": "مسح التاريخ، سيعرض رمز التقويم تاريخ اليوم ديناميكيًا",
"backlinkContainChildren": "جعل الروابط المرجعية تحتوي على كتل فرعية", "backlinkContainChildren": "جعل الروابط المرجعية تحتوي على كتل فرعية",
"backlinkContainChildrenTip": "عند التمكين، سيتم تضمين الكتل الفرعية في حساب الروابط المرجعية", "backlinkContainChildrenTip": "عند التمكين، سيتم تضمين الكتل الفرعية في حساب الروابط المرجعية",
"entryNum": "عدد المدخلات", "entryNum": "عدد المدخلات",
"workspaceData": "بيانات مساحة العمل", "workspaceData": "بيانات مساحة العمل",
"confirmRemoveRelationField": "‫هل أنت متأكد من أنك تريد حذف الحقل المرتبط بـ <b>${x}</b>؟‬", "confirmRemoveRelationField": "‫هل أنت متأكد من أنك تريد حذف الحقل <b>${x}</b>؟ بعد حذف هذا الحقل، سيتم حذف حقل العلاقة ثنائية الاتجاه <b>${z}</b> في قاعدة البيانات <b>${y}</b> أيضًا بشكل متزامن.",
"removeButKeepRelationField": "احذف، لكن حفظ الحقل المرتبط", "removeBothRelationField": "حذف كلا الحقلين",
"removeButKeepRelationField": "احذف هذا الحقل فقط، احتفظ بحقل العلاقة ثنائية الاتجاه",
"exportPDFLowMemory": "‫الذاكرة المتاحة غير كافية لتصدير هذا PDF، يرجى تقليل المحتوى أو زيادة الذاكرة المتاحة ومحاولة التصدير مرة أخرى‬", "exportPDFLowMemory": "‫الذاكرة المتاحة غير كافية لتصدير هذا PDF، يرجى تقليل المحتوى أو زيادة الذاكرة المتاحة ومحاولة التصدير مرة أخرى‬",
"exportConf": "إعدادات التصدير", "exportConf": "إعدادات التصدير",
"exportConfTip": "‫لن يتم تصدير الحساب، رمز الإذن بالوصول، المزامنة، رمز API ومفتاح مستودع البيانات‬", "exportConfTip": "‫لن يتم تصدير الحساب، رمز الإذن بالوصول، المزامنة، رمز API ومفتاح مستودع البيانات‬",
@ -129,6 +131,7 @@
"updateLayout": "تحديث التصميم", "updateLayout": "تحديث التصميم",
"dndFolderTip": "‫يرجى ملاحظة أن ${x} يقوم فقط بإدراج رابط file:// ولا يقوم بنسخ الملف‬", "dndFolderTip": "‫يرجى ملاحظة أن ${x} يقوم فقط بإدراج رابط file:// ولا يقوم بنسخ الملف‬",
"removeCol": "‫هل أنت متأكد من أنك تريد حذف حقل <b>${x}</b> في قاعدة البيانات؟‬", "removeCol": "‫هل أنت متأكد من أنك تريد حذف حقل <b>${x}</b> في قاعدة البيانات؟‬",
"removeColConfirm": "⚠️ حذف الحقل",
"video": "الفيديو", "video": "الفيديو",
"audio": "الصوت", "audio": "الصوت",
"updateAll": "تحديث الكل", "updateAll": "تحديث الكل",
@ -337,6 +340,9 @@
"filterOperatorIsAfter": "بعد", "filterOperatorIsAfter": "بعد",
"filterOperatorIsOnOrBefore": "في أو قبل", "filterOperatorIsOnOrBefore": "في أو قبل",
"filterOperatorIsOnOrAfter": "في أو بعد", "filterOperatorIsOnOrAfter": "في أو بعد",
"filterQuantifierAny": "أي",
"filterQuantifierAll": "الكل",
"filterQuantifierNone": "لا شيء",
"asc": "تصاعدي", "asc": "تصاعدي",
"desc": "تنازلي", "desc": "تنازلي",
"hideCol": "إخفاء الحقل", "hideCol": "إخفاء الحقل",
@ -1118,7 +1124,7 @@
"fileTree3": "لا يتطلب تأكيد عند حذف المستندات", "fileTree3": "لا يتطلب تأكيد عند حذف المستندات",
"fileTree4": "في حالة عدم التمكين، سوف يظهر مربع التأكيد في كل مرة تقوم فيها بحذف مستند", "fileTree4": "في حالة عدم التمكين، سوف يظهر مربع التأكيد في كل مرة تقوم فيها بحذف مستند",
"fileTree5": "موقع حفظ المستند الجديد المنشَأ من المرجع", "fileTree5": "موقع حفظ المستند الجديد المنشَأ من المرجع",
"fileTree6": "‫عند استخدام <code class='fn__code'>((</code>، مسار حفظ المستند الجديد (على سبيل المثال، <code class='fn__code'>/folder1/{{now | date \"20060102150405\"}}/</code>)", "fileTree6": "‫عند استخدام <code class='fn__code'>((</code> أو <code class='fn__code'>[[</code>، مسار حفظ المستند الجديد (على سبيل المثال، <code class='fn__code'>/folder1/{{now | date \"20060102150405\"}}/</code>)",
"fileTree7": "فتح في علامة التبويب الحالية", "fileTree7": "فتح في علامة التبويب الحالية",
"fileTree8": "سيتم استبدال علامة التبويب المستند المفتوحة حديثا علامة التبويب غير المعدلة", "fileTree8": "سيتم استبدال علامة التبويب المستند المفتوحة حديثا علامة التبويب غير المعدلة",
"fileTree9": "إغلاق جميع علامات التبويب عند بدء التشغيل", "fileTree9": "إغلاق جميع علامات التبويب عند بدء التشغيل",
@ -1656,6 +1662,7 @@
"268": "يرجى ملاحظة أن الملف [%s] قد تجاوز بالفعل [%d MB]‎، وقد يؤدي ذلك إلى انخفاض الأداء", "268": "يرجى ملاحظة أن الملف [%s] قد تجاوز بالفعل [%d MB]‎، وقد يؤدي ذلك إلى انخفاض الأداء",
"269": "تمت إضافة هذا المقطع بالفعل إلى قاعدة البيانات [%s]", "269": "تمت إضافة هذا المقطع بالفعل إلى قاعدة البيانات [%s]",
"270": "يتم تحسين فهرس البيانات، يرجى الانتظار...", "270": "يتم تحسين فهرس البيانات، يرجى الانتظار...",
"271": "اكتملت عملية تحسين فهرس البيانات، تم تحرير [%s] من مساحة القرص" "271": "اكتملت عملية تحسين فهرس البيانات، تم تحرير [%s] من مساحة القرص",
"272": "حقل غير مسمى"
} }
} }

View file

@ -41,7 +41,7 @@
"reconnectPrompt": "Nach dem Wechseln der Anwendungen dauert es einige Zeit, bis der Betrieb des SiYuan-Kernels wiederhergestellt ist. Bitte warten Sie einige Sekunden oder klicken Sie auf die Schaltfläche „Erneut versuchen“", "reconnectPrompt": "Nach dem Wechseln der Anwendungen dauert es einige Zeit, bis der Betrieb des SiYuan-Kernels wiederhergestellt ist. Bitte warten Sie einige Sekunden oder klicken Sie auf die Schaltfläche „Erneut versuchen“",
"relativeFontSize": "relativ zur Schriftgröße des Editors", "relativeFontSize": "relativ zur Schriftgröße des Editors",
"localFileSystem": "Lokales Dateisystem", "localFileSystem": "Lokales Dateisystem",
"deviceNotSupport": "Das aktuelle Gerät wird nicht unterstützt", "mobileNotSupport": "Diese Funktion wird derzeit auf mobilen Geräten (Telefon oder Tablet) nicht unterstützt",
"second": "Sekunde", "second": "Sekunde",
"syncInterval": "Synchronisierungsintervall", "syncInterval": "Synchronisierungsintervall",
"syncIntervalTip": "Automatische Datensynchronisierung, nachdem die Daten nicht mehr geändert werden", "syncIntervalTip": "Automatische Datensynchronisierung, nachdem die Daten nicht mehr geändert werden",
@ -53,13 +53,15 @@
"dataRepoAutoPurgeIndexRetentionDays": "Daten-Snapshot-Aufbewahrungstage", "dataRepoAutoPurgeIndexRetentionDays": "Daten-Snapshot-Aufbewahrungstage",
"dataRepoAutoPurgeRetentionIndexesDaily": "Daten-Snapshots pro Tag", "dataRepoAutoPurgeRetentionIndexesDaily": "Daten-Snapshots pro Tag",
"fields": "Attribut", "fields": "Attribut",
"dynamicEmoji": "Dynamisches Icon", "dynamicIcon": "Dynamisches Icon",
"dynamicIconDateEmptyInfo": "Datum löschen, das Kalender-Symbol zeigt dynamisch das heutige Datum an",
"backlinkContainChildren": "Enthalten Rückverweise untergeordnete Blöcke", "backlinkContainChildren": "Enthalten Rückverweise untergeordnete Blöcke",
"backlinkContainChildrenTip": "Wenn aktiviert, werden untergeordnete Blöcke in die Berechnung der Rückverweise einbezogen", "backlinkContainChildrenTip": "Wenn aktiviert, werden untergeordnete Blöcke in die Berechnung der Rückverweise einbezogen",
"entryNum": "Anzahl der Einträge", "entryNum": "Anzahl der Einträge",
"workspaceData": "Arbeitsbereichsdaten", "workspaceData": "Arbeitsbereichsdaten",
"confirmRemoveRelationField": "Sind Sie sicher, dass Sie das Feld, das mit <b>${x}</b> verknüpft ist, löschen möchten?", "confirmRemoveRelationField": "Sind Sie sicher, dass Sie das <b>${x}</b> Feld löschen möchten? Nach dem Löschen dieses Feldes wird das bidirektionale Beziehungsfeld <b>${z}</b> in der <b>${y}</b> Datenbank ebenfalls synchron gelöscht.",
"removeButKeepRelationField": "Entfernen, aber verknüpftes Feld behalten", "removeBothRelationField": "Beide Felder entfernen",
"removeButKeepRelationField": "Nur dieses Feld entfernen, bidirektionales Beziehungsfeld behalten",
"exportPDFLowMemory": "Nicht genügend verfügbarer Speicher, um dieses PDF zu exportieren, bitte reduzieren Sie den Inhalt oder erhöhen Sie den verfügbaren Speicher und versuchen Sie es erneut", "exportPDFLowMemory": "Nicht genügend verfügbarer Speicher, um dieses PDF zu exportieren, bitte reduzieren Sie den Inhalt oder erhöhen Sie den verfügbaren Speicher und versuchen Sie es erneut",
"exportConf": "Export-Einstellungen", "exportConf": "Export-Einstellungen",
"exportConfTip": "Konto, Zugriffscode, Synchronisation, API-Token und Daten-Repo-Schlüssel werden nicht exportiert", "exportConfTip": "Konto, Zugriffscode, Synchronisation, API-Token und Daten-Repo-Schlüssel werden nicht exportiert",
@ -129,6 +131,7 @@
"updateLayout": "Layout aktualisieren", "updateLayout": "Layout aktualisieren",
"dndFolderTip": "Bitte beachten Sie, dass ${x} nur den file:// Hyperlink einfügt und die Datei nicht kopiert.", "dndFolderTip": "Bitte beachten Sie, dass ${x} nur den file:// Hyperlink einfügt und die Datei nicht kopiert.",
"removeCol": "Sind Sie sicher, dass Sie die <b>${x}</b> Spalte in der Datenbank löschen möchten?", "removeCol": "Sind Sie sicher, dass Sie die <b>${x}</b> Spalte in der Datenbank löschen möchten?",
"removeColConfirm": "⚠️ Spalte löschen",
"video": "Video", "video": "Video",
"audio": "Audio", "audio": "Audio",
"updateAll": "Alle aktualisieren", "updateAll": "Alle aktualisieren",
@ -337,6 +340,9 @@
"filterOperatorIsAfter": "Ist nach", "filterOperatorIsAfter": "Ist nach",
"filterOperatorIsOnOrBefore": "Ist am oder vor", "filterOperatorIsOnOrBefore": "Ist am oder vor",
"filterOperatorIsOnOrAfter": "Ist am oder nach", "filterOperatorIsOnOrAfter": "Ist am oder nach",
"filterQuantifierAny": "Beliebig",
"filterQuantifierAll": "Alle",
"filterQuantifierNone": "Keine",
"asc": "Aufsteigend", "asc": "Aufsteigend",
"desc": "Absteigend", "desc": "Absteigend",
"hideCol": "Spalte ausblenden", "hideCol": "Spalte ausblenden",
@ -1118,7 +1124,7 @@
"fileTree3": "Keine Bestätigung erforderlich beim Löschen von Dokumenten", "fileTree3": "Keine Bestätigung erforderlich beim Löschen von Dokumenten",
"fileTree4": "Wenn nicht aktiviert, wird jedes Mal ein Bestätigungsfeld angezeigt, wenn Sie ein Dokument löschen", "fileTree4": "Wenn nicht aktiviert, wird jedes Mal ein Bestätigungsfeld angezeigt, wenn Sie ein Dokument löschen",
"fileTree5": "Referenz erstellt Doc-Speicherort", "fileTree5": "Referenz erstellt Doc-Speicherort",
"fileTree6": "Beim Verwenden von <code class='fn__code'>((</code> der Speicherpfad des neuen Dokuments (z.B. <code class='fn__code'>/folder1/{{now | date \"20060102150405\"}}/</code>)", "fileTree6": "Beim Verwenden von <code class='fn__code'>((</code> oder <code class='fn__code'>[[</code> der Speicherpfad des neuen Dokuments (z.B. <code class='fn__code'>/folder1/{{now | date \"20060102150405\"}}/</code>)",
"fileTree7": "Im aktuellen Tab öffnen", "fileTree7": "Im aktuellen Tab öffnen",
"fileTree8": "Der neu geöffnete Dokumenten-Tab ersetzt den nicht modifizierten Tab", "fileTree8": "Der neu geöffnete Dokumenten-Tab ersetzt den nicht modifizierten Tab",
"fileTree9": "Alle Tabs beim Start schließen", "fileTree9": "Alle Tabs beim Start schließen",
@ -1656,6 +1662,7 @@
"268": "Bitte beachten Sie, dass die Datei [%s] bereits [%d MB] überschritten hat, was die Leistung beeinträchtigen kann", "268": "Bitte beachten Sie, dass die Datei [%s] bereits [%d MB] überschritten hat, was die Leistung beeinträchtigen kann",
"269": "Dieser Block wurde bereits zur Datenbank [%s] hinzugefügt", "269": "Dieser Block wurde bereits zur Datenbank [%s] hinzugefügt",
"270": "Datenindex wird optimiert, bitte warten...", "270": "Datenindex wird optimiert, bitte warten...",
"271": "Datenindex-Optimierung abgeschlossen, [%s] Speicherplatz freigegeben" "271": "Datenindex-Optimierung abgeschlossen, [%s] Speicherplatz freigegeben",
"272": "Unbenanntes Feld"
} }
} }

View file

@ -41,7 +41,7 @@
"reconnectPrompt": "After switching applications, it will take some time to restore the SiYuan kernel operation. Please wait a few seconds or click the \"Retry\" button", "reconnectPrompt": "After switching applications, it will take some time to restore the SiYuan kernel operation. Please wait a few seconds or click the \"Retry\" button",
"relativeFontSize": "relative to the editor font size", "relativeFontSize": "relative to the editor font size",
"localFileSystem": "Local file system", "localFileSystem": "Local file system",
"deviceNotSupport": "The current device is not supported", "mobileNotSupport": "This feature is currently not supported on mobile devices (phone or tablet)",
"second": "second", "second": "second",
"syncInterval": "sync interval", "syncInterval": "sync interval",
"syncIntervalTip": "Automatically sync data after it stops changing", "syncIntervalTip": "Automatically sync data after it stops changing",
@ -53,13 +53,15 @@
"dataRepoAutoPurgeIndexRetentionDays": "Data snapshot retention days", "dataRepoAutoPurgeIndexRetentionDays": "Data snapshot retention days",
"dataRepoAutoPurgeRetentionIndexesDaily": "Data snapshots per day", "dataRepoAutoPurgeRetentionIndexesDaily": "Data snapshots per day",
"fields": "Fields", "fields": "Fields",
"dynamicEmoji": "Dynamic icon", "dynamicIcon": "Dynamic icon",
"dynamicIconDateEmptyInfo": "Clear the date, the calendar icon will dynamically display todays date",
"backlinkContainChildren": "Do backlinks contain child blocks", "backlinkContainChildren": "Do backlinks contain child blocks",
"backlinkContainChildrenTip": "When enabled, child blocks will be included in the backlink calculation", "backlinkContainChildrenTip": "When enabled, child blocks will be included in the backlink calculation",
"entryNum": "Number of entries", "entryNum": "Number of entries",
"workspaceData": "Workspace data", "workspaceData": "Workspace data",
"confirmRemoveRelationField": "Are you sure you want to delete the field associated with <b>${x}</b>?", "confirmRemoveRelationField": "Are you sure you want to delete the <b>${x}</b> field? After deleting this field, the bidirectional relation field <b>${z}</b> in the <b>${y}</b> database will also be deleted synchronously.",
"removeButKeepRelationField": "Remove, but keep related field", "removeBothRelationField": "Remove both fields",
"removeButKeepRelationField": "Remove only this field, keep bidirectional relation field",
"exportPDFLowMemory": "Insufficient available memory to export this PDF, please reduce the content or increase available memory and try exporting again", "exportPDFLowMemory": "Insufficient available memory to export this PDF, please reduce the content or increase available memory and try exporting again",
"exportConf": "Export settings", "exportConf": "Export settings",
"exportConfTip": "Account, access authorization code, synchronization, API token and data repo key will not be exported", "exportConfTip": "Account, access authorization code, synchronization, API token and data repo key will not be exported",
@ -129,6 +131,7 @@
"updateLayout": "Update layout", "updateLayout": "Update layout",
"dndFolderTip": "Please note that ${x} only inserts the file:// hyperlink and does not copy the file", "dndFolderTip": "Please note that ${x} only inserts the file:// hyperlink and does not copy the file",
"removeCol": "Are you sure you want to delete the <b>${x}</b> field in the database?", "removeCol": "Are you sure you want to delete the <b>${x}</b> field in the database?",
"removeColConfirm": "⚠️ Delete field",
"video": "Video", "video": "Video",
"audio": "Audio", "audio": "Audio",
"updateAll": "Update all", "updateAll": "Update all",
@ -337,6 +340,9 @@
"filterOperatorIsAfter": "Is after", "filterOperatorIsAfter": "Is after",
"filterOperatorIsOnOrBefore": "Is on or before", "filterOperatorIsOnOrBefore": "Is on or before",
"filterOperatorIsOnOrAfter": "Is on or after", "filterOperatorIsOnOrAfter": "Is on or after",
"filterQuantifierAny": "Any",
"filterQuantifierAll": "All",
"filterQuantifierNone": "None",
"asc": "Ascending", "asc": "Ascending",
"desc": "Descending", "desc": "Descending",
"hideCol": "Hide field", "hideCol": "Hide field",
@ -1118,7 +1124,7 @@
"fileTree3": "No confirmation required when deleting documents", "fileTree3": "No confirmation required when deleting documents",
"fileTree4": "If not enabled, a confirmation box will pop up every time you delete a document", "fileTree4": "If not enabled, a confirmation box will pop up every time you delete a document",
"fileTree5": "Ref create doc save location", "fileTree5": "Ref create doc save location",
"fileTree6": "When using <code class='fn__code'>((</code>, the save path of the new document (for example, <code class='fn__code'>/folder1/{{now | date \"20060102150405\"}}/</code>)", "fileTree6": "When using <code class='fn__code'>((</code> or <code class='fn__code'>[[</code>, the save path of the new document (for example, <code class='fn__code'>/folder1/{{now | date \"20060102150405\"}}/</code>)",
"fileTree7": "Open in the current tab", "fileTree7": "Open in the current tab",
"fileTree8": "The newly opened document tab will replace the unmodified tab", "fileTree8": "The newly opened document tab will replace the unmodified tab",
"fileTree9": "Close all tabs at startup", "fileTree9": "Close all tabs at startup",
@ -1656,6 +1662,7 @@
"268": "Please note that the file [%s] has already exceeded [%d MB], which may cause performance degradation", "268": "Please note that the file [%s] has already exceeded [%d MB], which may cause performance degradation",
"269": "This block has already been added to the database [%s]", "269": "This block has already been added to the database [%s]",
"270": "Optimizing data index, please wait...", "270": "Optimizing data index, please wait...",
"271": "Data index optimization completed, [%s] disk space freed" "271": "Data index optimization completed, [%s] disk space freed",
"272": "Unnamed field"
} }
} }

View file

@ -41,7 +41,7 @@
"reconnectPrompt": "Después de cambiar de aplicación, tomará algún tiempo restaurar el funcionamiento del núcleo de SiYuan. Espere unos segundos o haga clic en el botón \"Reintentar\"", "reconnectPrompt": "Después de cambiar de aplicación, tomará algún tiempo restaurar el funcionamiento del núcleo de SiYuan. Espere unos segundos o haga clic en el botón \"Reintentar\"",
"relativeFontSize": "en relación con el tamaño de fuente del editor", "relativeFontSize": "en relación con el tamaño de fuente del editor",
"localFileSystem": "Sistema de archivos local", "localFileSystem": "Sistema de archivos local",
"deviceNotSupport": "El dispositivo actual no es compatible", "mobileNotSupport": "Esta función no está disponible actualmente en dispositivos móviles (teléfono o tableta)",
"second": "segundo", "second": "segundo",
"syncInterval": "intervalo de sincronización", "syncInterval": "intervalo de sincronización",
"syncIntervalTip": "Sincronización automática de datos después de que los datos dejen de cambiar", "syncIntervalTip": "Sincronización automática de datos después de que los datos dejen de cambiar",
@ -53,13 +53,15 @@
"dataRepoAutoPurgeIndexRetentionDays": "Días de retención de instantáneas de datos", "dataRepoAutoPurgeIndexRetentionDays": "Días de retención de instantáneas de datos",
"dataRepoAutoPurgeRetentionIndexesDaily": "Número de instantáneas de datos por día", "dataRepoAutoPurgeRetentionIndexesDaily": "Número de instantáneas de datos por día",
"fields": "Atributo", "fields": "Atributo",
"dynamicEmoji": "Icono dinámico", "dynamicIcon": "Icono dinámico",
"dynamicIconDateEmptyInfo": "Borrar la fecha, el icono del calendario mostrará dinámicamente la fecha actual",
"backlinkContainChildren": "¿Los enlaces inversos contienen bloques secundarios?", "backlinkContainChildren": "¿Los enlaces inversos contienen bloques secundarios?",
"backlinkContainChildrenTip": "Una vez habilitado, los bloques secundarios se incluirán en el cálculo de los enlaces inversos", "backlinkContainChildrenTip": "Una vez habilitado, los bloques secundarios se incluirán en el cálculo de los enlaces inversos",
"entryNum": "Número de entradas", "entryNum": "Número de entradas",
"workspaceData": "Datos del espacio de trabajo", "workspaceData": "Datos del espacio de trabajo",
"confirmRemoveRelationField": "¿Está seguro de que desea eliminar el campo asociado a <b>${x}</b>?", "confirmRemoveRelationField": "¿Está seguro de que desea eliminar el campo <b>${x}</b>? Después de eliminar este campo, el campo de relación bidireccional <b>${z}</b> en la base de datos <b>${y}</b> también se eliminará de forma sincrónica.",
"removeButKeepRelationField": "Eliminar, pero mantener el campo relacionado", "removeBothRelationField": "Eliminar ambos campos",
"removeButKeepRelationField": "Eliminar solo este campo, mantener el campo de relación bidireccional",
"exportPDFLowMemory": "Memoria disponible insuficiente para exportar este PDF, por favor reduzca el contenido o aumente la memoria disponible y vuelva a intentar exportar", "exportPDFLowMemory": "Memoria disponible insuficiente para exportar este PDF, por favor reduzca el contenido o aumente la memoria disponible y vuelva a intentar exportar",
"exportConf": "Configuración de exportación", "exportConf": "Configuración de exportación",
"exportConfTip": "Las cuentas, los códigos de acceso, la sincronización, los tokens API y las claves del almacén de datos no se exportarán", "exportConfTip": "Las cuentas, los códigos de acceso, la sincronización, los tokens API y las claves del almacén de datos no se exportarán",
@ -129,6 +131,7 @@
"updateLayout": "Actualizar diseño", "updateLayout": "Actualizar diseño",
"dndFolderTip": "Tenga en cuenta que ${x} solo inserta el hipervínculo file:// y no copia el archivo", "dndFolderTip": "Tenga en cuenta que ${x} solo inserta el hipervínculo file:// y no copia el archivo",
"removeCol": "¿Está seguro de que desea eliminar la columna <b>${x}</b> en la base de datos?", "removeCol": "¿Está seguro de que desea eliminar la columna <b>${x}</b> en la base de datos?",
"removeColConfirm": "⚠️ Eliminar columna",
"vídeo": "Vídeo", "vídeo": "Vídeo",
"audio": "Audio", "audio": "Audio",
"updateAll": "Actualizar todo", "updateAll": "Actualizar todo",
@ -337,6 +340,9 @@
"filterOperatorIsAfter": "Es posterior a", "filterOperatorIsAfter": "Es posterior a",
"filterOperatorIsOnOrBefore": "Está activado o antes", "filterOperatorIsOnOrBefore": "Está activado o antes",
"filterOperatorIsOnOrAfter": "Está encendido o después", "filterOperatorIsOnOrAfter": "Está encendido o después",
"filterQuantifierAny": "Cualquiera",
"filterQuantifierAll": "Todos",
"filterQuantifierNone": "Ninguno",
"asc": "Ascendente", "asc": "Ascendente",
"desc": "Descendente", "desc": "Descendente",
"hideCol": "Ocultar columna", "hideCol": "Ocultar columna",
@ -1118,7 +1124,7 @@
"fileTree3": "No se requiere confirmación al borrar documentos", "fileTree3": "No se requiere confirmación al borrar documentos",
"fileTree4": "Si no se activa, aparecerá un cuadro de confirmación cada vez que se elimine un documento", "fileTree4": "Si no se activa, aparecerá un cuadro de confirmación cada vez que se elimine un documento",
"fileTree5": "Ref crear ubicación de guardado de documentos", "fileTree5": "Ref crear ubicación de guardado de documentos",
"fileTree6": "Al utilizar <code class='fn__code'>((</code>, la ruta de guardado del nuevo documento (por ejemplo, <code class='fn__code'>/carpeta1/{{now | date \"20060102150405\"}}/</code>)", "fileTree6": "Al utilizar <code class='fn__code'>((</code> o <code class='fn__code'>[[</code>, la ruta de guardado del nuevo documento (por ejemplo, <code class='fn__code'>/carpeta1/{{now | date \"20060102150405\"}}/</code>)",
"fileTree7": "Abrir en la pestaña actual", "fileTree7": "Abrir en la pestaña actual",
"fileTree8": "La pestaña del documento recién abierto sustituirá a la pestaña no modificada", "fileTree8": "La pestaña del documento recién abierto sustituirá a la pestaña no modificada",
"fileTree9": "Cerrar todas las pestañas al inicio", "fileTree9": "Cerrar todas las pestañas al inicio",
@ -1656,6 +1662,7 @@
"268": "Atención: el archivo [%s] ya ha superado los [%d MB], lo que puede causar una disminución del rendimiento", "268": "Atención: el archivo [%s] ya ha superado los [%d MB], lo que puede causar una disminución del rendimiento",
"269": "Este bloque ya ha sido añadido a la base de datos [%s]", "269": "Este bloque ya ha sido añadido a la base de datos [%s]",
"270": "Optimizando el índice de datos, por favor espere...", "270": "Optimizando el índice de datos, por favor espere...",
"271": "Optimización del índice de datos completada, se liberaron [%s] de espacio en disco" "271": "Optimización del índice de datos completada, se liberaron [%s] de espacio en disco",
"272": "Campo sin nombre"
} }
} }

View file

@ -1,8 +1,8 @@
{ {
"vacuumDataIndex": "Optimiser lindex", "vacuumDataIndex": "Optimiser l'index",
"vacuumDataIndexTip": "Vérifiez lindex des données, libérez de lespace et améliorez les performances de lindex", "vacuumDataIndexTip": "Vérifiez l'index des données, libérez de l'espace et améliorez les performances de l'index",
"rebuildDataIndex": "Reconstruire lindex", "rebuildDataIndex": "Reconstruire l'index",
"rebuildDataIndexTip": "Reconstruction complète de lindex des données, cela peut prendre du temps, veuillez patienter", "rebuildDataIndexTip": "Reconstruction complète de l'index des données, cela peut prendre du temps, veuillez patienter",
"displayFieldName": "Afficher le nom du champ", "displayFieldName": "Afficher le nom du champ",
"sortBySelectOption": "Trier par option", "sortBySelectOption": "Trier par option",
"groupStep": "Intervalle de regroupement", "groupStep": "Intervalle de regroupement",
@ -41,7 +41,7 @@
"reconnectPrompt": "Après avoir changé d'application, il faudra un certain temps pour rétablir le fonctionnement du noyau SiYuan. Veuillez patienter quelques secondes ou cliquer sur le bouton « Réessayer »", "reconnectPrompt": "Après avoir changé d'application, il faudra un certain temps pour rétablir le fonctionnement du noyau SiYuan. Veuillez patienter quelques secondes ou cliquer sur le bouton « Réessayer »",
"relativeFontSize": "par rapport à la taille de la police de l'éditeur", "relativeFontSize": "par rapport à la taille de la police de l'éditeur",
"localFileSystem": "Système de fichiers local", "localFileSystem": "Système de fichiers local",
"deviceNotSupport": "L'appareil actuel n'est pas pris en charge", "mobileNotSupport": "Cette fonctionnalité n'est pas prise en charge sur les appareils mobiles (téléphone ou tablette) pour le moment",
"second": "seconde", "second": "seconde",
"syncInterval": "intervalle de synchronisation", "syncInterval": "intervalle de synchronisation",
"syncIntervalTip": "Synchronisation automatique des données après l'arrêt des modifications", "syncIntervalTip": "Synchronisation automatique des données après l'arrêt des modifications",
@ -53,13 +53,15 @@
"dataRepoAutoPurgeIndexRetentionDays": "Jours de rétention des instantanés de données", "dataRepoAutoPurgeIndexRetentionDays": "Jours de rétention des instantanés de données",
"dataRepoAutoPurgeRetentionIndexesDaily": "Nombre d'instantanés de données par jour", "dataRepoAutoPurgeRetentionIndexesDaily": "Nombre d'instantanés de données par jour",
"fields": "Attribut", "fields": "Attribut",
"dynamicEmoji": "Icône dynamique", "dynamicIcon": "Icône dynamique",
"dynamicIconDateEmptyInfo": "Effacer la date, licône du calendrier affichera dynamiquement la date du jour",
"backlinkContainChildren": "Les liens retour contiennent-ils des sous-blocs", "backlinkContainChildren": "Les liens retour contiennent-ils des sous-blocs",
"backlinkContainChildrenTip": "Une fois activé, les sous-blocs seront inclus dans le calcul des liens retour", "backlinkContainChildrenTip": "Une fois activé, les sous-blocs seront inclus dans le calcul des liens retour",
"entryNum": "Nombre d'entrées", "entryNum": "Nombre d'entrées",
"workspaceData": "Données de l'espace de travail", "workspaceData": "Données de l'espace de travail",
"confirmRemoveRelationField": "Êtes-vous sûr de vouloir supprimer le champ associé à <b>${x}</b>?", "confirmRemoveRelationField": "Êtes-vous sûr de vouloir supprimer le champ <b>${x}</b> ? Après la suppression de ce champ, le champ de relation bidirectionnelle <b>${z}</b> dans la base de données <b>${y}</b> sera également supprimé de manière synchrone.",
"removeButKeepRelationField": "Supprimer, mais conserver le champ associé", "removeBothRelationField": "Supprimer les deux champs",
"removeButKeepRelationField": "Supprimer seulement ce champ, conserver le champ de relation bidirectionnelle",
"exportPDFLowMemory": "Mémoire disponible insuffisante pour exporter ce PDF, veuillez réduire le contenu ou augmenter la mémoire disponible et réessayer d'exporter", "exportPDFLowMemory": "Mémoire disponible insuffisante pour exporter ce PDF, veuillez réduire le contenu ou augmenter la mémoire disponible et réessayer d'exporter",
"exportConf": "Exporter les paramètres", "exportConf": "Exporter les paramètres",
"exportConfTip": "Les comptes, codes d'accès, synchronisation, tokens API et clés d'entrepôt de données ne seront pas exportés", "exportConfTip": "Les comptes, codes d'accès, synchronisation, tokens API et clés d'entrepôt de données ne seront pas exportés",
@ -129,6 +131,7 @@
"updateLayout": "Mettre à jour la mise en page", "updateLayout": "Mettre à jour la mise en page",
"dndFolderTip": "Veuillez noter que ${x} insère uniquement le lien hypertexte file:// et ne copie pas le fichier", "dndFolderTip": "Veuillez noter que ${x} insère uniquement le lien hypertexte file:// et ne copie pas le fichier",
"removeCol": "Êtes-vous sûr de vouloir supprimer la colonne <b>${x}</b> de la base de données ?", "removeCol": "Êtes-vous sûr de vouloir supprimer la colonne <b>${x}</b> de la base de données ?",
"removeColConfirm": "⚠️ Supprimer la colonne",
"video": "Vidéo", "video": "Vidéo",
"audio": "Audio", "audio": "Audio",
"updateAll": "Tout mettre à jour", "updateAll": "Tout mettre à jour",
@ -337,6 +340,9 @@
"filterOperatorIsAfter": "Est après", "filterOperatorIsAfter": "Est après",
"filterOperatorIsOnOrBefore": "Est le ou avant", "filterOperatorIsOnOrBefore": "Est le ou avant",
"filterOperatorIsOnOrAfter": "Est allumé ou après", "filterOperatorIsOnOrAfter": "Est allumé ou après",
"filterQuantifierAny": "N'importe lequel",
"filterQuantifierAll": "Tous",
"filterQuantifierNone": "Aucun",
"asc": "Ascendant", "asc": "Ascendant",
"desc": "Descendant", "desc": "Descendant",
"hideCol": "Masquer la colonne", "hideCol": "Masquer la colonne",
@ -495,7 +501,7 @@
"workspaceList": "Espaces de travail", "workspaceList": "Espaces de travail",
"removeWorkspaceTip": "Supprimer des espaces de travail", "removeWorkspaceTip": "Supprimer des espaces de travail",
"new": "Nouveau", "new": "Nouveau",
"share2LiandiConfirmTip": "Êtes-vous sûr de vouloir <b>publier</b> ce document dans la <a href=\"${accountServer}\" target=\"_blank\">communauté</a> ?<br>Après la publication, tout le monde pourra voir ce document, assurez-vous qu'il ne contient pas d'informations sensibles", "share2LiandiConfirmTip": "Êtes-vous sûr de vouloir <b>publier</b> ce document dans la <a href=\"${accountServer}\" target=\"_blank\">communauté</a> ?<br>Après la publication, tout le monde pourra voir ce document, assurez-vous qu'il ne contient pas d'informations sensibles",
"share2Liandi": "Partager avec communauté", "share2Liandi": "Partager avec communauté",
"noDueCard": "Excellent travail ! Il n'y a plus de tâches de révision pour le moment, revenez plus tard !", "noDueCard": "Excellent travail ! Il n'y a plus de tâches de révision pour le moment, revenez plus tard !",
"createDeck": "Créer un deck", "createDeck": "Créer un deck",
@ -757,7 +763,7 @@
"findHighlight": "Tout surligner", "findHighlight": "Tout surligner",
"findEntireWord": "Mots entiers", "findEntireWord": "Mots entiers",
"presentationMode": "Basculer en mode présentation", "presentationMode": "Basculer en mode présentation",
"focusOutline": "Trouver lélément de plan actuel", "focusOutline": "Trouver l'élément de plan actuel",
"previousLabel": "Précédent", "previousLabel": "Précédent",
"nextLabel": "Suivant", "nextLabel": "Suivant",
"pageScaleWidth": "Pleine largeur", "pageScaleWidth": "Pleine largeur",
@ -768,12 +774,12 @@
"loading": "Chargement…", "loading": "Chargement…",
"toggleSidebarNotification2Title": "Afficher/Masquer le panneau latéral (le document contient des signets/pièces jointes/calques)", "toggleSidebarNotification2Title": "Afficher/Masquer le panneau latéral (le document contient des signets/pièces jointes/calques)",
"toggleSidebarTitle": "Afficher/Masquer le panneau latéral", "toggleSidebarTitle": "Afficher/Masquer le panneau latéral",
"loadingError": "Une erreur sest produite lors du chargement du fichier PDF.", "loadingError": "Une erreur s'est produite lors du chargement du fichier PDF.",
"invalidFileError": "Fichier PDF invalide ou corrompu.", "invalidFileError": "Fichier PDF invalide ou corrompu.",
"missingFileError": "Fichier PDF manquant.", "missingFileError": "Fichier PDF manquant.",
"unexpectedResponseError": "Réponse inattendue du serveur.", "unexpectedResponseError": "Réponse inattendue du serveur.",
"printingNotSupported": "Attention : limpression nest pas totalement prise en charge par ce navigateur.", "printingNotSupported": "Attention : l'impression n'est pas totalement prise en charge par ce navigateur.",
"printingNotReady": "Attention : le PDF nest pas entièrement chargé pour pouvoir limprimer.", "printingNotReady": "Attention : le PDF n'est pas entièrement chargé pour pouvoir l'imprimer.",
"unitInches": "in", "unitInches": "in",
"unitMillimeters": "mm", "unitMillimeters": "mm",
"additionalLayers": "Calques additionnels", "additionalLayers": "Calques additionnels",
@ -1118,7 +1124,7 @@
"fileTree3": "Aucune confirmation requise lors de la suppression de documents", "fileTree3": "Aucune confirmation requise lors de la suppression de documents",
"fileTree4": "Si non activé, une boîte de confirmation apparaîtra à chaque fois que vous supprimerez un document", "fileTree4": "Si non activé, une boîte de confirmation apparaîtra à chaque fois que vous supprimerez un document",
"fileTree5": "Référence créer doc enregistrer emplacement", "fileTree5": "Référence créer doc enregistrer emplacement",
"fileTree6": "Lors de l'utilisation de <code class='fn__code'>((</code>, le chemin d'enregistrement du nouveau document (par exemple, <code class='fn__code'>/dossier1/{{now | date \"20060102150405\"}}/</code>).", "fileTree6": "Lors de l'utilisation de <code class='fn__code'>((</code> ou <code class='fn__code'>[[</code>, le chemin d'enregistrement du nouveau document (par exemple, <code class='fn__code'>/dossier1/{{now | date \"20060102150405\"}}/</code>).",
"fileTree7": "Ouvrir dans l'Onglet actuel", "fileTree7": "Ouvrir dans l'Onglet actuel",
"fileTree8": "L'onglet du document nouvellement ouvert remplacera l'Onglet non modifié.", "fileTree8": "L'onglet du document nouvellement ouvert remplacera l'Onglet non modifié.",
"fileTree9": "Fermer tous les onglets au démarrage", "fileTree9": "Fermer tous les onglets au démarrage",
@ -1655,7 +1661,8 @@
"267": "Base de données sans nom", "267": "Base de données sans nom",
"268": "Attention : le fichier [%s] a déjà dépassé [%d MB], ce qui peut entraîner une baisse des performances", "268": "Attention : le fichier [%s] a déjà dépassé [%d MB], ce qui peut entraîner une baisse des performances",
"269": "Ce bloc a déjà été ajouté à la base de données [%s]", "269": "Ce bloc a déjà été ajouté à la base de données [%s]",
"270": "Optimisation de lindex des données en cours, veuillez patienter...", "270": "Optimisation de l'index des données en cours, veuillez patienter...",
"271": "Optimisation de lindex des données terminée, [%s] despace disque libéré" "271": "Optimisation de l'index des données terminée, [%s] d'espace disque libéré",
"272": "Champ sans nom"
} }
} }

View file

@ -41,7 +41,7 @@
"reconnectPrompt": "לאחר מעבר בין יישומים, יידרש זמן מה כדי לשחזר את פעולת ליבת SiYuan. אנא המתן מספר שניות או לחץ על כפתור \"נסה שוב\"", "reconnectPrompt": "לאחר מעבר בין יישומים, יידרש זמן מה כדי לשחזר את פעולת ליבת SiYuan. אנא המתן מספר שניות או לחץ על כפתור \"נסה שוב\"",
"relativeFontSize": "יחסית לגודל הגופן של העורך", "relativeFontSize": "יחסית לגודל הגופן של העורך",
"localFileSystem": "מערכת קבצים מקומית", "localFileSystem": "מערכת קבצים מקומית",
"deviceNotSupport": "המכשיר הנוכחי אינו נתמך", "mobileNotSupport": "פונקציה זו אינה נתמכת כרגע במכשירים ניידים (טלפון או טאבלט)",
"second": "שנייה", "second": "שנייה",
"syncInterval": "מרווח סנכרון", "syncInterval": "מרווח סנכרון",
"syncIntervalTip": "סנכרון נתונים אוטומטי לאחר שהנתונים מפסיקים להשתנות", "syncIntervalTip": "סנכרון נתונים אוטומטי לאחר שהנתונים מפסיקים להשתנות",
@ -53,13 +53,15 @@
"dataRepoAutoPurgeIndexRetentionDays": "ימי שמירת תמונות נתונים", "dataRepoAutoPurgeIndexRetentionDays": "ימי שמירת תמונות נתונים",
"dataRepoAutoPurgeRetentionIndexesDaily": "מספר תמונות נתונים ביום", "dataRepoAutoPurgeRetentionIndexesDaily": "מספר תמונות נתונים ביום",
"fields": "מאפיין", "fields": "מאפיין",
"dynamicEmoji": "אייקון דינמי", "dynamicIcon": "אייקון דינמי",
"dynamicIconDateEmptyInfo": "נקה את התאריך, סמל לוח השנה יציג באופן דינמי את התאריך של היום",
"backlinkContainChildren": "האם קישורים חוזרים כוללים בלוקים משניים", "backlinkContainChildren": "האם קישורים חוזרים כוללים בלוקים משניים",
"backlinkContainChildrenTip": "לאחר ההפעלה, בלוקים משניים ייכללו בחישוב הקישורים החוזרים", "backlinkContainChildrenTip": "לאחר ההפעלה, בלוקים משניים ייכללו בחישוב הקישורים החוזרים",
"entryNum": "מספר ערכים", "entryNum": "מספר ערכים",
"workspaceData": "נתוני סביבת עבודה", "workspaceData": "נתוני סביבת עבודה",
"confirmRemoveRelationField": "האם אתה בטוח שברצונך למחוק את השדה המשויך ל-<b>${x}</b>?", "confirmRemoveRelationField": "האם אתה בטוח שברצונך למחוק את השדה <b>${x}</b>? לאחר מחיקת שדה זה, שדה הקשר הדו-כיווני <b>${z}</b> במסד הנתונים <b>${y}</b> יימחק גם הוא באופן סינכרוני.",
"removeButKeepRelationField": "מחק, אך שמור על שדה הקשר", "removeBothRelationField": "מחק את שני השדות",
"removeButKeepRelationField": "מחק רק שדה זה, שמור על שדה הקשר הדו-כיווני",
"exportPDFLowMemory": "אין מספיק זיכרון זמין במערכת כדי לייצא את ה-PDF הזה, נא לצמצם את התוכן או להגדיל את הזיכרון הזמין ולנסות שוב לייצא", "exportPDFLowMemory": "אין מספיק זיכרון זמין במערכת כדי לייצא את ה-PDF הזה, נא לצמצם את התוכן או להגדיל את הזיכרון הזמין ולנסות שוב לייצא",
"exportConf": "הגדרות ייצוא", "exportConf": "הגדרות ייצוא",
"exportConfTip": "פרטי חשבון, קוד אישור גישה, סנכרון, אסימון API ומפתח מאגר נתונים לא ייוצאו", "exportConfTip": "פרטי חשבון, קוד אישור גישה, סנכרון, אסימון API ומפתח מאגר נתונים לא ייוצאו",
@ -129,6 +131,7 @@
"updateLayout": "עדכן עימוד", "updateLayout": "עדכן עימוד",
"dndFolderTip": "שים לב כי ${x} ניחש את ה-hyperlink file:// ואינו מעתיק את הקובץ", "dndFolderTip": "שים לב כי ${x} ניחש את ה-hyperlink file:// ואינו מעתיק את הקובץ",
"removeCol": "האם אתה בטוח שברצונך למחוק את העמודה <b>${x}</b> במסד הנתונים?", "removeCol": "האם אתה בטוח שברצונך למחוק את העמודה <b>${x}</b> במסד הנתונים?",
"removeColConfirm": "⚠️ מחק עמודה",
"video": "וידאו", "video": "וידאו",
"audio": "אודיו", "audio": "אודיו",
"updateAll": "עדכן הכל", "updateAll": "עדכן הכל",
@ -337,6 +340,9 @@
"filterOperatorIsAfter": "היה אחרי", "filterOperatorIsAfter": "היה אחרי",
"filterOperatorIsOnOrBefore": "היה על או לפני", "filterOperatorIsOnOrBefore": "היה על או לפני",
"filterOperatorIsOnOrAfter": "היה על או אחרי", "filterOperatorIsOnOrAfter": "היה על או אחרי",
"filterQuantifierAny": "כל אחד",
"filterQuantifierAll": "הכל",
"filterQuantifierNone": "אין",
"asc": "עולה", "asc": "עולה",
"desc": "יורד", "desc": "יורד",
"hideCol": "החבא עמודה", "hideCol": "החבא עמודה",
@ -1118,7 +1124,7 @@
"fileTree3": "אין צורך באישור בעת מחיקת מסמכים", "fileTree3": "אין צורך באישור בעת מחיקת מסמכים",
"fileTree4": "אם לא הופק, תופיע תיבת אישור בכל פעם שמחקים מסמך", "fileTree4": "אם לא הופק, תופיע תיבת אישור בכל פעם שמחקים מסמך",
"fileTree5": "מיקום שמירת מסמך להפניה", "fileTree5": "מיקום שמירת מסמך להפניה",
"fileTree6": "בעת השימוש <code class='fn__code'>((</code>, מסלול השמירה של המסמך החדש (למשל, <code class='fn__code'>/folder1/{{now | date \"20060102150405\"}}</code>)", "fileTree6": "בעת השימוש <code class='fn__code'>((</code> או <code class='fn__code'>[[</code>, מסלול השמירה של המסמך החדש (למשל, <code class='fn__code'>/folder1/{{now | date \"20060102150405\"}}</code>)",
"fileTree7": "פתח בטאב הנוכחי", "fileTree7": "פתח בטאב הנוכחי",
"fileTree8": "טאב המסמך הנפתח החדש יחליף את הטאב הלא משתנה", "fileTree8": "טאב המסמך הנפתח החדש יחליף את הטאב הלא משתנה",
"fileTree9": "סגור את כל הטאבים בעת אתחול", "fileTree9": "סגור את כל הטאבים בעת אתחול",
@ -1630,7 +1636,7 @@
"242": "מעט מקום נותר [%s], נדרש לפחות [%s] כדי לבצע פעולה זו", "242": "מעט מקום נותר [%s], נדרש לפחות [%s] כדי לבצע פעולה זו",
"243": "רק רשום את %d התגים הראשונים (כולל תתי תגים), אם יש צורך להתאים, אנא שנה את [הגדרות - עץ המסמכים - מספר מקסימלי לרשימה]", "243": "רק רשום את %d התגים הראשונים (כולל תתי תגים), אם יש צורך להתאים, אנא שנה את [הגדרות - עץ המסמכים - מספר מקסימלי לרשימה]",
"244": "אינדוקס הנתונים לא הושלם לאחר השימוש האחרון. אנא הפעל את [עץ מסמכים - שכתוב אינדקס]. אנא צא מהתוכנית לחלוטין לפני כיבוי המחשב.", "244": "אינדוקס הנתונים לא הושלם לאחר השימוש האחרון. אנא הפעל את [עץ מסמכים - שכתוב אינדקס]. אנא צא מהתוכנית לחלוטין לפני כיבוי המחשב.",
"245": "אינדוקס הנתונים לא הושלם לאחר השימוש האחרון. אנא זכור לבצע [עץ המסמכים - שחזור אינדקס]. אנא השתמש [צא מהאפליקציה] בפאנל הטורי הימני כדי לצאת על פי סדר", "245": "אינדוקס הנתונים לא הושלם לאחר השימוש האחרון. אנא זכור לבצע [עץ המסמכים - שחזור אינדקס]. אנא השתמש [צא מהאפליקציה] בפאנל הטורי הימני כדי לצאת על פי סדר",
"246": "כותרת המסמך לא יכולה להכיל / והחלפה ב- _ ", "246": "כותרת המסמך לא יכולה להכיל / והחלפה ב- _ ",
"247": "הקובץ [%s] גדול יותר מהמגבלה המקסימלית [%s], והוזנח להעלות בענן", "247": "הקובץ [%s] גדול יותר מהמגבלה המקסימלית [%s], והוזנח להעלות בענן",
"248": "הכותרת היעד ממוקמת בבלוק המיכל ואינה יכולה לשמש כנקודת זרימה", "248": "הכותרת היעד ממוקמת בבלוק המיכל ואינה יכולה לשמש כנקודת זרימה",
@ -1656,6 +1662,7 @@
"268": "שים לב שהקובץ [%s] כבר חרג מ-[%d MB], דבר שעלול לגרום לירידה בביצועים", "268": "שים לב שהקובץ [%s] כבר חרג מ-[%d MB], דבר שעלול לגרום לירידה בביצועים",
"269": "הבלוק נוסף כבר למסד הנתונים [%s]", "269": "הבלוק נוסף כבר למסד הנתונים [%s]",
"270": "מתבצעת אופטימיזציה של אינדקס הנתונים, נא להמתין...", "270": "מתבצעת אופטימיזציה של אינדקס הנתונים, נא להמתין...",
"271": "אופטימיזציית אינדקס הנתונים הושלמה, שוחררו [%s] שטח דיסק" "271": "אופטימיזציית אינדקס הנתונים הושלמה, שוחררו [%s] שטח דיסק",
"272": "שדה ללא שם"
} }
} }

View file

@ -41,7 +41,7 @@
"reconnectPrompt": "Dopo aver cambiato applicazione, ci vorrà un po' di tempo per ripristinare il funzionamento del kernel SiYuan. Attendere qualche secondo o fare clic sul pulsante \"Riprova\"", "reconnectPrompt": "Dopo aver cambiato applicazione, ci vorrà un po' di tempo per ripristinare il funzionamento del kernel SiYuan. Attendere qualche secondo o fare clic sul pulsante \"Riprova\"",
"relativeFontSize": "rispetto alla dimensione del carattere dell'editor", "relativeFontSize": "rispetto alla dimensione del carattere dell'editor",
"localFileSystem": "File system locale", "localFileSystem": "File system locale",
"deviceNotSupport": "Il dispositivo corrente non è supportato", "mobileNotSupport": "La funzione non è attualmente supportata su dispositivi mobili (telefono o tablet)",
"second": "secondo", "second": "secondo",
"syncInterval": "intervallo di sincronizzazione", "syncInterval": "intervallo di sincronizzazione",
"syncIntervalTip": "Sincronizzazione automatica dei dati dopo che non ci sono più variazioni", "syncIntervalTip": "Sincronizzazione automatica dei dati dopo che non ci sono più variazioni",
@ -53,13 +53,15 @@
"dataRepoAutoPurgeIndexRetentionDays": "Giorni di conservazione degli snapshot dei dati", "dataRepoAutoPurgeIndexRetentionDays": "Giorni di conservazione degli snapshot dei dati",
"dataRepoAutoPurgeRetentionIndexesDaily": "Numero di snapshot dei dati al giorno", "dataRepoAutoPurgeRetentionIndexesDaily": "Numero di snapshot dei dati al giorno",
"fields": "Campi", "fields": "Campi",
"dynamicEmoji": "Emoji dinamica", "dynamicIcon": "Emoji dinamica",
"dynamicIconDateEmptyInfo": "Cancella la data, l'icona del calendario mostrerà dinamicamente la data odierna",
"backlinkContainChildren": "I backlink contengono blocchi figli", "backlinkContainChildren": "I backlink contengono blocchi figli",
"backlinkContainChildrenTip": "Dopo l'attivazione, i blocchi figli saranno inclusi nel calcolo dei backlink", "backlinkContainChildrenTip": "Dopo l'attivazione, i blocchi figli saranno inclusi nel calcolo dei backlink",
"entryNum": "Numero di voci", "entryNum": "Numero di voci",
"workspaceData": "Dati dello spazio di lavoro", "workspaceData": "Dati dello spazio di lavoro",
"confirmRemoveRelationField": "Sei sicuro di voler eliminare il campo associato a <b>${x}</b>?", "confirmRemoveRelationField": "Sei sicuro di voler eliminare il campo <b>${x}</b>? Dopo aver eliminato questo campo, il campo di relazione bidirezionale <b>${z}</b> nel database <b>${y}</b> verrà eliminato anche in modo sincrono.",
"removeButKeepRelationField": "Rimuovi, ma mantieni il campo correlato", "removeBothRelationField": "Rimuovi entrambi i campi",
"removeButKeepRelationField": "Rimuovi solo questo campo, mantieni il campo di relazione bidirezionale",
"exportPDFLowMemory": "Memoria disponibile insufficiente per esportare questo PDF, riduci il contenuto o aumenta la memoria disponibile e riprova a esportare", "exportPDFLowMemory": "Memoria disponibile insufficiente per esportare questo PDF, riduci il contenuto o aumenta la memoria disponibile e riprova a esportare",
"exportConf": "Impostazioni di esportazione", "exportConf": "Impostazioni di esportazione",
"exportConfTip": "Account, codici di accesso, sincronizzazione, token API e chiavi di data warehouse non verranno esportati", "exportConfTip": "Account, codici di accesso, sincronizzazione, token API e chiavi di data warehouse non verranno esportati",
@ -129,6 +131,7 @@
"updateLayout": "Aggiorna layout", "updateLayout": "Aggiorna layout",
"dndFolderTip": "Nota che ${x} inserisce solo il collegamento file:// e non copia il file", "dndFolderTip": "Nota che ${x} inserisce solo il collegamento file:// e non copia il file",
"removeCol": "Sei sicuro di voler eliminare la colonna <b>${x}</b> nel database?", "removeCol": "Sei sicuro di voler eliminare la colonna <b>${x}</b> nel database?",
"removeColConfirm": "⚠️ Elimina colonna",
"video": "Video", "video": "Video",
"audio": "Audio", "audio": "Audio",
"updateAll": "Aggiorna tutto", "updateAll": "Aggiorna tutto",
@ -337,6 +340,9 @@
"filterOperatorIsAfter": "È dopo", "filterOperatorIsAfter": "È dopo",
"filterOperatorIsOnOrBefore": "È il giorno o prima di", "filterOperatorIsOnOrBefore": "È il giorno o prima di",
"filterOperatorIsOnOrAfter": "È il giorno o dopo di", "filterOperatorIsOnOrAfter": "È il giorno o dopo di",
"filterQuantifierAny": "Qualsiasi",
"filterQuantifierAll": "Tutti",
"filterQuantifierNone": "Nessuno",
"asc": "Ascendente", "asc": "Ascendente",
"desc": "Discendente", "desc": "Discendente",
"hideCol": "Nascondi campo", "hideCol": "Nascondi campo",
@ -1118,7 +1124,7 @@
"fileTree3": "Nessuna conferma richiesta durante l'eliminazione dei documenti", "fileTree3": "Nessuna conferma richiesta durante l'eliminazione dei documenti",
"fileTree4": "Se non abilitato, ogni volta che elimini un documento verrà visualizzata una finestra di conferma", "fileTree4": "Se non abilitato, ogni volta che elimini un documento verrà visualizzata una finestra di conferma",
"fileTree5": "Percorso di salvataggio dei nuovi documenti creati con riferimento", "fileTree5": "Percorso di salvataggio dei nuovi documenti creati con riferimento",
"fileTree6": "Quando usi <code class='fn__code'>((</code>, il percorso di salvataggio del nuovo documento (ad esempio, <code class='fn__code'>/folder1/{{now | date \"20060102150405\"}}/</code>)", "fileTree6": "Quando usi <code class='fn__code'>((</code> o <code class='fn__code'>[[</code>, il percorso di salvataggio del nuovo documento (ad esempio, <code class='fn__code'>/folder1/{{now | date \"20060102150405\"}}/</code>)",
"fileTree7": "Apri nella scheda corrente", "fileTree7": "Apri nella scheda corrente",
"fileTree8": "La scheda del documento appena aperta sostituirà la scheda non modificata", "fileTree8": "La scheda del documento appena aperta sostituirà la scheda non modificata",
"fileTree9": "Chiudi tutte le schede all'avvio", "fileTree9": "Chiudi tutte le schede all'avvio",
@ -1656,6 +1662,7 @@
"268": "Attenzione: il file [%s] ha già superato [%d MB], il che potrebbe causare un calo delle prestazioni", "268": "Attenzione: il file [%s] ha già superato [%d MB], il che potrebbe causare un calo delle prestazioni",
"269": "Questo blocco è già stato aggiunto al database [%s]", "269": "Questo blocco è già stato aggiunto al database [%s]",
"270": "Ottimizzazione dell'indice dei dati in corso, attendere prego...", "270": "Ottimizzazione dell'indice dei dati in corso, attendere prego...",
"271": "Ottimizzazione dell'indice dei dati completata, liberati [%s] di spazio su disco" "271": "Ottimizzazione dell'indice dei dati completata, liberati [%s] di spazio su disco",
"272": "Campo senza nome"
} }
} }

View file

@ -41,7 +41,7 @@
"reconnectPrompt": "アプリを切り替えた後、思源カーネルの実行を再開するには少し時間がかかります。数秒待つか、「再試行」ボタンをクリックしてください", "reconnectPrompt": "アプリを切り替えた後、思源カーネルの実行を再開するには少し時間がかかります。数秒待つか、「再試行」ボタンをクリックしてください",
"relativeFontSize": "エディターのフォントサイズに対して", "relativeFontSize": "エディターのフォントサイズに対して",
"localFileSystem": "ローカルファイルシステム", "localFileSystem": "ローカルファイルシステム",
"deviceNotSupport": "現在のデバイスはサポートされていません", "mobileNotSupport": "モバイル端末(スマートフォンまたはタブレット)では現在この機能はサポートされていません",
"second": "秒", "second": "秒",
"syncInterval": "同期間隔", "syncInterval": "同期間隔",
"syncIntervalTip": "データが変動しなくなった後に自動的にデータを同期します", "syncIntervalTip": "データが変動しなくなった後に自動的にデータを同期します",
@ -53,13 +53,15 @@
"dataRepoAutoPurgeIndexRetentionDays": "データスナップショットの保持日数", "dataRepoAutoPurgeIndexRetentionDays": "データスナップショットの保持日数",
"dataRepoAutoPurgeRetentionIndexesDaily": "データスナップショットの毎日の保持数", "dataRepoAutoPurgeRetentionIndexesDaily": "データスナップショットの毎日の保持数",
"fields": "属性", "fields": "属性",
"dynamicEmoji": "動的アイコン", "dynamicIcon": "動的アイコン",
"dynamicIconDateEmptyInfo": "日付をクリアすると、カレンダーアイコンが当日の日付を動的に表示します",
"backlinkContainChildren": "バックリンクに子ブロックを含めるかどうか", "backlinkContainChildren": "バックリンクに子ブロックを含めるかどうか",
"backlinkContainChildrenTip": "有効にすると、子ブロックがバックリンク計算に含まれます", "backlinkContainChildrenTip": "有効にすると、子ブロックがバックリンク計算に含まれます",
"entryNum": "エントリ数", "entryNum": "エントリ数",
"workspaceData": "ワークスペースデータ", "workspaceData": "ワークスペースデータ",
"confirmRemoveRelationField": "<b>${x}</b> に関連するフィールドを同時に削除してもよろしいですか?", "confirmRemoveRelationField": "<b>${x}</b> フィールドを削除してもよろしいですか?このフィールドを削除すると、<b>${y}</b> データベースの双方向関連フィールド <b>${z}</b> も同時に削除されます。",
"removeButKeepRelationField": "削除して関連フィールドを保持", "removeBothRelationField": "両方のフィールドを削除",
"removeButKeepRelationField": "このフィールドのみ削除し、双方向関連フィールドを保持",
"exportPDFLowMemory": "システムの利用可能なメモリが不足しているため、この PDF をエクスポートできません。内容を減らすか、利用可能なメモリを増やしてから再試行してください", "exportPDFLowMemory": "システムの利用可能なメモリが不足しているため、この PDF をエクスポートできません。内容を減らすか、利用可能なメモリを増やしてから再試行してください",
"exportConf": "設定のエクスポート", "exportConf": "設定のエクスポート",
"exportConfTip": "アカウント、アクセスコード、同期、API トークン、データウェアハウスキーはエクスポートされません", "exportConfTip": "アカウント、アクセスコード、同期、API トークン、データウェアハウスキーはエクスポートされません",
@ -129,6 +131,7 @@
"updateLayout": "レイアウトを更新", "updateLayout": "レイアウトを更新",
"dndFolderTip": "${x} は file:// 形式のハイパーリンクを挿入するだけでファイルはコピーされないので注意してください", "dndFolderTip": "${x} は file:// 形式のハイパーリンクを挿入するだけでファイルはコピーされないので注意してください",
"removeCol": "データベースの <b>${x}</b> 列を削除してもよろしいですか?", "removeCol": "データベースの <b>${x}</b> 列を削除してもよろしいですか?",
"removeColConfirm": "⚠️ 列を削除",
"video": "ビデオ", "video": "ビデオ",
"audio": "音声", "audio": "音声",
"updateAll": "すべて更新", "updateAll": "すべて更新",
@ -337,6 +340,9 @@
"filterOperatorIsAfter": "より後", "filterOperatorIsAfter": "より後",
"filterOperatorIsOnOrBefore": "以前", "filterOperatorIsOnOrBefore": "以前",
"filterOperatorIsOnOrAfter": "以降", "filterOperatorIsOnOrAfter": "以降",
"filterQuantifierAny": "いずれか",
"filterQuantifierAll": "すべて",
"filterQuantifierNone": "なし",
"asc": "昇順", "asc": "昇順",
"desc": "降順", "desc": "降順",
"hideCol": "列を非表示", "hideCol": "列を非表示",
@ -1118,7 +1124,7 @@
"fileTree3": "ドキュメントを削除するときに確認しない", "fileTree3": "ドキュメントを削除するときに確認しない",
"fileTree4": "ドキュメントを削除するときに確認ボックスを表示しません", "fileTree4": "ドキュメントを削除するときに確認ボックスを表示しません",
"fileTree5": "参照の保存場所", "fileTree5": "参照の保存場所",
"fileTree6": "<code class='fn__code'>((</code> を使用した時の参照の保存パス (例: <code class='fn__code'>/folder1/{{now | date \"20060102150405\"}}/</code>)", "fileTree6": "<code class='fn__code'>((</code> または <code class='fn__code'>[[</code> を使用した時の参照の保存パス (例: <code class='fn__code'>/folder1/{{now | date \"20060102150405\"}}/</code>)",
"fileTree7": "現在のタブで開く", "fileTree7": "現在のタブで開く",
"fileTree8": "新しく開いたドキュメントのタブが未変更のタブを置き換えます", "fileTree8": "新しく開いたドキュメントのタブが未変更のタブを置き換えます",
"fileTree9": "起動時にすべてのタブを閉じる", "fileTree9": "起動時にすべてのタブを閉じる",
@ -1656,6 +1662,7 @@
"268": "ファイル [%s] はすでに [%d MB] を超えており、パフォーマンスが低下する可能性があります", "268": "ファイル [%s] はすでに [%d MB] を超えており、パフォーマンスが低下する可能性があります",
"269": "このブロックはすでにデータベース [%s] に追加されています", "269": "このブロックはすでにデータベース [%s] に追加されています",
"270": "データインデックスを最適化しています。しばらくお待ちください...", "270": "データインデックスを最適化しています。しばらくお待ちください...",
"271": "データインデックスの最適化が完了しました。合計 [%s] のディスク容量が解放されました" "271": "データインデックスの最適化が完了しました。合計 [%s] のディスク容量が解放されました",
"272": "未命名フィールド"
} }
} }

View file

@ -41,7 +41,7 @@
"reconnectPrompt": "Po przełączeniu aplikacji ponowne uruchomienie jądra SiYuan może zająć trochę czasu. Proszę poczekać kilka sekund lub kliknąć przycisk „Ponów próbę”", "reconnectPrompt": "Po przełączeniu aplikacji ponowne uruchomienie jądra SiYuan może zająć trochę czasu. Proszę poczekać kilka sekund lub kliknąć przycisk „Ponów próbę”",
"relativeFontSize": "względem rozmiaru czcionki edytora", "relativeFontSize": "względem rozmiaru czcionki edytora",
"localFileSystem": "Lokalny system plików", "localFileSystem": "Lokalny system plików",
"deviceNotSupport": "Bieżące urządzenie nie jest obsługiwane", "mobileNotSupport": "Funkcja nie jest obecnie obsługiwana na urządzeniach mobilnych (telefon lub tablet)",
"second": "sekunda", "second": "sekunda",
"syncInterval": "interwał synchronizacji", "syncInterval": "interwał synchronizacji",
"syncIntervalTip": "Automatyczna synchronizacja danych po zaprzestaniu zmian", "syncIntervalTip": "Automatyczna synchronizacja danych po zaprzestaniu zmian",
@ -53,13 +53,15 @@
"dataRepoAutoPurgeIndexRetentionDays": "Dni przechowywania migawek danych", "dataRepoAutoPurgeIndexRetentionDays": "Dni przechowywania migawek danych",
"dataRepoAutoPurgeRetentionIndexesDaily": "Liczba migawek danych dziennie", "dataRepoAutoPurgeRetentionIndexesDaily": "Liczba migawek danych dziennie",
"fields": "Atrybut", "fields": "Atrybut",
"dynamicEmoji": "Ikona dynamiczna", "dynamicIcon": "Ikona dynamiczna",
"dynamicIconDateEmptyInfo": "Wyczyść datę, ikona kalendarza będzie dynamicznie wyświetlać bieżącą datę",
"backlinkContainChildren": "Czy linki zwrotne zawierają bloki podrzędne", "backlinkContainChildren": "Czy linki zwrotne zawierają bloki podrzędne",
"backlinkContainChildrenTip": "Po włączeniu bloki podrzędne zostaną uwzględnione w obliczeniach linków zwrotnych", "backlinkContainChildrenTip": "Po włączeniu bloki podrzędne zostaną uwzględnione w obliczeniach linków zwrotnych",
"entryNum": "Количество записей", "entryNum": "Количество записей",
"workspaceData": "Dane przestrzeni roboczej", "workspaceData": "Dane przestrzeni roboczej",
"confirmRemoveRelationField": "Czy na pewno chcesz usunąć pole powiązane z <b>${x}</b>?", "confirmRemoveRelationField": "Czy na pewno chcesz usunąć pole <b>${x}</b>? Po usunięciu tego pola, dwukierunkowe pole relacji <b>${z}</b> w bazie danych <b>${y}</b> również zostanie usunięte synchronicznie.",
"removeButKeepRelationField": "Usuń, ale zachowaj powiązane pole", "removeBothRelationField": "Usuń oba pola",
"removeButKeepRelationField": "Usuń tylko to pole, zachowaj dwukierunkowe pole relacji",
"exportPDFLowMemory": "Za mało dostępnej pamięci, aby wyeksportować ten PDF, proszę zmniejszyć zawartość lub zwiększyć dostępną pamięć i spróbować ponownie", "exportPDFLowMemory": "Za mało dostępnej pamięci, aby wyeksportować ten PDF, proszę zmniejszyć zawartość lub zwiększyć dostępną pamięć i spróbować ponownie",
"exportConf": "Ustawienia eksportu", "exportConf": "Ustawienia eksportu",
"exportConfTip": "Konto, kod autoryzacji dostępu, synchronizacja, token API i klucz repozytorium danych nie będą eksportowane", "exportConfTip": "Konto, kod autoryzacji dostępu, synchronizacja, token API i klucz repozytorium danych nie będą eksportowane",
@ -129,6 +131,7 @@
"updateLayout": "Zaktualizuj układ", "updateLayout": "Zaktualizuj układ",
"dndFolderTip": "Proszę pamiętać, że ${x} tylko wstawia link file:// i nie kopiuje pliku", "dndFolderTip": "Proszę pamiętać, że ${x} tylko wstawia link file:// i nie kopiuje pliku",
"removeCol": "Czy na pewno chcesz usunąć <b>${x}</b> kolumnę w bazie danych?", "removeCol": "Czy na pewno chcesz usunąć <b>${x}</b> kolumnę w bazie danych?",
"removeColConfirm": "⚠️ Usuń kolumnę",
"video": "Wideo", "video": "Wideo",
"audio": "Audio", "audio": "Audio",
"updateAll": "Zaktualizuj wszystko", "updateAll": "Zaktualizuj wszystko",
@ -337,6 +340,9 @@
"filterOperatorIsAfter": "Jest po", "filterOperatorIsAfter": "Jest po",
"filterOperatorIsOnOrBefore": "Jest na lub przed", "filterOperatorIsOnOrBefore": "Jest na lub przed",
"filterOperatorIsOnOrAfter": "Jest na lub po", "filterOperatorIsOnOrAfter": "Jest na lub po",
"filterQuantifierAny": "Dowolny",
"filterQuantifierAll": "Wszystkie",
"filterQuantifierNone": "Brak",
"asc": "Rosnąco", "asc": "Rosnąco",
"desc": "Malejąco", "desc": "Malejąco",
"hideCol": "Ukryj kolumnę", "hideCol": "Ukryj kolumnę",
@ -1118,7 +1124,7 @@
"fileTree3": "Nie wymaga potwierdzenia przy usuwaniu dokumentów", "fileTree3": "Nie wymaga potwierdzenia przy usuwaniu dokumentów",
"fileTree4": "Jeśli nie jest włączone, okno potwierdzenia pojawi się za każdym razem, gdy usuniesz dokument", "fileTree4": "Jeśli nie jest włączone, okno potwierdzenia pojawi się za każdym razem, gdy usuniesz dokument",
"fileTree5": "Ref stworzone miejsce zapisu dokumentu", "fileTree5": "Ref stworzone miejsce zapisu dokumentu",
"fileTree6": "Kiedy używasz <code class='fn__code'>((</code>, ścieżka zapisu nowego dokumentu (na przykład <code class='fn__code'>/folder1/{{now | date \"20060102150405\"}}/</code>)", "fileTree6": "Kiedy używasz <code class='fn__code'>((</code> lub <code class='fn__code'>[[</code>, ścieżka zapisu nowego dokumentu (na przykład <code class='fn__code'>/folder1/{{now | date \"20060102150405\"}}/</code>)",
"fileTree7": "Otwórz w bieżącej zakładce", "fileTree7": "Otwórz w bieżącej zakładce",
"fileTree8": "Nowa otwarta zakładka dokumentu zastąpi niezmodyfikowaną zakładkę", "fileTree8": "Nowa otwarta zakładka dokumentu zastąpi niezmodyfikowaną zakładkę",
"fileTree9": "Zamknij wszystkie zakładki przy uruchamianiu", "fileTree9": "Zamknij wszystkie zakładki przy uruchamianiu",
@ -1656,6 +1662,7 @@
"268": "Uwaga: plik [%s] przekroczył już [%d MB], co może spowodować spadek wydajności", "268": "Uwaga: plik [%s] przekroczył już [%d MB], co może spowodować spadek wydajności",
"269": "Ten blok został już dodany do bazy danych [%s]", "269": "Ten blok został już dodany do bazy danych [%s]",
"270": "Optymalizacja indeksu danych, proszę czekać...", "270": "Optymalizacja indeksu danych, proszę czekać...",
"271": "Optymalizacja indeksu danych zakończona, zwolniono [%s] miejsca na dysku" "271": "Optymalizacja indeksu danych zakończona, zwolniono [%s] miejsca na dysku",
"272": "Nienazwane pole"
} }
} }

View file

@ -41,7 +41,7 @@
"reconnectPrompt": "Após alternar aplicativos, levará algum tempo para restaurar a operação do kernel SiYuan. Por favor, aguarde alguns segundos ou clique no botão \"Tentar novamente\"", "reconnectPrompt": "Após alternar aplicativos, levará algum tempo para restaurar a operação do kernel SiYuan. Por favor, aguarde alguns segundos ou clique no botão \"Tentar novamente\"",
"relativeFontSize": "relativo ao tamanho da fonte do editor", "relativeFontSize": "relativo ao tamanho da fonte do editor",
"localFileSystem": "Sistema de arquivos local", "localFileSystem": "Sistema de arquivos local",
"deviceNotSupport": "O dispositivo atual não é suportado", "mobileNotSupport": "O recurso não é suportado em dispositivos móveis (celular ou tablet) no momento,",
"second": "segundo", "second": "segundo",
"syncInterval": "intervalo de sincronização", "syncInterval": "intervalo de sincronização",
"syncIntervalTip": "Sincronizar dados automaticamente após parar de alterar", "syncIntervalTip": "Sincronizar dados automaticamente após parar de alterar",
@ -53,13 +53,15 @@
"dataRepoAutoPurgeIndexRetentionDays": "Dias de retenção de instantâneos de dados", "dataRepoAutoPurgeIndexRetentionDays": "Dias de retenção de instantâneos de dados",
"dataRepoAutoPurgeRetentionIndexesDaily": "Instantâneos de dados por dia", "dataRepoAutoPurgeRetentionIndexesDaily": "Instantâneos de dados por dia",
"fields": "Campos", "fields": "Campos",
"dynamicEmoji": "Ícone dinâmico", "dynamicIcon": "Ícone dinâmico",
"dynamicIconDateEmptyInfo": "Limpar a data, o ícone do calendário exibirá dinamicamente a data atual",
"backlinkContainChildren": "Os backlinks contêm blocos filhos", "backlinkContainChildren": "Os backlinks contêm blocos filhos",
"backlinkContainChildrenTip": "Quando ativado, os blocos filhos serão incluídos no cálculo do backlink", "backlinkContainChildrenTip": "Quando ativado, os blocos filhos serão incluídos no cálculo do backlink",
"entryNum": "Número de entradas", "entryNum": "Número de entradas",
"workspaceData": "Dados do espaço de trabalho", "workspaceData": "Dados do espaço de trabalho",
"confirmRemoveRelationField": "Tem certeza que deseja excluir o campo associado a <b>${x}</b>?", "confirmRemoveRelationField": "Tem certeza que deseja excluir o campo <b>${x}</b>? Após excluir este campo, o campo de relação bidirecional <b>${z}</b> no banco de dados <b>${y}</b> também será excluído de forma síncrona.",
"removeButKeepRelationField": "Remover, mas manter campo relacionado", "removeBothRelationField": "Remover ambos os campos",
"removeButKeepRelationField": "Remover apenas este campo, manter campo de relação bidirecional",
"exportPDFLowMemory": "Memória disponível insuficiente para exportar este PDF, reduza o conteúdo ou aumente a memória disponível e tente exportar novamente", "exportPDFLowMemory": "Memória disponível insuficiente para exportar este PDF, reduza o conteúdo ou aumente a memória disponível e tente exportar novamente",
"exportConf": "Configurações de exportação", "exportConf": "Configurações de exportação",
"exportConfTip": "Conta, código de autorização de acesso, sincronização, token de API e chave do repositório de dados não serão exportados", "exportConfTip": "Conta, código de autorização de acesso, sincronização, token de API e chave do repositório de dados não serão exportados",
@ -129,6 +131,7 @@
"updateLayout": "Atualizar layout", "updateLayout": "Atualizar layout",
"dndFolderTip": "Observe que ${x} apenas insere o hiperlink file:// e não copia o arquivo", "dndFolderTip": "Observe que ${x} apenas insere o hiperlink file:// e não copia o arquivo",
"removeCol": "Tem certeza que deseja excluir o campo <b>${x}</b> no banco de dados?", "removeCol": "Tem certeza que deseja excluir o campo <b>${x}</b> no banco de dados?",
"removeColConfirm": "⚠️ Excluir campo",
"video": "Vídeo", "video": "Vídeo",
"audio": "Áudio", "audio": "Áudio",
"updateAll": "Atualizar tudo", "updateAll": "Atualizar tudo",
@ -337,6 +340,9 @@
"filterOperatorIsAfter": "É depois de", "filterOperatorIsAfter": "É depois de",
"filterOperatorIsOnOrBefore": "É em ou antes de", "filterOperatorIsOnOrBefore": "É em ou antes de",
"filterOperatorIsOnOrAfter": "É em ou depois de", "filterOperatorIsOnOrAfter": "É em ou depois de",
"filterQuantifierAny": "Qualquer",
"filterQuantifierAll": "Todos",
"filterQuantifierNone": "Nenhum",
"asc": "Ascendente", "asc": "Ascendente",
"desc": "Descendente", "desc": "Descendente",
"hideCol": "Ocultar campo", "hideCol": "Ocultar campo",
@ -1118,7 +1124,7 @@
"fileTree3": "Nenhuma confirmação necessária ao excluir documentos", "fileTree3": "Nenhuma confirmação necessária ao excluir documentos",
"fileTree4": "Se não estiver ativado, uma caixa de confirmação aparecerá toda vez que você excluir um documento", "fileTree4": "Se não estiver ativado, uma caixa de confirmação aparecerá toda vez que você excluir um documento",
"fileTree5": "Local de salvamento do documento criado por Ref", "fileTree5": "Local de salvamento do documento criado por Ref",
"fileTree6": "Ao usar <code class='fn__code'>((</code>, o caminho de salvamento do novo documento (por exemplo, <code class='fn__code'>/folder1/{{now | date \"20060102150405\"}}/</code>)", "fileTree6": "Ao usar <code class='fn__code'>((</code> ou <code class='fn__code'>[[</code>, o caminho de salvamento do novo documento (por exemplo, <code class='fn__code'>/folder1/{{now | date \"20060102150405\"}}/</code>)",
"fileTree7": "Abrir na aba atual", "fileTree7": "Abrir na aba atual",
"fileTree8": "A nova aba de documento substituirá a aba não modificada", "fileTree8": "A nova aba de documento substituirá a aba não modificada",
"fileTree9": "Fechar todas as abas na inicialização", "fileTree9": "Fechar todas as abas na inicialização",
@ -1351,7 +1357,7 @@
"xy": "%d anos %s", "xy": "%d anos %s",
"max": "há muito tempo %s" "max": "há muito tempo %s"
}, },
"_taskAction": { "_taskAction": {
"task.repo.checkout": "Executar checkout do snapshot", "task.repo.checkout": "Executar checkout do snapshot",
"task.database.index.full": "Executar reconstrução do índice", "task.database.index.full": "Executar reconstrução do índice",
"task.database.index": "Executar índice do banco de dados", "task.database.index": "Executar índice do banco de dados",
@ -1656,6 +1662,7 @@
"268": "Atenção: o arquivo [%s] já excedeu [%d MB], o que pode causar queda de desempenho", "268": "Atenção: o arquivo [%s] já excedeu [%d MB], o que pode causar queda de desempenho",
"269": "Este bloco já foi adicionado ao banco de dados [%s]", "269": "Este bloco já foi adicionado ao banco de dados [%s]",
"270": "Otimizando o índice de dados, por favor aguarde...", "270": "Otimizando o índice de dados, por favor aguarde...",
"271": "Otimização do índice de dados concluída, [%s] de espaço liberado" "271": "Otimização do índice de dados concluída, [%s] de espaço liberado",
"272": "Campo sem nome"
} }
} }

View file

@ -41,7 +41,7 @@
"reconnectPrompt": "После переключения приложений потребуется некоторое время, чтобы восстановить работу ядра SiYuan. Пожалуйста, подождите несколько секунд или нажмите кнопку «Повторить»", "reconnectPrompt": "После переключения приложений потребуется некоторое время, чтобы восстановить работу ядра SiYuan. Пожалуйста, подождите несколько секунд или нажмите кнопку «Повторить»",
"relativeFontSize": "относительно размера шрифта редактора", "relativeFontSize": "относительно размера шрифта редактора",
"localFileSystem": "Локальная файловая система", "localFileSystem": "Локальная файловая система",
"deviceNotSupport": "Текущее устройство не поддерживается", "mobileNotSupport": "Мобильные устройства (телефон или планшет) в настоящее время не поддерживают эту функцию,",
"second": "секунда", "second": "секунда",
"syncInterval": "интервал синхронизации", "syncInterval": "интервал синхронизации",
"syncIntervalTip": "Автоматическая синхронизация данных после прекращения изменений", "syncIntervalTip": "Автоматическая синхронизация данных после прекращения изменений",
@ -53,13 +53,15 @@
"dataRepoAutoPurgeIndexRetentionDays": "Срок хранения снимков данных", "dataRepoAutoPurgeIndexRetentionDays": "Срок хранения снимков данных",
"dataRepoAutoPurgeRetentionIndexesDaily": "Количество снимков данных в день", "dataRepoAutoPurgeRetentionIndexesDaily": "Количество снимков данных в день",
"fields": "Атрибут", "fields": "Атрибут",
"dynamicEmoji": "Динамическая иконка", "dynamicIcon": "Динамическая иконка",
"dynamicIconDateEmptyInfo": "Очистить дату, иконка календаря будет динамически отображать текущую дату",
"backlinkContainChildren": "Включать ли дочерние блоки в обратные ссылки", "backlinkContainChildren": "Включать ли дочерние блоки в обратные ссылки",
"backlinkContainChildrenTip": "После включения дочерние блоки будут включены в расчет обратных ссылок", "backlinkContainChildrenTip": "После включения дочерние блоки будут включены в расчет обратных ссылок",
"entryNum": "Количество записей", "entryNum": "Количество записей",
"workspaceData": "Данные рабочей области", "workspaceData": "Данные рабочей области",
"confirmRemoveRelationField": "Вы уверены, что хотите удалить поле, связанное с <b>${x}</b>?", "confirmRemoveRelationField": "Вы уверены, что хотите удалить поле <b>${x}</b>? После удаления этого поля двунаправленное поле связи <b>${z}</b> в базе данных <b>${y}</b> также будет синхронно удалено.",
"removeButKeepRelationField": "Удалить, но сохранить связанное поле", "removeBothRelationField": "Удалить оба поля",
"removeButKeepRelationField": "Удалить только это поле, сохранить двунаправленное поле связи",
"exportPDFLowMemory": "Недостаточно доступной памяти для экспорта этого PDF, пожалуйста, уменьшите содержимое или увеличьте доступную память и повторите попытку экспорта", "exportPDFLowMemory": "Недостаточно доступной памяти для экспорта этого PDF, пожалуйста, уменьшите содержимое или увеличьте доступную память и повторите попытку экспорта",
"exportConf": "Экспорт настроек", "exportConf": "Экспорт настроек",
"exportConfTip": "Учетная запись, код авторизации доступа, синхронизация, API токен и ключ репозитория данных не будут экспортированы", "exportConfTip": "Учетная запись, код авторизации доступа, синхронизация, API токен и ключ репозитория данных не будут экспортированы",
@ -129,6 +131,7 @@
"updateLayout": "Обновить макет", "updateLayout": "Обновить макет",
"dndFolderTip": "Пожалуйста, обратите внимание, что ${x} только вставляет файл:// гиперссылку и не копирует файл", "dndFolderTip": "Пожалуйста, обратите внимание, что ${x} только вставляет файл:// гиперссылку и не копирует файл",
"removeCol": "Вы уверены, что хотите удалить колонку <b>${x}</b> в базе данных?", "removeCol": "Вы уверены, что хотите удалить колонку <b>${x}</b> в базе данных?",
"removeColConfirm": "⚠️ Удалить колонку",
"video": "Видео", "video": "Видео",
"audio": "Аудио", "audio": "Аудио",
"updateAll": "Обновить все", "updateAll": "Обновить все",
@ -337,6 +340,9 @@
"filterOperatorIsAfter": "Находится после", "filterOperatorIsAfter": "Находится после",
"filterOperatorIsOnOrBefore": "Находится на или до", "filterOperatorIsOnOrBefore": "Находится на или до",
"filterOperatorIsOnOrAfter": "Находится на или после", "filterOperatorIsOnOrAfter": "Находится на или после",
"filterQuantifierAny": "Любой",
"filterQuantifierAll": "Все",
"filterQuantifierNone": "Нет",
"asc": "По возрастанию", "asc": "По возрастанию",
"desc": "По убыванию", "desc": "По убыванию",
"hideCol": "Скрыть колонку", "hideCol": "Скрыть колонку",
@ -1118,7 +1124,7 @@
"fileTree3": "Подтверждение не требуется при удалении документов", "fileTree3": "Подтверждение не требуется при удалении документов",
"fileTree4": "Если не включено, будет появляться окно подтверждения каждый раз при удалении документа", "fileTree4": "Если не включено, будет появляться окно подтверждения каждый раз при удалении документа",
"fileTree5": "Сохранить местоположение созданного документа с ссылкой", "fileTree5": "Сохранить местоположение созданного документа с ссылкой",
"fileTree6": "При использовании <code class='fn__code'>((</code> путь для нового документа (например, <code class='fn__code'>/folder1/{{now | date \"20060102150405\"}}/</code>)", "fileTree6": "При использовании <code class='fn__code'>((</code> или <code class='fn__code'>[[</code> путь для нового документа (например, <code class='fn__code'>/folder1/{{now | date \"20060102150405\"}}/</code>)",
"fileTree7": "Открыть в текущей вкладке", "fileTree7": "Открыть в текущей вкладке",
"fileTree8": "Вкладка нового открытого документа заменит неизмененную вкладку", "fileTree8": "Вкладка нового открытого документа заменит неизмененную вкладку",
"fileTree9": "Закрыть все вкладки при запуске", "fileTree9": "Закрыть все вкладки при запуске",
@ -1656,6 +1662,7 @@
"268": "Обратите внимание, что файл [%s] уже превышает [%d МБ], это может привести к снижению производительности", "268": "Обратите внимание, что файл [%s] уже превышает [%d МБ], это может привести к снижению производительности",
"269": "Этот блок уже добавлен в базу данных [%s]", "269": "Этот блок уже добавлен в базу данных [%s]",
"270": "Оптимизация индекса данных, пожалуйста, подождите...", "270": "Оптимизация индекса данных, пожалуйста, подождите...",
"271": "Оптимизация индекса данных завершена, освобождено [%s] дискового пространства" "271": "Оптимизация индекса данных завершена, освобождено [%s] дискового пространства",
"272": "Неименованное поле"
} }
} }

View file

@ -22,8 +22,8 @@
"insertItemAfter": "在後方插入${x}條", "insertItemAfter": "在後方插入${x}條",
"allViews": "所有視圖", "allViews": "所有視圖",
"copyAVID": "複製資料庫 ID", "copyAVID": "複製資料庫 ID",
"hideEmptyFields": "隱藏空字段", "hideEmptyFields": "隱藏空欄位",
"displayEmptyFields": "顯示空字段", "displayEmptyFields": "顯示空欄位",
"cardAspectRatio": "預覽區寬高比", "cardAspectRatio": "預覽區寬高比",
"cardPreview1": "卡片預覽", "cardPreview1": "卡片預覽",
"contentImage": "內容圖片", "contentImage": "內容圖片",
@ -34,14 +34,14 @@
"fitImage": "自動調整圖片大小", "fitImage": "自動調整圖片大小",
"showIcon": "顯示圖標", "showIcon": "顯示圖標",
"showAllEntriesIcons": "顯示條目圖標", "showAllEntriesIcons": "顯示條目圖標",
"wrapAllFields": "字段自動換行", "wrapAllFields": "欄位自動換行",
"gallery": "卡片", "gallery": "卡片",
"newTag": "新建標籤", "newTag": "新建標籤",
"pleaseWait": "請稍等片刻...", "pleaseWait": "請稍等片刻...",
"reconnectPrompt": "切換應用後再次進入需要一些時間恢復思源內核運行,請稍等幾秒或者點擊“重試”按鈕", "reconnectPrompt": "切換應用後再次進入需要一些時間恢復思源內核運行,請稍等幾秒或者點擊“重試”按鈕",
"relativeFontSize": "相對於編輯器字號", "relativeFontSize": "相對於編輯器字號",
"localFileSystem": "本地檔案系統", "localFileSystem": "本地檔案系統",
"deviceNotSupport": "當前設備不支援", "mobileNotSupport": "行動裝置(手機或平板)目前不支援此功能,",
"second": "秒", "second": "秒",
"syncInterval": "同步間隔", "syncInterval": "同步間隔",
"syncIntervalTip": "數據不再變動後自動進行數據同步", "syncIntervalTip": "數據不再變動後自動進行數據同步",
@ -53,13 +53,15 @@
"dataRepoAutoPurgeIndexRetentionDays": "數據快照保留天數", "dataRepoAutoPurgeIndexRetentionDays": "數據快照保留天數",
"dataRepoAutoPurgeRetentionIndexesDaily": "數據快照每天保留個數", "dataRepoAutoPurgeRetentionIndexesDaily": "數據快照每天保留個數",
"fields": "欄位", "fields": "欄位",
"dynamicEmoji": "動態圖標", "dynamicIcon": "動態圖標",
"dynamicIconDateEmptyInfo": "清除日期,日曆圖示將動態顯示當天日期",
"backlinkContainChildren": "反向鏈接包含子塊", "backlinkContainChildren": "反向鏈接包含子塊",
"backlinkContainChildrenTip": "啟用後子塊將被納入到反向鏈接計算中", "backlinkContainChildrenTip": "啟用後子塊將被納入到反向鏈接計算中",
"entryNum": "條目數", "entryNum": "條目數",
"workspaceData": "工作空間數據", "workspaceData": "工作空間數據",
"confirmRemoveRelationField": "確定同時刪除關聯至 <b>${x}</b> 中的字段嗎?", "confirmRemoveRelationField": "確定要刪除 <b>${x}</b> 欄位嗎?刪除本欄位後,<b>${y}</b> 數據庫中的雙向關聯欄位 <b>${z}</b> 也會同步刪除。",
"removeButKeepRelationField": "刪除,但保留關聯字段", "removeBothRelationField": "同時刪除兩個欄位",
"removeButKeepRelationField": "僅刪除本欄位,保留雙向關聯欄位",
"exportPDFLowMemory": "系統可用記憶體不足,無法導出該 PDF請減少內容或者增加可用記憶體後再嘗試導出", "exportPDFLowMemory": "系統可用記憶體不足,無法導出該 PDF請減少內容或者增加可用記憶體後再嘗試導出",
"exportConf": "匯出設定", "exportConf": "匯出設定",
"exportConfTip": "帳號、存取授權碼、同步、API token 和資料倉儲金鑰不會被匯出", "exportConfTip": "帳號、存取授權碼、同步、API token 和資料倉儲金鑰不會被匯出",
@ -129,6 +131,7 @@
"updateLayout": "更新版面配置", "updateLayout": "更新版面配置",
"dndFolderTip": "請注意 ${x} 僅插入 file:// 超鏈接,不複製檔案", "dndFolderTip": "請注意 ${x} 僅插入 file:// 超鏈接,不複製檔案",
"removeCol": "確定刪除資料庫中的 <b>${x}</b> 欄位?", "removeCol": "確定刪除資料庫中的 <b>${x}</b> 欄位?",
"removeColConfirm": "⚠️ 刪除欄位",
"video": "影片", "video": "影片",
"audio": "音訊", "audio": "音訊",
"updateAll": "全部更新", "updateAll": "全部更新",
@ -337,6 +340,9 @@
"filterOperatorIsAfter": "晚於", "filterOperatorIsAfter": "晚於",
"filterOperatorIsOnOrBefore": "早於或等於", "filterOperatorIsOnOrBefore": "早於或等於",
"filterOperatorIsOnOrAfter": "晚於或等於", "filterOperatorIsOnOrAfter": "晚於或等於",
"filterQuantifierAny": "任一",
"filterQuantifierAll": "所有",
"filterQuantifierNone": "沒有",
"asc": "升序", "asc": "升序",
"desc": "降序", "desc": "降序",
"hideCol": "隱藏欄位", "hideCol": "隱藏欄位",
@ -1118,7 +1124,7 @@
"fileTree3": "刪除文檔時不需要確認", "fileTree3": "刪除文檔時不需要確認",
"fileTree4": "不啟用時每次刪除文檔都會彈出確認框", "fileTree4": "不啟用時每次刪除文檔都會彈出確認框",
"fileTree5": "塊引新建文檔存放位置", "fileTree5": "塊引新建文檔存放位置",
"fileTree6": "使用 <code class='fn__code'>((</code> 時新建文檔的存放路徑(例如 <code class='fn__code'>/folder1/{{now | date \"20060102150405\"}}/</code>", "fileTree6": "使用 <code class='fn__code'>((</code> 或 <code class='fn__code'>[[</code> 時新建文檔的存放路徑(例如 <code class='fn__code'>/folder1/{{now | date \"20060102150405\"}}/</code>",
"fileTree7": "在當前分頁中打開", "fileTree7": "在當前分頁中打開",
"fileTree8": "新打開的文檔分頁將會替換沒有修改過的分頁", "fileTree8": "新打開的文檔分頁將會替換沒有修改過的分頁",
"fileTree9": "啟動時關閉所有分頁", "fileTree9": "啟動時關閉所有分頁",
@ -1649,13 +1655,14 @@
"261": "今天", "261": "今天",
"262": "明天", "262": "明天",
"263": "未來 %d 天", "263": "未來 %d 天",
"264": "字段 [%s] 為空", "264": "欄位 [%s] 為空",
"265": "不在範圍內", "265": "不在範圍內",
"266": "Tesseract OCR 未安裝或未配置,請參考 用戶指南-資料文件 章節進行配置", "266": "Tesseract OCR 未安裝或未配置,請參考 用戶指南-資料文件 章節進行配置",
"267": "未命名資料庫", "267": "未命名資料庫",
"268": "請注意該檔案 [%s] 已經超過 [%d MB],可能會導致效能下降", "268": "請注意該檔案 [%s] 已經超過 [%d MB],可能會導致效能下降",
"269": "該塊已經添加到資料庫 [%s] 中", "269": "該塊已經添加到資料庫 [%s] 中",
"270": "正在優化資料索引,請稍等...", "270": "正在優化資料索引,請稍等...",
"271": "資料索引優化完畢,共釋放 [%s] 磁碟空間" "271": "資料索引優化完畢,共釋放 [%s] 磁碟空間",
"272": "未命名欄位"
} }
} }

View file

@ -41,7 +41,7 @@
"reconnectPrompt": "切换应用后再次进入需要一些时间恢复思源内核运行,请稍等几秒或者点击“重试”按钮", "reconnectPrompt": "切换应用后再次进入需要一些时间恢复思源内核运行,请稍等几秒或者点击“重试”按钮",
"relativeFontSize": "相对于编辑器字号", "relativeFontSize": "相对于编辑器字号",
"localFileSystem": "本地文件系统", "localFileSystem": "本地文件系统",
"deviceNotSupport": "当前设备不支持", "mobileNotSupport": "移动端(手机或平板)设备目前不支持该功能",
"second": "秒", "second": "秒",
"syncInterval": "同步间隔", "syncInterval": "同步间隔",
"syncIntervalTip": "数据不再变动后自动进行数据同步", "syncIntervalTip": "数据不再变动后自动进行数据同步",
@ -53,13 +53,15 @@
"dataRepoAutoPurgeIndexRetentionDays": "数据快照保留天数", "dataRepoAutoPurgeIndexRetentionDays": "数据快照保留天数",
"dataRepoAutoPurgeRetentionIndexesDaily": "数据快照每天保留个数", "dataRepoAutoPurgeRetentionIndexesDaily": "数据快照每天保留个数",
"fields": "字段", "fields": "字段",
"dynamicEmoji": "动态图标", "dynamicIcon": "动态图标",
"dynamicIconDateEmptyInfo": "清除日期,日历图标将动态显示当天日期",
"backlinkContainChildren": "反向链接包含子块", "backlinkContainChildren": "反向链接包含子块",
"backlinkContainChildrenTip": "启用后子块将被纳入到反向链接计算中", "backlinkContainChildrenTip": "启用后子块将被纳入到反向链接计算中",
"entryNum": "条目数", "entryNum": "条目数",
"workspaceData": "工作空间数据", "workspaceData": "工作空间数据",
"confirmRemoveRelationField": "确定同时删除关联至 <b>${x}</b> 中的字段吗?", "confirmRemoveRelationField": "确定要删除 <b>${x}</b> 字段吗?删除本字段后,<b>${y}</b> 数据库中的双向关联字段 <b>${z}</b> 也会同步删除。",
"removeButKeepRelationField": "删除,但保留关联字段", "removeBothRelationField": "同时删除两个字段",
"removeButKeepRelationField": "仅删除本字段,保留双向关联字段",
"exportPDFLowMemory": "系统可用内存不足,无法导出该 PDF请减少内容或者增加可用内存后再尝试导出", "exportPDFLowMemory": "系统可用内存不足,无法导出该 PDF请减少内容或者增加可用内存后再尝试导出",
"exportConf": "导出设置", "exportConf": "导出设置",
"exportConfTip": "账号、访问授权码、同步、API token 和数据仓库密钥不会被导出", "exportConfTip": "账号、访问授权码、同步、API token 和数据仓库密钥不会被导出",
@ -129,6 +131,7 @@
"updateLayout": "更新布局", "updateLayout": "更新布局",
"dndFolderTip": "请注意 ${x} 仅插入 file:// 超链接,不复制文件", "dndFolderTip": "请注意 ${x} 仅插入 file:// 超链接,不复制文件",
"removeCol": "确定删除数据库中的 <b>${x}</b> 字段?", "removeCol": "确定删除数据库中的 <b>${x}</b> 字段?",
"removeColConfirm": "⚠️ 删除字段",
"video": "视频", "video": "视频",
"audio": "音频", "audio": "音频",
"updateAll": "全部更新", "updateAll": "全部更新",
@ -337,6 +340,9 @@
"filterOperatorIsAfter": "晚于", "filterOperatorIsAfter": "晚于",
"filterOperatorIsOnOrBefore": "早于或等于", "filterOperatorIsOnOrBefore": "早于或等于",
"filterOperatorIsOnOrAfter": "晚于或等于", "filterOperatorIsOnOrAfter": "晚于或等于",
"filterQuantifierAny": "任一",
"filterQuantifierAll": "所有",
"filterQuantifierNone": "没有",
"asc": "升序", "asc": "升序",
"desc": "降序", "desc": "降序",
"hideCol": "隐藏字段", "hideCol": "隐藏字段",
@ -1118,7 +1124,7 @@
"fileTree3": "删除文档时不需要确认", "fileTree3": "删除文档时不需要确认",
"fileTree4": "不启用时每次删除文档都会弹出确认框", "fileTree4": "不启用时每次删除文档都会弹出确认框",
"fileTree5": "块引新建文档存放位置", "fileTree5": "块引新建文档存放位置",
"fileTree6": "使用 <code class='fn__code'>((</code> 时新建文档的存放路径(例如 <code class='fn__code'>/folder1/{{now | date \"20060102150405\"}}/</code>", "fileTree6": "使用 <code class='fn__code'>((</code> 或 <code class='fn__code'>[[</code> 时新建文档的存放路径(例如 <code class='fn__code'>/folder1/{{now | date \"20060102150405\"}}/</code>",
"fileTree7": "在当前页签中打开", "fileTree7": "在当前页签中打开",
"fileTree8": "新打开的文档页签将会替换没有修改过的页签", "fileTree8": "新打开的文档页签将会替换没有修改过的页签",
"fileTree9": "启动时关闭所有页签", "fileTree9": "启动时关闭所有页签",
@ -1656,6 +1662,7 @@
"268": "请注意该文件 [%s] 已经超过 [%d MB],可能会导致性能下降", "268": "请注意该文件 [%s] 已经超过 [%d MB],可能会导致性能下降",
"269": "该块已经添加到数据库 [%s] 中", "269": "该块已经添加到数据库 [%s] 中",
"270": "正在优化数据索引,请稍等...", "270": "正在优化数据索引,请稍等...",
"271": "数据索引优化完毕,共释放 [%s] 磁盘空间" "271": "数据索引优化完毕,共释放 [%s] 磁盘空间",
"272": "未命名字段"
} }
} }

View file

@ -9,7 +9,7 @@
<Identity Name="89C2A984.SiYuan" <Identity Name="89C2A984.SiYuan"
ProcessorArchitecture="x64" ProcessorArchitecture="x64"
Publisher="CN=087C656E-C1D9-42D8-8807-CED45A74FC0F" Publisher="CN=087C656E-C1D9-42D8-8807-CED45A74FC0F"
Version="3.3.0.0"/> Version="3.3.2.0"/>
<Properties> <Properties>
<DisplayName>SiYuan</DisplayName> <DisplayName>SiYuan</DisplayName>
<PublisherDisplayName>云南链滴科技有限公司</PublisherDisplayName> <PublisherDisplayName>云南链滴科技有限公司</PublisherDisplayName>

View file

@ -21,7 +21,7 @@ Below are the detailed changes in this version.
* [Database cells support vertical dragging to fill values](https://github.com/siyuan-note/siyuan/issues/12907) * [Database cells support vertical dragging to fill values](https://github.com/siyuan-note/siyuan/issues/12907)
* [Improve document tree movement and its animation](https://github.com/siyuan-note/siyuan/issues/12914) * [Improve document tree movement and its animation](https://github.com/siyuan-note/siyuan/issues/12914)
* [Improve S3/WebDAV data sync config](https://github.com/siyuan-note/siyuan/issues/12923) * [Improve S3/WebDAV data sync config](https://github.com/siyuan-note/siyuan/issues/12923)
* [The Publishing service no longer support export](https://github.com/siyuan-note/siyuan/issues/12928) * [The Publish service no longer support export](https://github.com/siyuan-note/siyuan/issues/12928)
* [Display document title in data history preview area](https://github.com/siyuan-note/siyuan/issues/12948) * [Display document title in data history preview area](https://github.com/siyuan-note/siyuan/issues/12948)
* [Improve parsing `<img>` when importing markdown](https://github.com/siyuan-note/siyuan/issues/12956) * [Improve parsing `<img>` when importing markdown](https://github.com/siyuan-note/siyuan/issues/12956)
* [Improve parsing of YAML Front Matter when importing Markdown](https://github.com/siyuan-note/siyuan/issues/12962) * [Improve parsing of YAML Front Matter when importing Markdown](https://github.com/siyuan-note/siyuan/issues/12962)

View file

@ -0,0 +1,49 @@
## Overview
This version improves some details.
## Changelogs
Below are the detailed changes in this version.
### Enhancement
* [Support reading file paths from the clipboard](https://github.com/siyuan-note/siyuan/issues/14269)
* [New template functions `ISOYear`, `ISOMonth` and `ISOWeekDate`](https://github.com/siyuan-note/siyuan/issues/15679)
* [The year is changed to ISOYear when the dynamic icon displays the week number](https://github.com/siyuan-note/siyuan/pull/15680)
* [Improve database template field grouping](https://github.com/siyuan-note/siyuan/issues/15687)
* [Support opening assets through other apps on HarmonyOS NEXT](https://github.com/siyuan-note/siyuan/issues/15691)
* [Add cookie-based auth in publish proxy](https://github.com/siyuan-note/siyuan/pull/15692)
* [Dynamic icon use current date as default](https://github.com/siyuan-note/siyuan/pull/15693)
* [Improve template syntax highlight](https://github.com/siyuan-note/siyuan/pull/15694)
* [Improve synchronization of database bound blocks when list blocks change](https://github.com/siyuan-note/siyuan/issues/15697)
* [Improve the display height of the Android keyboard toolbar](https://github.com/siyuan-note/siyuan/issues/15700)
* [The height of the dividing line adjusts with font size](https://github.com/siyuan-note/siyuan/pull/15701)
* [Improve document tree custom sorting stability when creating a notebook or doc](https://github.com/siyuan-note/siyuan/issues/15716)
* [Block ref search and global search results display reference counts](https://github.com/siyuan-note/siyuan/issues/15721)
* [Improve database rollup template rendering](https://github.com/siyuan-note/siyuan/issues/15722)
### Bugfix
* [Blockquote custom attributes are lost in some cases](https://github.com/siyuan-note/siyuan/issues/15601)
* [When "Default fill created time" is enabled for database date fields, the automatically filled time value is incorrect](https://github.com/siyuan-note/siyuan/issues/15684)
* [When searching for document tags, keyword highlighting will have extra pound signs](https://github.com/siyuan-note/siyuan/issues/15690)
* [Database rollup template calculations are incorrect](https://github.com/siyuan-note/siyuan/issues/15695)
* [The update time of the database checkbox field keeps changing](https://github.com/siyuan-note/siyuan/issues/15707)
* [Database relative date filtering is incorrect](https://github.com/siyuan-note/siyuan/issues/15710)
* [The folded state of the block under the folded heading is incorrect in some cases](https://github.com/siyuan-note/siyuan/issues/15717)
### Refactor
* [Upgrade to Electron v37.4.0](https://github.com/siyuan-note/siyuan/issues/15704)
### Development
* [Add plugin event bus `code-language-update` and `code-language-change`](https://github.com/siyuan-note/siyuan/pull/15610)
* [Add internal kernel API `/api/av/getAttributeViewBoundBlockIDs` and `getAttributeViewItemIDs`](https://github.com/siyuan-note/siyuan/issues/15708)
* [Improve the front-end compilation performance of the development environment](https://github.com/siyuan-note/siyuan/issues/15734)
## Download
* [B3log](https://b3log.org/siyuan/en/download.html)
* [GitHub](https://github.com/siyuan-note/siyuan/releases)

View file

@ -0,0 +1,49 @@
## 概述
該版本改進了一些細節。
## 變更記錄
以下是此版本中的詳細變更。
### 改進功能
* [支援從剪貼簿讀取檔案路徑](https://github.com/siyuan-note/siyuan/issues/14269)
* [新增範本函數 `ISOYear`、`ISOMonth` 和 `ISOWeekDate`](https://github.com/siyuan-note/siyuan/issues/15679)
* [動態圖示顯示週數時年份改為 ISOYear](https://github.com/siyuan-note/siyuan/pull/15680)
* [改進資料庫範本欄位分組](https://github.com/siyuan-note/siyuan/issues/15687)
* [支援在 HarmonyOS NEXT 上透過其他應用程式開啟資源檔案](https://github.com/siyuan-note/siyuan/issues/15691)
* [發布代理商中增加基於 Cookie 的認證](https://github.com/siyuan-note/siyuan/pull/15692)
* [動態圖示預設使用目前日期](https://github.com/siyuan-note/siyuan/pull/15693)
* [改進模板語法高亮](https://github.com/siyuan-note/siyuan/pull/15694)
* [改進清單區塊變更時資料庫綁定區塊的同步](https://github.com/siyuan-note/siyuan/issues/15697)
* [改進 Android 鍵盤工具列的顯示高度](https://github.com/siyuan-note/siyuan/issues/15700)
* [分割線高度隨字體大小調整](https://github.com/siyuan-note/siyuan/pull/15701)
* [改進新筆記本或文件時文件樹自訂排序的穩定性](https://github.com/siyuan-note/siyuan/issues/15716)
* [區塊引用搜尋和全域搜尋結果顯示引用計數](https://github.com/siyuan-note/siyuan/issues/15721)
* [改進資料庫匯總範本渲染](https://github.com/siyuan-note/siyuan/issues/15722)
### 修復缺陷
* [某些情況下引用區塊自訂屬性遺失](https://github.com/siyuan-note/siyuan/issues/15601)
* [資料庫日期欄位啟用「預設填滿建立時間」時自動填入的時間值不正確](https://github.com/siyuan-note/siyuan/issues/15684)
* [搜尋文件標籤時,關鍵字高亮會多出井號](https://github.com/siyuan-note/siyuan/issues/15690)
* [資料庫總表範本計算不正確](https://github.com/siyuan-note/siyuan/issues/15695)
* [資料庫複選框欄位的更新時間不斷變化](https://github.com/siyuan-note/siyuan/issues/15707)
* [資料庫相對日期篩選不正確](https://github.com/siyuan-note/siyuan/issues/15710)
* [折疊標題下塊的折疊狀態在某些情況下不正確](https://github.com/siyuan-note/siyuan/issues/15717)
### 開發重構
* [升級至 Electron v37.4.0](https://github.com/siyuan-note/siyuan/issues/15704)
### 開發者
* [新增外掛事件匯流排 `code-language-update` 和 `code-language-change`](https://github.com/siyuan-note/siyuan/pull/15610)
* [新增核心介面 `/api/av/getAttributeViewBoundBlockIDs` 和 `getAttributeViewItemIDs`](https://github.com/siyuan-note/siyuan/issues/15708)
* [提升開發環境前端編譯效能](https://github.com/siyuan-note/siyuan/issues/15734)
## 下載
* [B3log](https://b3log.org/siyuan/download.html)
* [GitHub](https://github.com/siyuan-note/siyuan/releases)

View file

@ -0,0 +1,49 @@
## 概述
该版本改进了一些细节。
## 变更记录
以下是此版本中的详细变更。
### 改进功能
* [支持从剪贴板读取文件路径](https://github.com/siyuan-note/siyuan/issues/14269)
* [新增模板函数 `ISOYear`、`ISOMonth` 和 `ISOWeekDate`](https://github.com/siyuan-note/siyuan/issues/15679)
* [动态图标显示周数时年份改为 ISOYear](https://github.com/siyuan-note/siyuan/pull/15680)
* [改进数据库模板字段分组](https://github.com/siyuan-note/siyuan/issues/15687)
* [支持在 HarmonyOS NEXT 上通过其他应用打开资源文件](https://github.com/siyuan-note/siyuan/issues/15691)
* [发布代理中增加基于 Cookie 的认证](https://github.com/siyuan-note/siyuan/pull/15692)
* [动态图标默认使用当前日期](https://github.com/siyuan-note/siyuan/pull/15693)
* [改进模板语法高亮](https://github.com/siyuan-note/siyuan/pull/15694)
* [改进列表块变动时数据库绑定块的同步](https://github.com/siyuan-note/siyuan/issues/15697)
* [改进 Android 键盘工具栏的显示高度](https://github.com/siyuan-note/siyuan/issues/15700)
* [分割线高度随字体大小调整](https://github.com/siyuan-note/siyuan/pull/15701)
* [改进新建笔记本或文档时文档树自定义排序的稳定性](https://github.com/siyuan-note/siyuan/issues/15716)
* [块引用搜索和全局搜索结果显示引用计数](https://github.com/siyuan-note/siyuan/issues/15721)
* [改进数据库汇总模板渲染](https://github.com/siyuan-note/siyuan/issues/15722)
### 修复缺陷
* [某些情况下引用块自定义属性丢失](https://github.com/siyuan-note/siyuan/issues/15601)
* [数据库日期字段启用“默认填充创建时间”时自动填充的时间值不正确](https://github.com/siyuan-note/siyuan/issues/15684)
* [搜索文档标签时,关键字高亮会多出井号](https://github.com/siyuan-note/siyuan/issues/15690)
* [数据库汇总模板计算不正确](https://github.com/siyuan-note/siyuan/issues/15695)
* [数据库复选框字段的更新时间不断变化](https://github.com/siyuan-note/siyuan/issues/15707)
* [数据库相对日期筛选不正确](https://github.com/siyuan-note/siyuan/issues/15710)
* [折叠标题下块的折叠状态在某些情况下不正确](https://github.com/siyuan-note/siyuan/issues/15717)
### 开发重构
* [升级至 Electron v37.4.0](https://github.com/siyuan-note/siyuan/issues/15704)
### 开发者
* [新增插件事件总线 `code-language-update` 和 `code-language-change`](https://github.com/siyuan-note/siyuan/pull/15610)
* [新增内核接口 `/api/av/getAttributeViewBoundBlockIDs` 和 `getAttributeViewItemIDs`](https://github.com/siyuan-note/siyuan/issues/15708)
* [提升开发环境前端编译性能](https://github.com/siyuan-note/siyuan/issues/15734)
## 下载
* [B3log](https://b3log.org/siyuan/download.html)
* [GitHub](https://github.com/siyuan-note/siyuan/releases)

View file

@ -0,0 +1,48 @@
## Overview
This version improves some details.
## Changelogs
Below are the detailed changes in this version.
### Enhancement
* [Copy/Cut folded heading changed to copy/cut `Headings and Bottom Blocks` and support multiple headings copy/cut](https://github.com/siyuan-note/siyuan/issues/8019)
* [Improve database field editing menu](https://github.com/siyuan-note/siyuan/issues/15185)
* [Database rollup field filtering rules support "Any", "All", and "None"](https://github.com/siyuan-note/siyuan/issues/15609)
* [Improve flashcards](https://github.com/siyuan-note/siyuan/issues/15699)
* [If the new data created in the database is in a collapsed group, the edit box will not pop up](https://github.com/siyuan-note/siyuan/issues/15728)
* [Select Copy in the code block to copy only the plain text](https://github.com/siyuan-note/siyuan/issues/15733)
* [Use the default sorting when the search content in the code block language prompt is empty](https://github.com/siyuan-note/siyuan/issues/15737)
* [Improve database rollup field filtering](https://github.com/siyuan-note/siyuan/issues/15740)
* [Improve database date field filtering](https://github.com/siyuan-note/siyuan/issues/15744)
* [Disable editing when adding options to the database](https://github.com/siyuan-note/siyuan/issues/15751)
* [After dragging database entries across groups, groups in other views need to be updated](https://github.com/siyuan-note/siyuan/issues/15755)
* [Browser clipping extension supports clipping page to the database](https://github.com/siyuan-note/siyuan/issues/15758)
* [Hide the bottom gesture navigation bar on Android](https://github.com/siyuan-note/siyuan/issues/15763)
* [Improve database group view performance](https://github.com/siyuan-note/siyuan/issues/15764)
* [Dragging multiple files into the editor will cause them to be opened by the default program](https://github.com/siyuan-note/siyuan/pull/15773)
* [Improve HTML table clipping](https://github.com/siyuan-note/siyuan/issues/15781)
* [Automatically create a new document when clicking on a notebook without documents](https://github.com/siyuan-note/siyuan/issues/15782)
* [Add field `disabledInPublish` to the code snippet to indicate whether it is disabled in the publish service](https://github.com/siyuan-note/siyuan/issues/15806)
### Bugfix
* [PDF files with too long file names cannot generate annotated images](https://github.com/siyuan-note/siyuan/issues/15739)
* [The video block network address is incorrect](https://github.com/siyuan-note/siyuan/issues/15741)
* [The database date field cannot paste the time of 0 o'clock](https://github.com/siyuan-note/siyuan/issues/15742)
* [Read-only mode cannot be set in preview mode](https://github.com/siyuan-note/siyuan/issues/15756)
* [Exception when inserting batch files into the editor](https://github.com/siyuan-note/siyuan/issues/15768)
* [When using certain input methods, punctuation characters are inserted twice after pasting a link at the end of a block](https://github.com/siyuan-note/siyuan/issues/15801)
### Development
* [Add field `disabledInPublish` to the marketplace plugin package metadata to indicate whether it is disabled in the publish service](https://github.com/siyuan-note/siyuan/issues/11730)
* [Add plugin function `expandDocTree`](https://github.com/siyuan-note/siyuan/issues/15639)
* [Improve kernel API `appendBlock`, `insertBlock` and `prependBlock`](https://github.com/siyuan-note/siyuan/issues/15798)
## Download
* [B3log](https://b3log.org/siyuan/en/download.html)
* [GitHub](https://github.com/siyuan-note/siyuan/releases)

View file

@ -0,0 +1,48 @@
## 概述
該版本改進了一些細節。
## 變更記錄
以下是此版本中的詳細變更。
### 改進功能
* [折疊標題的複製/剪切改為複製/剪切 `標題及其下方塊`,並支援多標題複製/剪切](https://github.com/siyuan-note/siyuan/issues/8019)
* [改進資料庫欄位編輯選單](https://github.com/siyuan-note/siyuan/issues/15185)
* [資料庫匯總欄位篩選規則支援「任一」、「所有」和「沒有」](https://github.com/siyuan-note/siyuan/issues/15609)
* [改良閃卡](https://github.com/siyuan-note/siyuan/issues/15699)
* [資料庫中新建資料如果在折疊分組內,不再彈出編輯框](https://github.com/siyuan-note/siyuan/issues/15728)
* [程式碼區塊選擇複製時僅複製純文字](https://github.com/siyuan-note/siyuan/issues/15733)
* [程式碼區塊語言提示搜尋內容為空時使用預設排序](https://github.com/siyuan-note/siyuan/issues/15737)
* [改進資料庫匯總欄位篩選](https://github.com/siyuan-note/siyuan/issues/15740)
* [改進資料庫日期欄位篩選](https://github.com/siyuan-note/siyuan/issues/15744)
* [資料庫新增選項時禁止編輯](https://github.com/siyuan-note/siyuan/issues/15751)
* [資料庫條目跨分組拖曳後,同步更新其他檢視中的分組](https://github.com/siyuan-note/siyuan/issues/15755)
* [瀏覽器剪藏擴充功能支援剪藏頁面到資料庫](https://github.com/siyuan-note/siyuan/issues/15758)
* [Android 隱藏底部手勢導覽列](https://github.com/siyuan-note/siyuan/issues/15763)
* [提升資料庫分組檢視效能](https://github.com/siyuan-note/siyuan/issues/15764)
* [拖入多個檔案到編輯器不再被預設程式開啟](https://github.com/siyuan-note/siyuan/pull/15773)
* [改進 HTML 表格剪藏](https://github.com/siyuan-note/siyuan/issues/15781)
* [點選無文件的筆記本時自動新建文件](https://github.com/siyuan-note/siyuan/issues/15782)
* [程式碼片段新增欄位 `disabledInPublish`,用於識別發佈服務中是否已停用](https://github.com/siyuan-note/siyuan/issues/15806)
### 修復缺陷
* [PDF 檔名過長無法產生標註圖片](https://github.com/siyuan-note/siyuan/issues/15739)
* [影片區塊網路網址不正確](https://github.com/siyuan-note/siyuan/issues/15741)
* [資料庫日期欄位無法貼上 0 點時間](https://github.com/siyuan-note/siyuan/issues/15742)
* [預覽模式下無法設定唯讀模式](https://github.com/siyuan-note/siyuan/issues/15756)
* [批次插入檔案到編輯器時異常](https://github.com/siyuan-note/siyuan/issues/15768)
* [部分輸入法在區塊末尾貼上連結後標點符號重複插入](https://github.com/siyuan-note/siyuan/issues/15801)
### 開發者
* [集市插件包元資料新增欄位 `disabledInPublish`,用於識別發布服務中是否已停用](https://github.com/siyuan-note/siyuan/issues/11730)
* [新增外掛程式 `expandDocTree`](https://github.com/siyuan-note/siyuan/issues/15639)
* [改進內核 API `appendBlock`、`insertBlock` 和 `prependBlock`](https://github.com/siyuan-note/siyuan/issues/15798)
## 下載
* [B3log](https://b3log.org/siyuan/download.html)
* [GitHub](https://github.com/siyuan-note/siyuan/releases)

View file

@ -0,0 +1,48 @@
## 概述
该版本改进了一些细节。
## 变更记录
以下是此版本中的详细变更。
### 改进功能
* [折叠标题的复制/剪切改为复制/剪切 `标题及其下方块`,并支持多标题复制/剪切](https://github.com/siyuan-note/siyuan/issues/8019)
* [改进数据库字段编辑菜单](https://github.com/siyuan-note/siyuan/issues/15185)
* [数据库汇总字段筛选规则支持“任一”、“所有”和“没有”](https://github.com/siyuan-note/siyuan/issues/15609)
* [改进闪卡](https://github.com/siyuan-note/siyuan/issues/15699)
* [数据库中新建数据如果在折叠分组内,不再弹出编辑框](https://github.com/siyuan-note/siyuan/issues/15728)
* [代码块选择复制时仅复制纯文本](https://github.com/siyuan-note/siyuan/issues/15733)
* [代码块语言提示搜索内容为空时使用默认排序](https://github.com/siyuan-note/siyuan/issues/15737)
* [改进数据库汇总字段筛选](https://github.com/siyuan-note/siyuan/issues/15740)
* [改进数据库日期字段筛选](https://github.com/siyuan-note/siyuan/issues/15744)
* [数据库添加选项时禁止编辑](https://github.com/siyuan-note/siyuan/issues/15751)
* [数据库条目跨分组拖动后,同步更新其他视图中的分组](https://github.com/siyuan-note/siyuan/issues/15755)
* [浏览器剪藏扩展支持剪藏页面到数据库](https://github.com/siyuan-note/siyuan/issues/15758)
* [Android 隐藏底部手势导航栏](https://github.com/siyuan-note/siyuan/issues/15763)
* [提升数据库分组视图性能](https://github.com/siyuan-note/siyuan/issues/15764)
* [拖入多个文件到编辑器不再被默认程序打开](https://github.com/siyuan-note/siyuan/pull/15773)
* [改进 HTML 表格剪藏](https://github.com/siyuan-note/siyuan/issues/15781)
* [点击无文档的笔记本时自动新建文档](https://github.com/siyuan-note/siyuan/issues/15782)
* [代码片段新增字段 `disabledInPublish`,用于标识发布服务中是否禁用](https://github.com/siyuan-note/siyuan/issues/15806)
### 修复缺陷
* [PDF 文件名过长无法生成标注图片](https://github.com/siyuan-note/siyuan/issues/15739)
* [视频块网络地址不正确](https://github.com/siyuan-note/siyuan/issues/15741)
* [数据库日期字段无法粘贴 0 点时间](https://github.com/siyuan-note/siyuan/issues/15742)
* [预览模式下无法设置只读模式](https://github.com/siyuan-note/siyuan/issues/15756)
* [批量插入文件到编辑器时异常](https://github.com/siyuan-note/siyuan/issues/15768)
* [部分输入法在块末尾粘贴链接后标点符号重复插入](https://github.com/siyuan-note/siyuan/issues/15801)
### 开发者
* [集市插件包元数据新增字段 `disabledInPublish`,用于标识发布服务中是否禁用](https://github.com/siyuan-note/siyuan/issues/11730)
* [新增插件函数 `expandDocTree`](https://github.com/siyuan-note/siyuan/issues/15639)
* [改进内核 API `appendBlock`、`insertBlock` 和 `prependBlock`](https://github.com/siyuan-note/siyuan/issues/15798)
## 下载
* [B3log](https://b3log.org/siyuan/download.html)
* [GitHub](https://github.com/siyuan-note/siyuan/releases)

View file

@ -3820,7 +3820,7 @@
"Children": [ "Children": [
{ {
"Type": "NodeText", "Type": "NodeText",
"Data": "In the code block, only select the content of the code block" "Data": "Double press to select all loaded content blocks in the document; in the code block, only select the content of the code block"
} }
] ]
} }

View file

@ -102,7 +102,7 @@
}, },
{ {
"Type": "NodeText", "Type": "NodeText",
"Data": " to enter the publishing service settings panel." "Data": " to enter the publish service settings panel."
} }
] ]
} }
@ -252,7 +252,7 @@
"Children": [ "Children": [
{ {
"Type": "NodeText", "Type": "NodeText",
"Data": "If access control is required for the publishing service:" "Data": "If access control is required for the publish service:"
} }
] ]
}, },
@ -333,7 +333,7 @@
"Children": [ "Children": [
{ {
"Type": "NodeText", "Type": "NodeText",
"Data": "When enabled, the publishing service will use the " "Data": "When enabled, the publish service will use the "
}, },
{ {
"Type": "NodeTextMark", "Type": "NodeTextMark",
@ -482,7 +482,7 @@
"Children": [ "Children": [
{ {
"Type": "NodeText", "Type": "NodeText",
"Data": "After enabling the publishing service, visitors can browse the content of the entire workspace." "Data": "After enabling the publish service, visitors can browse the content of the entire workspace."
} }
] ]
} }

View file

@ -5,7 +5,8 @@
"Properties": { "Properties": {
"id": "20230805232134-3d6mx2k", "id": "20230805232134-3d6mx2k",
"title": "Search asset content", "title": "Search asset content",
"updated": "20231026085302" "type": "doc",
"updated": "20250903163017"
}, },
"Children": [ "Children": [
{ {
@ -46,7 +47,7 @@
"ListData": {}, "ListData": {},
"Properties": { "Properties": {
"id": "20230818102341-ny18orr", "id": "20230818102341-ny18orr",
"updated": "20230818102341" "updated": "20250903163017"
}, },
"Children": [ "Children": [
{ {
@ -58,7 +59,7 @@
}, },
"Properties": { "Properties": {
"id": "20230818102341-eg8labw", "id": "20230818102341-eg8labw",
"updated": "20230818102341" "updated": "20250903163017"
}, },
"Children": [ "Children": [
{ {
@ -66,12 +67,318 @@
"Type": "NodeParagraph", "Type": "NodeParagraph",
"Properties": { "Properties": {
"id": "20230818102341-izc16tp", "id": "20230818102341-izc16tp",
"updated": "20230818102426" "updated": "20250903163017"
}, },
"Children": [ "Children": [
{ {
"Type": "NodeText", "Type": "NodeText",
"Data": "Text files (.txt, .md, .json, .log, .sql, .html, .xml, .java, .h, .c, .cpp, .go, .rs, .swift, .kt, . py, .php, .js, .css, .ts, .sh, .bat, .cmd, .ini, .yaml, .rst, .adoc, .textile, .opml, .org, .wiki)" "Data": "Text files ("
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".txt"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".md"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".markdown"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".json"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".log"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".sql"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".html"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".xml"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".java"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".h"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".c"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".cpp"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".go"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".rs"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".swift"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".kt"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".py"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".php"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".js"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".css"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".ts"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".sh"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".bat"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".cmd"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".ini"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".yaml"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".rst"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".adoc"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".textile"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".opml"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".org"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".wiki"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".epub"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".cs"
},
{
"Type": "NodeText",
"Data": ")"
} }
] ]
} }
@ -85,7 +392,8 @@
"Marker": "Kg==" "Marker": "Kg=="
}, },
"Properties": { "Properties": {
"id": "20230818102427-os9c4nm" "id": "20230818102427-os9c4nm",
"updated": "20250903162955"
}, },
"Children": [ "Children": [
{ {
@ -93,12 +401,21 @@
"Type": "NodeParagraph", "Type": "NodeParagraph",
"Properties": { "Properties": {
"id": "20230818102427-dyojs23", "id": "20230818102427-dyojs23",
"updated": "20230818102429" "updated": "20250903162955"
}, },
"Children": [ "Children": [
{ {
"Type": "NodeText", "Type": "NodeText",
"Data": ".docx" "Data": ""
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".docx"
},
{
"Type": "NodeText",
"Data": ""
} }
] ]
} }
@ -112,7 +429,8 @@
"Marker": "Kg==" "Marker": "Kg=="
}, },
"Properties": { "Properties": {
"id": "20230818102430-sw9p4uf" "id": "20230818102430-sw9p4uf",
"updated": "20250903162956"
}, },
"Children": [ "Children": [
{ {
@ -120,12 +438,21 @@
"Type": "NodeParagraph", "Type": "NodeParagraph",
"Properties": { "Properties": {
"id": "20230818102430-boci4wf", "id": "20230818102430-boci4wf",
"updated": "20230818102431" "updated": "20250903162956"
}, },
"Children": [ "Children": [
{ {
"Type": "NodeText", "Type": "NodeText",
"Data": ".pptx" "Data": ""
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".pptx"
},
{
"Type": "NodeText",
"Data": ""
} }
] ]
} }
@ -139,7 +466,8 @@
"Marker": "Kg==" "Marker": "Kg=="
}, },
"Properties": { "Properties": {
"id": "20230818102432-6uclx4n" "id": "20230818102432-6uclx4n",
"updated": "20250903162957"
}, },
"Children": [ "Children": [
{ {
@ -147,12 +475,21 @@
"Type": "NodeParagraph", "Type": "NodeParagraph",
"Properties": { "Properties": {
"id": "20230818102432-3n95b7k", "id": "20230818102432-3n95b7k",
"updated": "20230818102433" "updated": "20250903162957"
}, },
"Children": [ "Children": [
{ {
"Type": "NodeText", "Type": "NodeText",
"Data": ".xlsx" "Data": ""
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".xlsx"
},
{
"Type": "NodeText",
"Data": ""
} }
] ]
} }
@ -166,19 +503,30 @@
"Marker": "Kg==" "Marker": "Kg=="
}, },
"Properties": { "Properties": {
"id": "20230818102434-9xgwy7r" "id": "20230818102434-9xgwy7r",
"updated": "20250903162959"
}, },
"Children": [ "Children": [
{ {
"ID": "20230818102434-1efdkw9", "ID": "20230818102434-1efdkw9",
"Type": "NodeParagraph", "Type": "NodeParagraph",
"Properties": { "Properties": {
"id": "20230818102434-1efdkw9" "id": "20230818102434-1efdkw9",
"updated": "20250903162959"
}, },
"Children": [ "Children": [
{ {
"Type": "NodeText", "Type": "NodeText",
"Data": ".pdf" "Data": ""
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".pdf"
},
{
"Type": "NodeText",
"Data": ""
} }
] ]
} }

View file

@ -3818,7 +3818,7 @@
"Children": [ "Children": [
{ {
"Type": "NodeText", "Type": "NodeText",
"Data": "代码块中使用时仅选中代码块中的内容" "Data": "连续按下两次以选中文档中所有已加载的内容块;代码块中使用时仅选中代码块中的内容"
} }
] ]
} }

View file

@ -5,7 +5,8 @@
"Properties": { "Properties": {
"id": "20230805230218-aea8icj", "id": "20230805230218-aea8icj",
"title": "搜索资源文件内容", "title": "搜索资源文件内容",
"updated": "20231026085139" "type": "doc",
"updated": "20250903162923"
}, },
"Children": [ "Children": [
{ {
@ -46,7 +47,7 @@
"ListData": {}, "ListData": {},
"Properties": { "Properties": {
"id": "20230818101450-4a6lzdg", "id": "20230818101450-4a6lzdg",
"updated": "20230818101545" "updated": "20250903162923"
}, },
"Children": [ "Children": [
{ {
@ -58,7 +59,7 @@
}, },
"Properties": { "Properties": {
"id": "20230818101510-rfacaaf", "id": "20230818101510-rfacaaf",
"updated": "20230818101800" "updated": "20250903162915"
}, },
"Children": [ "Children": [
{ {
@ -66,12 +67,318 @@
"Type": "NodeParagraph", "Type": "NodeParagraph",
"Properties": { "Properties": {
"id": "20230818101510-duzarcy", "id": "20230818101510-duzarcy",
"updated": "20230818101800" "updated": "20250903162915"
}, },
"Children": [ "Children": [
{ {
"Type": "NodeText", "Type": "NodeText",
"Data": "文本文件(.txt、.md、.json、.log、.sql、.html、.xml、.java、.h、.c、.cpp、.go、.rs、.swift、.kt、.py、.php、.js、.css、.ts、.sh、.bat、.cmd、.ini、.yaml、.rst、.adoc、.textile、.opml、.org、.wiki" "Data": "文本文件("
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".txt"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".md"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".markdown"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".json"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".log"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".sql"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".html"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".xml"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".java"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".h"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".c"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".cpp"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".go"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".rs"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".swift"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".kt"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".py"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".php"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".js"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".css"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".ts"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".sh"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".bat"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".cmd"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".ini"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".yaml"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".rst"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".adoc"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".textile"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".opml"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".org"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".wiki"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".epub"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".cs"
},
{
"Type": "NodeText",
"Data": ""
} }
] ]
} }
@ -85,7 +392,8 @@
"Marker": "Kg==" "Marker": "Kg=="
}, },
"Properties": { "Properties": {
"id": "20230818101513-x5baw16" "id": "20230818101513-x5baw16",
"updated": "20250903162918"
}, },
"Children": [ "Children": [
{ {
@ -93,12 +401,21 @@
"Type": "NodeParagraph", "Type": "NodeParagraph",
"Properties": { "Properties": {
"id": "20230818101513-558ntbl", "id": "20230818101513-558ntbl",
"updated": "20230818101520" "updated": "20250903162918"
}, },
"Children": [ "Children": [
{ {
"Type": "NodeText", "Type": "NodeText",
"Data": ".docx" "Data": ""
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".docx"
},
{
"Type": "NodeText",
"Data": ""
} }
] ]
} }
@ -112,7 +429,8 @@
"Marker": "Kg==" "Marker": "Kg=="
}, },
"Properties": { "Properties": {
"id": "20230818101521-n1r8yqv" "id": "20230818101521-n1r8yqv",
"updated": "20250903162920"
}, },
"Children": [ "Children": [
{ {
@ -120,12 +438,21 @@
"Type": "NodeParagraph", "Type": "NodeParagraph",
"Properties": { "Properties": {
"id": "20230818101521-mutuxqo", "id": "20230818101521-mutuxqo",
"updated": "20230818101526" "updated": "20250903162920"
}, },
"Children": [ "Children": [
{ {
"Type": "NodeText", "Type": "NodeText",
"Data": ".pptx" "Data": ""
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".pptx"
},
{
"Type": "NodeText",
"Data": ""
} }
] ]
} }
@ -139,7 +466,8 @@
"Marker": "Kg==" "Marker": "Kg=="
}, },
"Properties": { "Properties": {
"id": "20230818101526-oortrwo" "id": "20230818101526-oortrwo",
"updated": "20250903162921"
}, },
"Children": [ "Children": [
{ {
@ -147,12 +475,21 @@
"Type": "NodeParagraph", "Type": "NodeParagraph",
"Properties": { "Properties": {
"id": "20230818101526-t4uvb3w", "id": "20230818101526-t4uvb3w",
"updated": "20230818101529" "updated": "20250903162921"
}, },
"Children": [ "Children": [
{ {
"Type": "NodeText", "Type": "NodeText",
"Data": ".xlsx" "Data": ""
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".xlsx"
},
{
"Type": "NodeText",
"Data": ""
} }
] ]
} }
@ -167,7 +504,7 @@
}, },
"Properties": { "Properties": {
"id": "20230818101543-ejcoq3j", "id": "20230818101543-ejcoq3j",
"updated": "20230818101545" "updated": "20250903162923"
}, },
"Children": [ "Children": [
{ {
@ -175,12 +512,21 @@
"Type": "NodeParagraph", "Type": "NodeParagraph",
"Properties": { "Properties": {
"id": "20230818101543-36waszk", "id": "20230818101543-36waszk",
"updated": "20230818101545" "updated": "20250903162923"
}, },
"Children": [ "Children": [
{ {
"Type": "NodeText", "Type": "NodeText",
"Data": ".pdf" "Data": ""
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".pdf"
},
{
"Type": "NodeText",
"Data": ""
} }
] ]
} }

View file

@ -3808,7 +3808,7 @@
"Children": [ "Children": [
{ {
"Type": "NodeText", "Type": "NodeText",
"Data": "代碼塊中使用時僅選中代碼塊中的內容" "Data": "連續按下兩次以選中文檔中所有已加載的內容塊;代碼塊中使用時僅選中代碼塊中的內容"
} }
] ]
} }

View file

@ -5,7 +5,8 @@
"Properties": { "Properties": {
"id": "20230805232920-5fdco36", "id": "20230805232920-5fdco36",
"title": "搜索資源文件內容", "title": "搜索資源文件內容",
"updated": "20231026085346" "type": "doc",
"updated": "20250903162952"
}, },
"Children": [ "Children": [
{ {
@ -46,7 +47,7 @@
"ListData": {}, "ListData": {},
"Properties": { "Properties": {
"id": "20230818102501-gq9fesz", "id": "20230818102501-gq9fesz",
"updated": "20230818102519" "updated": "20250903162952"
}, },
"Children": [ "Children": [
{ {
@ -58,7 +59,7 @@
}, },
"Properties": { "Properties": {
"id": "20230818102501-2qu8flm", "id": "20230818102501-2qu8flm",
"updated": "20230818102519" "updated": "20250903162947"
}, },
"Children": [ "Children": [
{ {
@ -66,12 +67,318 @@
"Type": "NodeParagraph", "Type": "NodeParagraph",
"Properties": { "Properties": {
"id": "20230818102501-p1l631d", "id": "20230818102501-p1l631d",
"updated": "20230818102519" "updated": "20250903162947"
}, },
"Children": [ "Children": [
{ {
"Type": "NodeText", "Type": "NodeText",
"Data": "文本文件(.txt、.md、.json、.log、.sql、.html、.xml、.java、.h、.c、.cpp、.go、.rs、.swift、.kt、.py、.php、.js、.css、.ts、.sh、.bat、.cmd、.ini、.yaml、.rst、.adoc、.textile、.opml、.org、.wiki" "Data": "文本文件("
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".txt"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".md"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".markdown"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".json"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".log"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".sql"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".html"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".xml"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".java"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".h"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".c"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".cpp"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".go"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".rs"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".swift"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".kt"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".py"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".php"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".js"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".css"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".ts"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".sh"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".bat"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".cmd"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".ini"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".yaml"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".rst"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".adoc"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".textile"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".opml"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".org"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".wiki"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".epub"
},
{
"Type": "NodeText",
"Data": "​、"
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".cs"
},
{
"Type": "NodeText",
"Data": ""
} }
] ]
} }
@ -86,7 +393,7 @@
}, },
"Properties": { "Properties": {
"id": "20230818102501-8jue7y8", "id": "20230818102501-8jue7y8",
"updated": "20230818102501" "updated": "20250903162949"
}, },
"Children": [ "Children": [
{ {
@ -94,12 +401,21 @@
"Type": "NodeParagraph", "Type": "NodeParagraph",
"Properties": { "Properties": {
"id": "20230818102501-fom9qf4", "id": "20230818102501-fom9qf4",
"updated": "20230818102501" "updated": "20250903162949"
}, },
"Children": [ "Children": [
{ {
"Type": "NodeText", "Type": "NodeText",
"Data": ".docx" "Data": ""
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".docx"
},
{
"Type": "NodeText",
"Data": ""
} }
] ]
} }
@ -114,7 +430,7 @@
}, },
"Properties": { "Properties": {
"id": "20230818102501-609htp0", "id": "20230818102501-609htp0",
"updated": "20230818102501" "updated": "20250903162950"
}, },
"Children": [ "Children": [
{ {
@ -122,12 +438,21 @@
"Type": "NodeParagraph", "Type": "NodeParagraph",
"Properties": { "Properties": {
"id": "20230818102501-fu9up7s", "id": "20230818102501-fu9up7s",
"updated": "20230818102501" "updated": "20250903162950"
}, },
"Children": [ "Children": [
{ {
"Type": "NodeText", "Type": "NodeText",
"Data": ".pptx" "Data": ""
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".pptx"
},
{
"Type": "NodeText",
"Data": ""
} }
] ]
} }
@ -142,7 +467,7 @@
}, },
"Properties": { "Properties": {
"id": "20230818102501-cjozdv1", "id": "20230818102501-cjozdv1",
"updated": "20230818102501" "updated": "20250903162951"
}, },
"Children": [ "Children": [
{ {
@ -150,12 +475,21 @@
"Type": "NodeParagraph", "Type": "NodeParagraph",
"Properties": { "Properties": {
"id": "20230818102501-ewonoc2", "id": "20230818102501-ewonoc2",
"updated": "20230818102501" "updated": "20250903162951"
}, },
"Children": [ "Children": [
{ {
"Type": "NodeText", "Type": "NodeText",
"Data": ".xlsx" "Data": ""
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".xlsx"
},
{
"Type": "NodeText",
"Data": ""
} }
] ]
} }
@ -170,7 +504,7 @@
}, },
"Properties": { "Properties": {
"id": "20230818102501-ljun2c0", "id": "20230818102501-ljun2c0",
"updated": "20230818102501" "updated": "20250903162952"
}, },
"Children": [ "Children": [
{ {
@ -178,12 +512,21 @@
"Type": "NodeParagraph", "Type": "NodeParagraph",
"Properties": { "Properties": {
"id": "20230818102501-w0e68xh", "id": "20230818102501-w0e68xh",
"updated": "20230818102501" "updated": "20250903162952"
}, },
"Children": [ "Children": [
{ {
"Type": "NodeText", "Type": "NodeText",
"Data": ".pdf" "Data": ""
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".pdf"
},
{
"Type": "NodeText",
"Data": ""
} }
] ]
} }

View file

@ -7,7 +7,7 @@
"id": "20240530101000-5k5d5i3", "id": "20240530101000-5k5d5i3",
"title": "アセットの内容検索", "title": "アセットの内容検索",
"type": "doc", "type": "doc",
"updated": "20240530101000" "updated": "20250903163024"
}, },
"Children": [ "Children": [
{ {
@ -50,7 +50,7 @@
"Properties": { "Properties": {
"ID": "20240530101000-gui4fuq", "ID": "20240530101000-gui4fuq",
"id": "20240530101000-dy607mr", "id": "20240530101000-dy607mr",
"updated": "20240530101000" "updated": "20250903163024"
}, },
"Children": [ "Children": [
{ {
@ -63,21 +63,326 @@
"Properties": { "Properties": {
"ID": "20240530101000-d6fzgev", "ID": "20240530101000-d6fzgev",
"id": "20240530101000-423ygdo", "id": "20240530101000-423ygdo",
"updated": "20240530101000" "updated": "20250903163024"
}, },
"Children": [ "Children": [
{ {
"ID": "20240530101000-5htsgo0", "ID": "20240530101000-5htsgo0",
"Type": "NodeParagraph", "Type": "NodeParagraph",
"Properties": { "Properties": {
"ID": "20240530101000-lunnpt0",
"id": "20240530101000-5htsgo0", "id": "20240530101000-5htsgo0",
"updated": "20240530101000" "updated": "20250903163024"
}, },
"Children": [ "Children": [
{ {
"Type": "NodeText", "Type": "NodeText",
"Data": "テキストファイル (.txt, .md, .json, .log, .sql, .html, .xml, .java, .h, .c, .cpp, .go, .rs, .swift, .kt, . py, .php, .js, .css, .ts, .sh, .bat, .cmd, .ini, .yaml, .rst, .adoc, .textile, .opml, .org, .wiki)" "Data": "テキストファイル ("
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".txt"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".md"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".markdown"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".json"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".log"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".sql"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".html"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".xml"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".java"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".h"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".c"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".cpp"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".go"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".rs"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".swift"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".kt"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".py"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".php"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".js"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".css"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".ts"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".sh"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".bat"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".cmd"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".ini"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".yaml"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".rst"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".adoc"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".textile"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".opml"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".org"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".wiki"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".epub"
},
{
"Type": "NodeText",
"Data": ", "
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".cs"
},
{
"Type": "NodeText",
"Data": ")"
} }
] ]
} }
@ -92,21 +397,30 @@
}, },
"Properties": { "Properties": {
"ID": "20240530101000-jhc3a4i", "ID": "20240530101000-jhc3a4i",
"id": "20240530101000-ddgjyye" "id": "20240530101000-ddgjyye",
"updated": "20250903163001"
}, },
"Children": [ "Children": [
{ {
"ID": "20240530101000-alu1ygl", "ID": "20240530101000-alu1ygl",
"Type": "NodeParagraph", "Type": "NodeParagraph",
"Properties": { "Properties": {
"ID": "20240530101000-cznhpu3",
"id": "20240530101000-alu1ygl", "id": "20240530101000-alu1ygl",
"updated": "20240530101000" "updated": "20250903163001"
}, },
"Children": [ "Children": [
{ {
"Type": "NodeText", "Type": "NodeText",
"Data": ".docx" "Data": ""
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".docx"
},
{
"Type": "NodeText",
"Data": ""
} }
] ]
} }
@ -121,21 +435,30 @@
}, },
"Properties": { "Properties": {
"ID": "20240530101000-0t3jtob", "ID": "20240530101000-0t3jtob",
"id": "20240530101000-t8ewu5o" "id": "20240530101000-t8ewu5o",
"updated": "20250903163002"
}, },
"Children": [ "Children": [
{ {
"ID": "20240530101000-afub9kt", "ID": "20240530101000-afub9kt",
"Type": "NodeParagraph", "Type": "NodeParagraph",
"Properties": { "Properties": {
"ID": "20240530101000-isl867u",
"id": "20240530101000-afub9kt", "id": "20240530101000-afub9kt",
"updated": "20240530101000" "updated": "20250903163002"
}, },
"Children": [ "Children": [
{ {
"Type": "NodeText", "Type": "NodeText",
"Data": ".pptx" "Data": ""
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".pptx"
},
{
"Type": "NodeText",
"Data": ""
} }
] ]
} }
@ -150,21 +473,30 @@
}, },
"Properties": { "Properties": {
"ID": "20240530101000-79w2hmi", "ID": "20240530101000-79w2hmi",
"id": "20240530101000-6c3or97" "id": "20240530101000-6c3or97",
"updated": "20250903163003"
}, },
"Children": [ "Children": [
{ {
"ID": "20240530101000-p5qs8ir", "ID": "20240530101000-p5qs8ir",
"Type": "NodeParagraph", "Type": "NodeParagraph",
"Properties": { "Properties": {
"ID": "20240530101000-zo7jhc4",
"id": "20240530101000-p5qs8ir", "id": "20240530101000-p5qs8ir",
"updated": "20240530101000" "updated": "20250903163003"
}, },
"Children": [ "Children": [
{ {
"Type": "NodeText", "Type": "NodeText",
"Data": ".xlsx" "Data": ""
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".xlsx"
},
{
"Type": "NodeText",
"Data": ""
} }
] ]
} }
@ -179,20 +511,30 @@
}, },
"Properties": { "Properties": {
"ID": "20240530101000-nm831gm", "ID": "20240530101000-nm831gm",
"id": "20240530101000-napqxcr" "id": "20240530101000-napqxcr",
"updated": "20250903163004"
}, },
"Children": [ "Children": [
{ {
"ID": "20240530101000-vknnawk", "ID": "20240530101000-vknnawk",
"Type": "NodeParagraph", "Type": "NodeParagraph",
"Properties": { "Properties": {
"ID": "20240530101000-l05rbi9", "id": "20240530101000-vknnawk",
"id": "20240530101000-vknnawk" "updated": "20250903163004"
}, },
"Children": [ "Children": [
{ {
"Type": "NodeText", "Type": "NodeText",
"Data": ".pdf" "Data": ""
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": ".pdf"
},
{
"Type": "NodeText",
"Data": ""
} }
] ]
} }

View file

@ -3775,7 +3775,7 @@
"Children": [ "Children": [
{ {
"Type": "NodeText", "Type": "NodeText",
"Data": "コードブロックではコードのみが選択されます" "Data": "文書内のすべてのロード済みコンテンツブロックを選択するにはダブルプレスしてください;コードブロックではコードのみが選択されます"
} }
] ]
} }

View file

@ -1,10 +1,10 @@
{ {
"name": "SiYuan", "name": "SiYuan",
"version": "3.3.0", "version": "3.3.2",
"description": "Refactor your thinking", "description": "Refactor your thinking",
"homepage": "https://b3log.org/siyuan", "homepage": "https://b3log.org/siyuan",
"main": "./electron/main.js", "main": "./electron/main.js",
"packageManager": "pnpm@10.15.0", "packageManager": "pnpm@10.15.1",
"scripts": { "scripts": {
"lint": "eslint . --fix --cache", "lint": "eslint . --fix --cache",
"dev": "webpack --mode development", "dev": "webpack --mode development",

264
app/pnpm-lock.yaml generated
View file

@ -17,16 +17,16 @@ importers:
version: 3.3.1 version: 3.3.1
'@eslint/js': '@eslint/js':
specifier: ^9.24.0 specifier: ^9.24.0
version: 9.34.0 version: 9.35.0
'@types/node': '@types/node':
specifier: ^18.13.0 specifier: ^18.13.0
version: 18.19.123 version: 18.19.124
'@typescript-eslint/eslint-plugin': '@typescript-eslint/eslint-plugin':
specifier: ^8.15.0 specifier: ^8.15.0
version: 8.41.0(@typescript-eslint/parser@8.41.0(eslint@9.34.0)(typescript@4.9.5))(eslint@9.34.0)(typescript@4.9.5) version: 8.42.0(@typescript-eslint/parser@8.42.0(eslint@9.35.0)(typescript@4.9.5))(eslint@9.35.0)(typescript@4.9.5)
'@typescript-eslint/parser': '@typescript-eslint/parser':
specifier: ^8.15.0 specifier: ^8.15.0
version: 8.41.0(eslint@9.34.0)(typescript@4.9.5) version: 8.42.0(eslint@9.35.0)(typescript@4.9.5)
blueimp-md5: blueimp-md5:
specifier: ^2.19.0 specifier: ^2.19.0
version: 2.19.0 version: 2.19.0
@ -38,7 +38,7 @@ importers:
version: 7.1.2(webpack@5.101.3) version: 7.1.2(webpack@5.101.3)
dayjs: dayjs:
specifier: ^1.11.5 specifier: ^1.11.5
version: 1.11.15 version: 1.11.18
electron: electron:
specifier: 37.4.0 specifier: 37.4.0
version: 37.4.0 version: 37.4.0
@ -53,7 +53,7 @@ importers:
version: 3.2.0(webpack@5.101.3) version: 3.2.0(webpack@5.101.3)
eslint: eslint:
specifier: ^9.15.0 specifier: ^9.15.0
version: 9.34.0 version: 9.35.0
file-loader: file-loader:
specifier: ^6.2.0 specifier: ^6.2.0
version: 6.2.0(webpack@5.101.3) version: 6.2.0(webpack@5.101.3)
@ -83,10 +83,10 @@ importers:
version: 2.1.2 version: 2.1.2
sass: sass:
specifier: ^1.89.2 specifier: ^1.89.2
version: 1.91.0 version: 1.92.1
sass-loader: sass-loader:
specifier: ^16.0.5 specifier: ^16.0.5
version: 16.0.5(sass@1.91.0)(webpack@5.101.3) version: 16.0.5(sass@1.92.1)(webpack@5.101.3)
typescript: typescript:
specifier: ^4.7.4 specifier: ^4.7.4
version: 4.9.5 version: 4.9.5
@ -303,8 +303,8 @@ packages:
cpu: [x64] cpu: [x64]
os: [win32] os: [win32]
'@eslint-community/eslint-utils@4.7.0': '@eslint-community/eslint-utils@4.8.0':
resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==} resolution: {integrity: sha512-MJQFqrZgcW0UNYLGOuQpey/oTN59vyWwplvCGZztn1cKz9agZPPYpJB7h2OMmuu7VLqkvEjN8feFZJmxNF9D+Q==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies: peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
@ -329,8 +329,8 @@ packages:
resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@eslint/js@9.34.0': '@eslint/js@9.35.0':
resolution: {integrity: sha512-EoyvqQnBNsV1CWaEJ559rxXL4c8V92gxirbawSmVUOWXlsRxxQXl6LmCpdUblgxgSkDIqKnhzba2SjRTI/A5Rw==} resolution: {integrity: sha512-30iXE9whjlILfWobBkNerJo+TXYsgVM5ERQwMcMKCHckHflCmf7wXDAHlARoWnh0s1U72WqlbeyE7iAcCzuCPw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@eslint/object-schema@2.1.6': '@eslint/object-schema@2.1.6':
@ -348,18 +348,14 @@ packages:
resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==}
engines: {node: '>=18.18.0'} engines: {node: '>=18.18.0'}
'@humanfs/node@0.16.6': '@humanfs/node@0.16.7':
resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==}
engines: {node: '>=18.18.0'} engines: {node: '>=18.18.0'}
'@humanwhocodes/module-importer@1.0.1': '@humanwhocodes/module-importer@1.0.1':
resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
engines: {node: '>=12.22'} engines: {node: '>=12.22'}
'@humanwhocodes/retry@0.3.1':
resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==}
engines: {node: '>=18.18'}
'@humanwhocodes/retry@0.4.3': '@humanwhocodes/retry@0.4.3':
resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==}
engines: {node: '>=18.18'} engines: {node: '>=18.18'}
@ -568,11 +564,11 @@ packages:
'@types/ms@2.1.0': '@types/ms@2.1.0':
resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==}
'@types/node@18.19.123': '@types/node@18.19.124':
resolution: {integrity: sha512-K7DIaHnh0mzVxreCR9qwgNxp3MH9dltPNIEddW9MYUlcKAzm+3grKNSTe2vCJHI1FaLpvpL5JGJrz1UZDKYvDg==} resolution: {integrity: sha512-hY4YWZFLs3ku6D2Gqo3RchTd9VRCcrjqp/I0mmohYeUVA5Y8eCXKJEasHxLAJVZRJuQogfd1GiJ9lgogBgKeuQ==}
'@types/node@22.18.0': '@types/node@22.18.1':
resolution: {integrity: sha512-m5ObIqwsUp6BZzyiy4RdZpzWGub9bqLJMvZDD0QMXhxjqMHMENlj+SqF5QxoUwaQNFe+8kz8XM8ZQhqkQPTgMQ==} resolution: {integrity: sha512-rzSDyhn4cYznVG+PCzGe1lwuMYJrcBS1fc3JqSa2PvtABwWo+dZ1ij5OVok3tqfpEBCBoaR4d7upFJk73HRJDw==}
'@types/plist@3.0.5': '@types/plist@3.0.5':
resolution: {integrity: sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA==} resolution: {integrity: sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA==}
@ -586,63 +582,63 @@ packages:
'@types/yauzl@2.10.3': '@types/yauzl@2.10.3':
resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==}
'@typescript-eslint/eslint-plugin@8.41.0': '@typescript-eslint/eslint-plugin@8.42.0':
resolution: {integrity: sha512-8fz6oa6wEKZrhXWro/S3n2eRJqlRcIa6SlDh59FXJ5Wp5XRZ8B9ixpJDcjadHq47hMx0u+HW6SNa6LjJQ6NLtw==} resolution: {integrity: sha512-Aq2dPqsQkxHOLfb2OPv43RnIvfj05nw8v/6n3B2NABIPpHnjQnaLo9QGMTvml+tv4korl/Cjfrb/BYhoL8UUTQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies: peerDependencies:
'@typescript-eslint/parser': ^8.41.0 '@typescript-eslint/parser': ^8.42.0
eslint: ^8.57.0 || ^9.0.0 eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <6.0.0' typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/parser@8.41.0': '@typescript-eslint/parser@8.42.0':
resolution: {integrity: sha512-gTtSdWX9xiMPA/7MV9STjJOOYtWwIJIYxkQxnSV1U3xcE+mnJSH3f6zI0RYP+ew66WSlZ5ed+h0VCxsvdC1jJg==} resolution: {integrity: sha512-r1XG74QgShUgXph1BYseJ+KZd17bKQib/yF3SR+demvytiRXrwd12Blnz5eYGm8tXaeRdd4x88MlfwldHoudGg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies: peerDependencies:
eslint: ^8.57.0 || ^9.0.0 eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <6.0.0' typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/project-service@8.41.0': '@typescript-eslint/project-service@8.42.0':
resolution: {integrity: sha512-b8V9SdGBQzQdjJ/IO3eDifGpDBJfvrNTp2QD9P2BeqWTGrRibgfgIlBSw6z3b6R7dPzg752tOs4u/7yCLxksSQ==} resolution: {integrity: sha512-vfVpLHAhbPjilrabtOSNcUDmBboQNrJUiNAGoImkZKnMjs2TIcWG33s4Ds0wY3/50aZmTMqJa6PiwkwezaAklg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies: peerDependencies:
typescript: '>=4.8.4 <6.0.0' typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/scope-manager@8.41.0': '@typescript-eslint/scope-manager@8.42.0':
resolution: {integrity: sha512-n6m05bXn/Cd6DZDGyrpXrELCPVaTnLdPToyhBoFkLIMznRUQUEQdSp96s/pcWSQdqOhrgR1mzJ+yItK7T+WPMQ==} resolution: {integrity: sha512-51+x9o78NBAVgQzOPd17DkNTnIzJ8T/O2dmMBLoK9qbY0Gm52XJcdJcCl18ExBMiHo6jPMErUQWUv5RLE51zJw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/tsconfig-utils@8.41.0': '@typescript-eslint/tsconfig-utils@8.42.0':
resolution: {integrity: sha512-TDhxYFPUYRFxFhuU5hTIJk+auzM/wKvWgoNYOPcOf6i4ReYlOoYN8q1dV5kOTjNQNJgzWN3TUUQMtlLOcUgdUw==} resolution: {integrity: sha512-kHeFUOdwAJfUmYKjR3CLgZSglGHjbNTi1H8sTYRYV2xX6eNz4RyJ2LIgsDLKf8Yi0/GL1WZAC/DgZBeBft8QAQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies: peerDependencies:
typescript: '>=4.8.4 <6.0.0' typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/type-utils@8.41.0': '@typescript-eslint/type-utils@8.42.0':
resolution: {integrity: sha512-63qt1h91vg3KsjVVonFJWjgSK7pZHSQFKH6uwqxAH9bBrsyRhO6ONoKyXxyVBzG1lJnFAJcKAcxLS54N1ee1OQ==} resolution: {integrity: sha512-9KChw92sbPTYVFw3JLRH1ockhyR3zqqn9lQXol3/YbI6jVxzWoGcT3AsAW0mu1MY0gYtsXnUGV/AKpkAj5tVlQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies: peerDependencies:
eslint: ^8.57.0 || ^9.0.0 eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <6.0.0' typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/types@8.41.0': '@typescript-eslint/types@8.42.0':
resolution: {integrity: sha512-9EwxsWdVqh42afLbHP90n2VdHaWU/oWgbH2P0CfcNfdKL7CuKpwMQGjwev56vWu9cSKU7FWSu6r9zck6CVfnag==} resolution: {integrity: sha512-LdtAWMiFmbRLNP7JNeY0SqEtJvGMYSzfiWBSmx+VSZ1CH+1zyl8Mmw1TT39OrtsRvIYShjJWzTDMPWZJCpwBlw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/typescript-estree@8.41.0': '@typescript-eslint/typescript-estree@8.42.0':
resolution: {integrity: sha512-D43UwUYJmGhuwHfY7MtNKRZMmfd8+p/eNSfFe6tH5mbVDto+VQCayeAt35rOx3Cs6wxD16DQtIKw/YXxt5E0UQ==} resolution: {integrity: sha512-ku/uYtT4QXY8sl9EDJETD27o3Ewdi72hcXg1ah/kkUgBvAYHLwj2ofswFFNXS+FL5G+AGkxBtvGt8pFBHKlHsQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies: peerDependencies:
typescript: '>=4.8.4 <6.0.0' typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/utils@8.41.0': '@typescript-eslint/utils@8.42.0':
resolution: {integrity: sha512-udbCVstxZ5jiPIXrdH+BZWnPatjlYwJuJkDA4Tbo3WyYLh8NvB+h/bKeSZHDOFKfphsZYJQqaFtLeXEqurQn1A==} resolution: {integrity: sha512-JnIzu7H3RH5BrKC4NoZqRfmjqCIS1u3hGZltDYJgkVdqAezl4L9d1ZLw+36huCujtSBSAirGINF/S4UxOcR+/g==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies: peerDependencies:
eslint: ^8.57.0 || ^9.0.0 eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <6.0.0' typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/visitor-keys@8.41.0': '@typescript-eslint/visitor-keys@8.42.0':
resolution: {integrity: sha512-+GeGMebMCy0elMNg67LRNoVnUFPIm37iu5CmHESVx56/9Jsfdpsvbv605DQ81Pi/x11IdKUsS5nzgTYbCQU9fg==} resolution: {integrity: sha512-3WbiuzoEowaEn8RSnhJBrxSwX8ULYE9CXaPepS2C2W3NSA5NNIvBaslpBSBElPq0UGr0xVJlXFWOAKIkyylydQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@webassemblyjs/ast@1.14.1': '@webassemblyjs/ast@1.14.1':
@ -918,8 +914,8 @@ packages:
camel-case@4.1.2: camel-case@4.1.2:
resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==} resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==}
caniuse-lite@1.0.30001737: caniuse-lite@1.0.30001741:
resolution: {integrity: sha512-BiloLiXtQNrY5UyF0+1nSJLXUENuhka2pzy2Fx5pGxqavdrxSCW4U6Pn/PoG3Efspi2frRbHpBV2XsrPE6EDlw==} resolution: {integrity: sha512-QGUGitqsc8ARjLdgAfxETDhRbJ0REsP6O3I96TAth/mVjh2cYzN2u+3AzPP3aVSm2FehEItaJw1xd+IGBXWeSw==}
chalk@4.1.2: chalk@4.1.2:
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
@ -1073,8 +1069,8 @@ packages:
engines: {node: '>=4'} engines: {node: '>=4'}
hasBin: true hasBin: true
dayjs@1.11.15: dayjs@1.11.18:
resolution: {integrity: sha512-MC+DfnSWiM9APs7fpiurHGCoeIx0Gdl6QZBy+5lu8MbYKN5FZEXqOgrundfibdfhGZ15o9hzmZ2xJjZnbvgKXQ==} resolution: {integrity: sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA==}
debounce@1.2.1: debounce@1.2.1:
resolution: {integrity: sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==} resolution: {integrity: sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==}
@ -1195,8 +1191,8 @@ packages:
electron-publish@26.0.11: electron-publish@26.0.11:
resolution: {integrity: sha512-a8QRH0rAPIWH9WyyS5LbNvW9Ark6qe63/LqDB7vu2JXYpi0Gma5Q60Dh4tmTqhOBQt0xsrzD8qE7C+D7j+B24A==} resolution: {integrity: sha512-a8QRH0rAPIWH9WyyS5LbNvW9Ark6qe63/LqDB7vu2JXYpi0Gma5Q60Dh4tmTqhOBQt0xsrzD8qE7C+D7j+B24A==}
electron-to-chromium@1.5.211: electron-to-chromium@1.5.214:
resolution: {integrity: sha512-IGBvimJkotaLzFnwIVgW9/UD/AOJ2tByUmeOrtqBfACSbAw5b1G0XpvdaieKyc7ULmbwXVx+4e4Be8pOPBrYkw==} resolution: {integrity: sha512-TpvUNdha+X3ybfU78NoQatKvQEm1oq3lf2QbnmCEdw+Bd9RuIAY+hJTvq1avzHM0f7EJfnH3vbCnbzKzisc/9Q==}
electron-winstaller@5.4.0: electron-winstaller@5.4.0:
resolution: {integrity: sha512-bO3y10YikuUwUuDUQRM4KfwNkKhnpVO7IPdbsrejwN9/AABJzzTQ4GeHwyzNSrVO+tEH3/Np255a3sVZpZDjvg==} resolution: {integrity: sha512-bO3y10YikuUwUuDUQRM4KfwNkKhnpVO7IPdbsrejwN9/AABJzzTQ4GeHwyzNSrVO+tEH3/Np255a3sVZpZDjvg==}
@ -1298,8 +1294,8 @@ packages:
resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
eslint@9.34.0: eslint@9.35.0:
resolution: {integrity: sha512-RNCHRX5EwdrESy3Jc9o8ie8Bog+PeYvvSR8sDGoZxNFTvZ4dlxUB3WzQ3bQMztFrSRODGrLLj8g6OFuGY/aiQg==} resolution: {integrity: sha512-QePbBFMJFjgmlE+cXAlbHZbHpdFVS2E/6vzCy7aKlebddvl1vadiC4JFV5u/wqTkNUwEV8WrQi257jf5f06hrg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
hasBin: true hasBin: true
peerDependencies: peerDependencies:
@ -2002,8 +1998,8 @@ packages:
no-case@3.0.4: no-case@3.0.4:
resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==}
node-abi@3.75.0: node-abi@3.77.0:
resolution: {integrity: sha512-OhYaY5sDsIka7H7AtijtI9jwGYLyl29eQn/W623DiN/MIv5sUqc4g7BIDThX+gb7di9f6xK02nkp8sdfFWZLTg==} resolution: {integrity: sha512-DSmt0OEcLoK4i3NuscSbGjOf3bqiDEutejqENSplMSFA/gmB8mkED9G4pKWnPl7MDU4rSHebKPHeitpDfyH0cQ==}
engines: {node: '>=10'} engines: {node: '>=10'}
node-addon-api@1.7.2: node-addon-api@1.7.2:
@ -2015,8 +2011,8 @@ packages:
node-api-version@0.2.1: node-api-version@0.2.1:
resolution: {integrity: sha512-2xP/IGGMmmSQpI1+O/k72jF/ykvZ89JeuKX3TLJAYPDVLUalrshrLHkeVcCCZqG/eEa635cr8IBYzgnDvM2O8Q==} resolution: {integrity: sha512-2xP/IGGMmmSQpI1+O/k72jF/ykvZ89JeuKX3TLJAYPDVLUalrshrLHkeVcCCZqG/eEa635cr8IBYzgnDvM2O8Q==}
node-releases@2.0.19: node-releases@2.0.20:
resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} resolution: {integrity: sha512-7gK6zSXEH6neM212JgfYFXe+GmZQM+fia5SsusuBIUgnPheLFBmIPhtFoAQRj8/7wASYQnbDlHPVwY0BefoFgA==}
nopt@6.0.0: nopt@6.0.0:
resolution: {integrity: sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==} resolution: {integrity: sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==}
@ -2377,8 +2373,8 @@ packages:
webpack: webpack:
optional: true optional: true
sass@1.91.0: sass@1.92.1:
resolution: {integrity: sha512-aFOZHGf+ur+bp1bCHZ+u8otKGh77ZtmFyXDo4tlYvT7PWql41Kwd8wdkPqhhT+h2879IVblcHFglIMofsFd1EA==} resolution: {integrity: sha512-ffmsdbwqb3XeyR8jJR6KelIXARM9bFQe8A6Q3W4Klmwy5Ckd5gz7jgUNHo4UOqutU5Sk1DtKLbpDP0nLCg1xqQ==}
engines: {node: '>=14.0.0'} engines: {node: '>=14.0.0'}
hasBin: true hasBin: true
@ -2559,8 +2555,8 @@ packages:
engines: {node: '>=6.0.0'} engines: {node: '>=6.0.0'}
hasBin: true hasBin: true
terser@5.43.1: terser@5.44.0:
resolution: {integrity: sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==} resolution: {integrity: sha512-nIVck8DK+GM/0Frwd+nIhZ84pR/BX7rmXMfYwyg+Sri5oGVE99/E3KvXqpC2xHFxyqXyGHTKBSioxxplrO4I4w==}
engines: {node: '>=10'} engines: {node: '>=10'}
hasBin: true hasBin: true
@ -2857,7 +2853,7 @@ snapshots:
detect-libc: 2.0.4 detect-libc: 2.0.4
fs-extra: 10.1.0 fs-extra: 10.1.0
got: 11.8.6 got: 11.8.6
node-abi: 3.75.0 node-abi: 3.77.0
node-api-version: 0.2.1 node-api-version: 0.2.1
ora: 5.4.1 ora: 5.4.1
read-binary-file-arch: 1.0.6 read-binary-file-arch: 1.0.6
@ -2964,9 +2960,9 @@ snapshots:
'@esbuild/win32-x64@0.19.12': '@esbuild/win32-x64@0.19.12':
optional: true optional: true
'@eslint-community/eslint-utils@4.7.0(eslint@9.34.0)': '@eslint-community/eslint-utils@4.8.0(eslint@9.35.0)':
dependencies: dependencies:
eslint: 9.34.0 eslint: 9.35.0
eslint-visitor-keys: 3.4.3 eslint-visitor-keys: 3.4.3
'@eslint-community/regexpp@4.12.1': {} '@eslint-community/regexpp@4.12.1': {}
@ -2999,7 +2995,7 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@eslint/js@9.34.0': {} '@eslint/js@9.35.0': {}
'@eslint/object-schema@2.1.6': {} '@eslint/object-schema@2.1.6': {}
@ -3012,15 +3008,13 @@ snapshots:
'@humanfs/core@0.19.1': {} '@humanfs/core@0.19.1': {}
'@humanfs/node@0.16.6': '@humanfs/node@0.16.7':
dependencies: dependencies:
'@humanfs/core': 0.19.1 '@humanfs/core': 0.19.1
'@humanwhocodes/retry': 0.3.1 '@humanwhocodes/retry': 0.4.3
'@humanwhocodes/module-importer@1.0.1': {} '@humanwhocodes/module-importer@1.0.1': {}
'@humanwhocodes/retry@0.3.1': {}
'@humanwhocodes/retry@0.4.3': {} '@humanwhocodes/retry@0.4.3': {}
'@isaacs/balanced-match@4.0.1': {} '@isaacs/balanced-match@4.0.1': {}
@ -3170,7 +3164,7 @@ snapshots:
dependencies: dependencies:
'@types/http-cache-semantics': 4.0.4 '@types/http-cache-semantics': 4.0.4
'@types/keyv': 3.1.4 '@types/keyv': 3.1.4
'@types/node': 18.19.123 '@types/node': 18.19.124
'@types/responselike': 1.0.3 '@types/responselike': 1.0.3
'@types/debug@4.1.12': '@types/debug@4.1.12':
@ -3191,12 +3185,12 @@ snapshots:
'@types/fs-extra@9.0.13': '@types/fs-extra@9.0.13':
dependencies: dependencies:
'@types/node': 18.19.123 '@types/node': 18.19.124
'@types/glob@7.2.0': '@types/glob@7.2.0':
dependencies: dependencies:
'@types/minimatch': 6.0.0 '@types/minimatch': 6.0.0
'@types/node': 18.19.123 '@types/node': 18.19.124
'@types/html-minifier-terser@6.1.0': {} '@types/html-minifier-terser@6.1.0': {}
@ -3206,7 +3200,7 @@ snapshots:
'@types/keyv@3.1.4': '@types/keyv@3.1.4':
dependencies: dependencies:
'@types/node': 18.19.123 '@types/node': 18.19.124
'@types/minimatch@6.0.0': '@types/minimatch@6.0.0':
dependencies: dependencies:
@ -3214,41 +3208,41 @@ snapshots:
'@types/ms@2.1.0': {} '@types/ms@2.1.0': {}
'@types/node@18.19.123': '@types/node@18.19.124':
dependencies: dependencies:
undici-types: 5.26.5 undici-types: 5.26.5
'@types/node@22.18.0': '@types/node@22.18.1':
dependencies: dependencies:
undici-types: 6.21.0 undici-types: 6.21.0
'@types/plist@3.0.5': '@types/plist@3.0.5':
dependencies: dependencies:
'@types/node': 18.19.123 '@types/node': 18.19.124
xmlbuilder: 15.1.1 xmlbuilder: 15.1.1
optional: true optional: true
'@types/responselike@1.0.3': '@types/responselike@1.0.3':
dependencies: dependencies:
'@types/node': 18.19.123 '@types/node': 18.19.124
'@types/verror@1.10.11': '@types/verror@1.10.11':
optional: true optional: true
'@types/yauzl@2.10.3': '@types/yauzl@2.10.3':
dependencies: dependencies:
'@types/node': 18.19.123 '@types/node': 18.19.124
optional: true optional: true
'@typescript-eslint/eslint-plugin@8.41.0(@typescript-eslint/parser@8.41.0(eslint@9.34.0)(typescript@4.9.5))(eslint@9.34.0)(typescript@4.9.5)': '@typescript-eslint/eslint-plugin@8.42.0(@typescript-eslint/parser@8.42.0(eslint@9.35.0)(typescript@4.9.5))(eslint@9.35.0)(typescript@4.9.5)':
dependencies: dependencies:
'@eslint-community/regexpp': 4.12.1 '@eslint-community/regexpp': 4.12.1
'@typescript-eslint/parser': 8.41.0(eslint@9.34.0)(typescript@4.9.5) '@typescript-eslint/parser': 8.42.0(eslint@9.35.0)(typescript@4.9.5)
'@typescript-eslint/scope-manager': 8.41.0 '@typescript-eslint/scope-manager': 8.42.0
'@typescript-eslint/type-utils': 8.41.0(eslint@9.34.0)(typescript@4.9.5) '@typescript-eslint/type-utils': 8.42.0(eslint@9.35.0)(typescript@4.9.5)
'@typescript-eslint/utils': 8.41.0(eslint@9.34.0)(typescript@4.9.5) '@typescript-eslint/utils': 8.42.0(eslint@9.35.0)(typescript@4.9.5)
'@typescript-eslint/visitor-keys': 8.41.0 '@typescript-eslint/visitor-keys': 8.42.0
eslint: 9.34.0 eslint: 9.35.0
graphemer: 1.4.0 graphemer: 1.4.0
ignore: 7.0.5 ignore: 7.0.5
natural-compare: 1.4.0 natural-compare: 1.4.0
@ -3257,56 +3251,56 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@typescript-eslint/parser@8.41.0(eslint@9.34.0)(typescript@4.9.5)': '@typescript-eslint/parser@8.42.0(eslint@9.35.0)(typescript@4.9.5)':
dependencies: dependencies:
'@typescript-eslint/scope-manager': 8.41.0 '@typescript-eslint/scope-manager': 8.42.0
'@typescript-eslint/types': 8.41.0 '@typescript-eslint/types': 8.42.0
'@typescript-eslint/typescript-estree': 8.41.0(typescript@4.9.5) '@typescript-eslint/typescript-estree': 8.42.0(typescript@4.9.5)
'@typescript-eslint/visitor-keys': 8.41.0 '@typescript-eslint/visitor-keys': 8.42.0
debug: 4.4.1 debug: 4.4.1
eslint: 9.34.0 eslint: 9.35.0
typescript: 4.9.5 typescript: 4.9.5
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@typescript-eslint/project-service@8.41.0(typescript@4.9.5)': '@typescript-eslint/project-service@8.42.0(typescript@4.9.5)':
dependencies: dependencies:
'@typescript-eslint/tsconfig-utils': 8.41.0(typescript@4.9.5) '@typescript-eslint/tsconfig-utils': 8.42.0(typescript@4.9.5)
'@typescript-eslint/types': 8.41.0 '@typescript-eslint/types': 8.42.0
debug: 4.4.1 debug: 4.4.1
typescript: 4.9.5 typescript: 4.9.5
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@typescript-eslint/scope-manager@8.41.0': '@typescript-eslint/scope-manager@8.42.0':
dependencies: dependencies:
'@typescript-eslint/types': 8.41.0 '@typescript-eslint/types': 8.42.0
'@typescript-eslint/visitor-keys': 8.41.0 '@typescript-eslint/visitor-keys': 8.42.0
'@typescript-eslint/tsconfig-utils@8.41.0(typescript@4.9.5)': '@typescript-eslint/tsconfig-utils@8.42.0(typescript@4.9.5)':
dependencies: dependencies:
typescript: 4.9.5 typescript: 4.9.5
'@typescript-eslint/type-utils@8.41.0(eslint@9.34.0)(typescript@4.9.5)': '@typescript-eslint/type-utils@8.42.0(eslint@9.35.0)(typescript@4.9.5)':
dependencies: dependencies:
'@typescript-eslint/types': 8.41.0 '@typescript-eslint/types': 8.42.0
'@typescript-eslint/typescript-estree': 8.41.0(typescript@4.9.5) '@typescript-eslint/typescript-estree': 8.42.0(typescript@4.9.5)
'@typescript-eslint/utils': 8.41.0(eslint@9.34.0)(typescript@4.9.5) '@typescript-eslint/utils': 8.42.0(eslint@9.35.0)(typescript@4.9.5)
debug: 4.4.1 debug: 4.4.1
eslint: 9.34.0 eslint: 9.35.0
ts-api-utils: 2.1.0(typescript@4.9.5) ts-api-utils: 2.1.0(typescript@4.9.5)
typescript: 4.9.5 typescript: 4.9.5
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@typescript-eslint/types@8.41.0': {} '@typescript-eslint/types@8.42.0': {}
'@typescript-eslint/typescript-estree@8.41.0(typescript@4.9.5)': '@typescript-eslint/typescript-estree@8.42.0(typescript@4.9.5)':
dependencies: dependencies:
'@typescript-eslint/project-service': 8.41.0(typescript@4.9.5) '@typescript-eslint/project-service': 8.42.0(typescript@4.9.5)
'@typescript-eslint/tsconfig-utils': 8.41.0(typescript@4.9.5) '@typescript-eslint/tsconfig-utils': 8.42.0(typescript@4.9.5)
'@typescript-eslint/types': 8.41.0 '@typescript-eslint/types': 8.42.0
'@typescript-eslint/visitor-keys': 8.41.0 '@typescript-eslint/visitor-keys': 8.42.0
debug: 4.4.1 debug: 4.4.1
fast-glob: 3.3.3 fast-glob: 3.3.3
is-glob: 4.0.3 is-glob: 4.0.3
@ -3317,20 +3311,20 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@typescript-eslint/utils@8.41.0(eslint@9.34.0)(typescript@4.9.5)': '@typescript-eslint/utils@8.42.0(eslint@9.35.0)(typescript@4.9.5)':
dependencies: dependencies:
'@eslint-community/eslint-utils': 4.7.0(eslint@9.34.0) '@eslint-community/eslint-utils': 4.8.0(eslint@9.35.0)
'@typescript-eslint/scope-manager': 8.41.0 '@typescript-eslint/scope-manager': 8.42.0
'@typescript-eslint/types': 8.41.0 '@typescript-eslint/types': 8.42.0
'@typescript-eslint/typescript-estree': 8.41.0(typescript@4.9.5) '@typescript-eslint/typescript-estree': 8.42.0(typescript@4.9.5)
eslint: 9.34.0 eslint: 9.35.0
typescript: 4.9.5 typescript: 4.9.5
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@typescript-eslint/visitor-keys@8.41.0': '@typescript-eslint/visitor-keys@8.42.0':
dependencies: dependencies:
'@typescript-eslint/types': 8.41.0 '@typescript-eslint/types': 8.42.0
eslint-visitor-keys: 4.2.1 eslint-visitor-keys: 4.2.1
'@webassemblyjs/ast@1.14.1': '@webassemblyjs/ast@1.14.1':
@ -3598,9 +3592,9 @@ snapshots:
browserslist@4.25.4: browserslist@4.25.4:
dependencies: dependencies:
caniuse-lite: 1.0.30001737 caniuse-lite: 1.0.30001741
electron-to-chromium: 1.5.211 electron-to-chromium: 1.5.214
node-releases: 2.0.19 node-releases: 2.0.20
update-browserslist-db: 1.1.3(browserslist@4.25.4) update-browserslist-db: 1.1.3(browserslist@4.25.4)
buffer-crc32@0.2.13: {} buffer-crc32@0.2.13: {}
@ -3688,7 +3682,7 @@ snapshots:
pascal-case: 3.1.2 pascal-case: 3.1.2
tslib: 2.8.1 tslib: 2.8.1
caniuse-lite@1.0.30001737: {} caniuse-lite@1.0.30001741: {}
chalk@4.1.2: chalk@4.1.2:
dependencies: dependencies:
@ -3828,7 +3822,7 @@ snapshots:
cssesc@3.0.0: {} cssesc@3.0.0: {}
dayjs@1.11.15: {} dayjs@1.11.18: {}
debounce@1.2.1: {} debounce@1.2.1: {}
@ -4001,7 +3995,7 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
electron-to-chromium@1.5.211: {} electron-to-chromium@1.5.214: {}
electron-winstaller@5.4.0: electron-winstaller@5.4.0:
dependencies: dependencies:
@ -4018,7 +4012,7 @@ snapshots:
electron@37.4.0: electron@37.4.0:
dependencies: dependencies:
'@electron/get': 2.0.3 '@electron/get': 2.0.3
'@types/node': 22.18.0 '@types/node': 22.18.1
extract-zip: 2.0.1 extract-zip: 2.0.1
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -4122,17 +4116,17 @@ snapshots:
eslint-visitor-keys@4.2.1: {} eslint-visitor-keys@4.2.1: {}
eslint@9.34.0: eslint@9.35.0:
dependencies: dependencies:
'@eslint-community/eslint-utils': 4.7.0(eslint@9.34.0) '@eslint-community/eslint-utils': 4.8.0(eslint@9.35.0)
'@eslint-community/regexpp': 4.12.1 '@eslint-community/regexpp': 4.12.1
'@eslint/config-array': 0.21.0 '@eslint/config-array': 0.21.0
'@eslint/config-helpers': 0.3.1 '@eslint/config-helpers': 0.3.1
'@eslint/core': 0.15.2 '@eslint/core': 0.15.2
'@eslint/eslintrc': 3.3.1 '@eslint/eslintrc': 3.3.1
'@eslint/js': 9.34.0 '@eslint/js': 9.35.0
'@eslint/plugin-kit': 0.3.5 '@eslint/plugin-kit': 0.3.5
'@humanfs/node': 0.16.6 '@humanfs/node': 0.16.7
'@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/module-importer': 1.0.1
'@humanwhocodes/retry': 0.4.3 '@humanwhocodes/retry': 0.4.3
'@types/estree': 1.0.8 '@types/estree': 1.0.8
@ -4479,7 +4473,7 @@ snapshots:
he: 1.2.0 he: 1.2.0
param-case: 3.0.4 param-case: 3.0.4
relateurl: 0.2.7 relateurl: 0.2.7
terser: 5.43.1 terser: 5.44.0
html-webpack-plugin@5.6.4(webpack@5.101.3): html-webpack-plugin@5.6.4(webpack@5.101.3):
dependencies: dependencies:
@ -4651,7 +4645,7 @@ snapshots:
jest-worker@27.5.1: jest-worker@27.5.1:
dependencies: dependencies:
'@types/node': 18.19.123 '@types/node': 18.19.124
merge-stream: 2.0.0 merge-stream: 2.0.0
supports-color: 8.1.1 supports-color: 8.1.1
@ -4882,7 +4876,7 @@ snapshots:
lower-case: 2.0.2 lower-case: 2.0.2
tslib: 2.8.1 tslib: 2.8.1
node-abi@3.75.0: node-abi@3.77.0:
dependencies: dependencies:
semver: 7.7.2 semver: 7.7.2
@ -4896,7 +4890,7 @@ snapshots:
dependencies: dependencies:
semver: 7.7.2 semver: 7.7.2
node-releases@2.0.19: {} node-releases@2.0.20: {}
nopt@6.0.0: nopt@6.0.0:
dependencies: dependencies:
@ -5206,14 +5200,14 @@ snapshots:
dependencies: dependencies:
truncate-utf8-bytes: 1.0.2 truncate-utf8-bytes: 1.0.2
sass-loader@16.0.5(sass@1.91.0)(webpack@5.101.3): sass-loader@16.0.5(sass@1.92.1)(webpack@5.101.3):
dependencies: dependencies:
neo-async: 2.6.2 neo-async: 2.6.2
optionalDependencies: optionalDependencies:
sass: 1.91.0 sass: 1.92.1
webpack: 5.101.3(webpack-cli@4.10.0) webpack: 5.101.3(webpack-cli@4.10.0)
sass@1.91.0: sass@1.92.1:
dependencies: dependencies:
chokidar: 4.0.3 chokidar: 4.0.3
immutable: 5.1.3 immutable: 5.1.3
@ -5389,7 +5383,7 @@ snapshots:
jest-worker: 27.5.1 jest-worker: 27.5.1
schema-utils: 4.3.2 schema-utils: 4.3.2
serialize-javascript: 6.0.2 serialize-javascript: 6.0.2
terser: 5.43.1 terser: 5.44.0
webpack: 5.101.3(webpack-cli@4.10.0) webpack: 5.101.3(webpack-cli@4.10.0)
terser@4.8.1: terser@4.8.1:
@ -5399,7 +5393,7 @@ snapshots:
source-map: 0.6.1 source-map: 0.6.1
source-map-support: 0.5.21 source-map-support: 0.5.21
terser@5.43.1: terser@5.44.0:
dependencies: dependencies:
'@jridgewell/source-map': 0.3.11 '@jridgewell/source-map': 0.3.11
acorn: 8.15.0 acorn: 8.15.0

View file

@ -62,7 +62,7 @@ export const pdfResize = () => {
export const genAssetHTML = (type: string, pathString: string, imgName: string, linkName: string) => { export const genAssetHTML = (type: string, pathString: string, imgName: string, linkName: string) => {
let html = ""; let html = "";
if (Constants.SIYUAN_ASSETS_AUDIO.includes(type)) { if (Constants.SIYUAN_ASSETS_AUDIO.includes(type)) {
html = `<div data-node-id="${Lute.NewNodeID()}" data-type="NodeAudio" class="iframe" updated="${dayjs().format("YYYYMMDDHHmmss")}"><div class="iframe-content"><audio controls="controls" src="${pathString}" data-src="${pathString}"></audio>${Constants.ZWSP}</div><div class="protyle-attr" contenteditable="false">${Constants.ZWSP}</div></div>`; html = `<div data-node-id="${Lute.NewNodeID()}" data-type="NodeAudio" class="iframe" updated="${dayjs().format("YYYYMMDDHHmmss")}"><div class="iframe-content"><audio controls="controls" src="${pathString}"></audio>${Constants.ZWSP}</div><div class="protyle-attr" contenteditable="false">${Constants.ZWSP}</div></div>`;
} else if (Constants.SIYUAN_ASSETS_IMAGE.includes(type)) { } else if (Constants.SIYUAN_ASSETS_IMAGE.includes(type)) {
let netHTML = ""; let netHTML = "";
if (!pathString.startsWith("assets/")) { if (!pathString.startsWith("assets/")) {
@ -70,7 +70,7 @@ export const genAssetHTML = (type: string, pathString: string, imgName: string,
} }
html = `<span contenteditable="false" data-type="img" class="img"><span> </span><span><span class="protyle-action protyle-icons"><span class="protyle-icon protyle-icon--only"><svg><use xlink:href="#iconMore"></use></svg></span></span><img src="${pathString}" data-src="${pathString}" alt="${imgName}" /><span class="protyle-action__drag"></span>${netHTML}<span class="protyle-action__title"></span></span><span> </span></span>`; html = `<span contenteditable="false" data-type="img" class="img"><span> </span><span><span class="protyle-action protyle-icons"><span class="protyle-icon protyle-icon--only"><svg><use xlink:href="#iconMore"></use></svg></span></span><img src="${pathString}" data-src="${pathString}" alt="${imgName}" /><span class="protyle-action__drag"></span>${netHTML}<span class="protyle-action__title"></span></span><span> </span></span>`;
} else if (Constants.SIYUAN_ASSETS_VIDEO.includes(type)) { } else if (Constants.SIYUAN_ASSETS_VIDEO.includes(type)) {
html = `<div data-node-id="${Lute.NewNodeID()}" data-type="NodeVideo" class="iframe" updated="${dayjs().format("YYYYMMDDHHmmss")}"><div class="iframe-content">${Constants.ZWSP}<video controls="controls" src="${pathString}" data-src="${pathString}"></video><span class="protyle-action__drag" contenteditable="false"></span></div><div class="protyle-attr" contenteditable="false">${Constants.ZWSP}</div></div>`; html = `<div data-node-id="${Lute.NewNodeID()}" data-type="NodeVideo" class="iframe" updated="${dayjs().format("YYYYMMDDHHmmss")}"><div class="iframe-content">${Constants.ZWSP}<video controls="controls" src="${pathString}"></video><span class="protyle-action__drag" contenteditable="false"></span></div><div class="protyle-attr" contenteditable="false">${Constants.ZWSP}</div></div>`;
} else { } else {
html = `<span data-type="a" data-href="${pathString}">${linkName}</span>`; html = `<span data-type="a" data-href="${pathString}">${linkName}</span>`;
} }

View file

@ -4,7 +4,7 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" <meta name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, viewport-fit=cover, user-scalable=no"> content="width=device-width, initial-scale=1.0, maximum-scale=1.0, viewport-fit=cover, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes"> <meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"> <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<link rel="apple-touch-icon" href="../../icon.png"> <link rel="apple-touch-icon" href="../../icon.png">
<style id="editorAttr" type="text/css"></style> <style id="editorAttr" type="text/css"></style>

View file

@ -4,7 +4,7 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" <meta name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, viewport-fit=cover, user-scalable=no"> content="width=device-width, initial-scale=1.0, maximum-scale=1.0, viewport-fit=cover, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes"> <meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"> <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<link rel="manifest" href="/manifest.webmanifest" crossorigin="use-credentials"> <link rel="manifest" href="/manifest.webmanifest" crossorigin="use-credentials">
<link rel="apple-touch-icon" href="../../icon.png"> <link rel="apple-touch-icon" href="../../icon.png">

View file

@ -67,10 +67,14 @@ export const viewCards = (app: App, deckID: string, title: string, deckType: "Tr
if (response.data.blocks.length > 0) { if (response.data.blocks.length > 0) {
edit = new Protyle(app, dialog.element.querySelector("#cardPreview") as HTMLElement, { edit = new Protyle(app, dialog.element.querySelector("#cardPreview") as HTMLElement, {
blockId: "", blockId: "",
action: [Constants.CB_GET_ALL],
render: { render: {
gutter: true, gutter: true,
breadcrumbDocName: true breadcrumbDocName: true,
title: true,
hideTitleOnZoom: true,
}, },
typewriterMode: false
}); });
if (window.siyuan.mobile) { if (window.siyuan.mobile) {
window.siyuan.mobile.popEditor = edit; window.siyuan.mobile.popEditor = edit;
@ -310,6 +314,10 @@ const getArticle = (edit: Protyle, id: string) => {
data: getResponse, data: getResponse,
protyle: edit.protyle, protyle: edit.protyle,
action: getResponse.data.rootID === getResponse.data.id ? [Constants.CB_GET_HTML] : [Constants.CB_GET_ALL, Constants.CB_GET_HTML], action: getResponse.data.rootID === getResponse.data.id ? [Constants.CB_GET_HTML] : [Constants.CB_GET_ALL, Constants.CB_GET_HTML],
afterCB() {
edit.protyle.title.element.removeAttribute("data-render");
edit.protyle.title.render(edit.protyle, response);
}
}); });
}); });
}); });

View file

@ -6,7 +6,6 @@ import {processSync} from "../dialog/processSystem";
import {getCloudURL} from "./util/about"; import {getCloudURL} from "./util/about";
import {openByMobile} from "../protyle/util/compatibility"; import {openByMobile} from "../protyle/util/compatibility";
import {confirmDialog} from "../dialog/confirmDialog"; import {confirmDialog} from "../dialog/confirmDialog";
import {isKernelInMobile} from "../util/functions";
const renderProvider = (provider: number) => { const renderProvider = (provider: number) => {
if (provider === 0) { if (provider === 0) {
@ -41,7 +40,13 @@ const renderProvider = (provider: number) => {
</div>`; </div>`;
} }
if (!isPaidUser()) { if (!isPaidUser()) {
return `<div class="b3-label b3-label--inner">${window.siyuan.languages["_kernel"][214].replaceAll("${accountServer}", getCloudURL(""))}</div>`; return `<div>
${window.siyuan.languages["_kernel"][214].replaceAll("${accountServer}", getCloudURL(""))}
</div>
<div class="ft__error${provider == 4 ? "" : " fn__none"}">
<div class="fn__hr--b"></div>
${window.siyuan.languages.mobileNotSupport}
</div>`;
} }
if (provider === 2) { if (provider === 2) {
return `<div class="b3-label b3-label--inner"> return `<div class="b3-label b3-label--inner">
@ -180,16 +185,11 @@ const renderProvider = (provider: number) => {
</button> </button>
</div>`; </div>`;
} else if (provider === 4) { } else if (provider === 4) {
if (isKernelInMobile()) {
return `<div class="b3-label b3-label--inner">
${window.siyuan.languages.syncThirdPartyProviderLocalIntro}
<div class="fn__hr"></div>
<em>${window.siyuan.languages.proFeature}</em>
<div class="fn__hr"></div>
${window.siyuan.languages.deviceNotSupport}
</div>`;
}
return `<div class="b3-label b3-label--inner"> return `<div class="b3-label b3-label--inner">
<div class="ft__error">
${window.siyuan.languages.mobileNotSupport}
</div>
<div class="fn__hr"></div>
${window.siyuan.languages.syncThirdPartyProviderLocalIntro} ${window.siyuan.languages.syncThirdPartyProviderLocalIntro}
<div class="fn__hr"></div> <div class="fn__hr"></div>
<em>${window.siyuan.languages.proFeature}</em> <em>${window.siyuan.languages.proFeature}</em>

View file

@ -62,33 +62,31 @@ export const openSnippets = () => {
<div class="fn__flex-1" style="overflow:auto;padding: 16px 24px"> <div class="fn__flex-1" style="overflow:auto;padding: 16px 24px">
<div> <div>
<div class="fn__flex"> <div class="fn__flex">
<div class="fn__flex-1"></div> <div class="b3-form__icon fn__flex-1">
<div class="b3-form__icon">
<svg class="b3-form__icon-icon"><use xlink:href="#iconSearch"></use></svg> <svg class="b3-form__icon-icon"><use xlink:href="#iconSearch"></use></svg>
<input data-type="css" data-action="search" type="text" placeholder="${window.siyuan.languages.search}" class="b3-text-field b3-form__icon-input"> <input data-type="css" data-action="search" type="text" placeholder="${window.siyuan.languages.search}" class="b3-text-field b3-form__icon-input fn__block">
</div> </div>
<div class="fn__space"></div> <div class="fn__space"></div>
<span aria-label="${window.siyuan.languages.addAttr} CSS" id="addCodeSnippetCSS" class="b3-tooltips b3-tooltips__sw block__icon block__icon--show"> <span aria-label="${window.siyuan.languages.addAttr} CSS" id="addCodeSnippetCSS" class="b3-tooltips b3-tooltips__sw block__icon block__icon--show">
<svg><use xlink:href="#iconAdd"></use></svg> <svg><use xlink:href="#iconAdd"></use></svg>
</span> </span>
<div class="fn__space"></div> <div class="fn__space"></div>
<input data-action="toggleCSS" class="b3-switch b3-switch--side fn__flex-center" type="checkbox"${window.siyuan.config.snippet.enabledCSS ? " checked" : ""}> <input data-action="toggleCSS" class="b3-switch fn__flex-center" type="checkbox"${window.siyuan.config.snippet.enabledCSS ? " checked" : ""}>
</div> </div>
${cssHTML} ${cssHTML}
</div> </div>
<div class="fn__none"> <div class="fn__none">
<div class="fn__flex"> <div class="fn__flex">
<div class="fn__flex-1"></div> <div class="b3-form__icon fn__flex-1">
<div class="b3-form__icon">
<svg class="b3-form__icon-icon"><use xlink:href="#iconSearch"></use></svg> <svg class="b3-form__icon-icon"><use xlink:href="#iconSearch"></use></svg>
<input data-type="js" data-action="search" type="text" placeholder="${window.siyuan.languages.search}" class="b3-text-field b3-form__icon-input"> <input data-type="js" data-action="search" type="text" placeholder="${window.siyuan.languages.search}" class="b3-text-field b3-form__icon-input fn__block">
</div> </div>
<div class="fn__space"></div> <div class="fn__space"></div>
<span aria-label="${window.siyuan.languages.addAttr} JS" id="addCodeSnippetJS" class="b3-tooltips b3-tooltips__sw block__icon block__icon--show"> <span aria-label="${window.siyuan.languages.addAttr} JS" id="addCodeSnippetJS" class="b3-tooltips b3-tooltips__sw block__icon block__icon--show">
<svg><use xlink:href="#iconAdd"></use></svg> <svg><use xlink:href="#iconAdd"></use></svg>
</span> </span>
<div class="fn__space"></div> <div class="fn__space"></div>
<input data-action="toggleJS" class="b3-switch b3-switch--side fn__flex-center" type="checkbox"${window.siyuan.config.snippet.enabledJS ? " checked" : ""}> <input data-action="toggleJS" class="b3-switch fn__flex-center" type="checkbox"${window.siyuan.config.snippet.enabledJS ? " checked" : ""}>
</div> </div>
${jsHTML} ${jsHTML}
</div> </div>
@ -120,7 +118,8 @@ export const openSnippets = () => {
type: target.id === "addCodeSnippetCSS" ? "css" : "js", type: target.id === "addCodeSnippetCSS" ? "css" : "js",
name: "", name: "",
content: "", content: "",
enabled: false enabled: false,
disabledInPublish: false,
})); }));
event.stopPropagation(); event.stopPropagation();
event.preventDefault(); event.preventDefault();
@ -195,13 +194,19 @@ const genSnippet = (options: ISnippet) => {
<div class="fn__hr--b"></div> <div class="fn__hr--b"></div>
<div class="fn__flex"> <div class="fn__flex">
<input type="text" class="fn__size200 b3-text-field" placeholder="${window.siyuan.languages.title}"> <input type="text" class="fn__size200 b3-text-field" placeholder="${window.siyuan.languages.title}">
<div class="fn__space"></div>
<label class="fn__flex${window.siyuan.config.publish.enable ? "" : " fn__none"}">
<input data-type="disabledInPublish" type="checkbox" class="b3-switch fn__flex-center" ${options.disabledInPublish ? "" : " checked"}>
<div class="fn__space"></div>
<span class="fn__flex-center">${window.siyuan.languages.publishService}</span>
</label>
<div class="fn__flex-1"></div> <div class="fn__flex-1"></div>
<div class="fn__space"></div> <div class="fn__space"></div>
<span aria-label="${window.siyuan.languages.remove}" data-action="remove" class="b3-tooltips b3-tooltips__sw block__icon block__icon--show"> <span aria-label="${window.siyuan.languages.remove}" data-action="remove" class="b3-tooltips b3-tooltips__sw block__icon block__icon--show">
<svg><use xlink:href="#iconTrashcan"></use></svg> <svg><use xlink:href="#iconTrashcan"></use></svg>
</span> </span>
<div class="fn__space"></div> <div class="fn__space"></div>
<input data-type="snippet" class="b3-switch b3-switch--side fn__flex-center" type="checkbox"${options.enabled ? " checked" : ""}> <input data-type="snippet" class="b3-switch fn__flex-center" type="checkbox"${options.enabled ? " checked" : ""}>
</div> </div>
<div class="fn__hr"></div> <div class="fn__hr"></div>
<textarea class="fn__block b3-text-field" placeholder="${window.siyuan.languages.codeSnippet}" style="resize: vertical;font-family:var(--b3-font-family-code)" spellcheck="false"></textarea> <textarea class="fn__block b3-text-field" placeholder="${window.siyuan.languages.codeSnippet}" style="resize: vertical;font-family:var(--b3-font-family-code)" spellcheck="false"></textarea>
@ -229,11 +234,12 @@ const setSnippet = (dialog: Dialog, oldSnippets: ISnippet[], removeIds: string[]
const snippets: ISnippet[] = []; const snippets: ISnippet[] = [];
dialog.element.querySelectorAll("[data-id]").forEach((item) => { dialog.element.querySelectorAll("[data-id]").forEach((item) => {
snippets.push({ snippets.push({
disabledInPublish: !(item.querySelector('.b3-switch[data-type="disabledInPublish"]') as HTMLInputElement).checked,
id: item.getAttribute("data-id"), id: item.getAttribute("data-id"),
name: item.querySelector("input").value, name: item.querySelector("input").value,
type: item.getAttribute("data-type"), type: item.getAttribute("data-type"),
content: item.querySelector("textarea").value, content: item.querySelector("textarea").value,
enabled: (item.querySelector(".b3-switch") as HTMLInputElement).checked enabled: (item.querySelector('.b3-switch[data-type="snippet"]') as HTMLInputElement).checked
}); });
}); });
if (objEquals(oldSnippets, snippets) && if (objEquals(oldSnippets, snippets) &&

View file

@ -240,7 +240,7 @@ export const openEmojiPanel = (id: string, type: "doc" | "notebook" | "av", posi
const dynamicCurrentObj: IObject = { const dynamicCurrentObj: IObject = {
color: "#d23f31", color: "#d23f31",
lang: "", lang: "",
date: "", date: dayjs().format("YYYY-MM-DD"),
weekdayType: "1", weekdayType: "1",
type: "1", type: "1",
content: "SiYuan", content: "SiYuan",
@ -268,7 +268,7 @@ export const openEmojiPanel = (id: string, type: "doc" | "notebook" | "av", posi
<div class="emojis__tabheader"> <div class="emojis__tabheader">
<div data-type="tab-emoji" class="ariaLabel block__icon block__icon--show" aria-label="${window.siyuan.languages.emoji}"><svg><use xlink:href="#iconEmoji"></use></svg></div> <div data-type="tab-emoji" class="ariaLabel block__icon block__icon--show" aria-label="${window.siyuan.languages.emoji}"><svg><use xlink:href="#iconEmoji"></use></svg></div>
<div class="fn__space"></div> <div class="fn__space"></div>
<div data-type="tab-dynamic" class="ariaLabel block__icon block__icon--show" aria-label="${window.siyuan.languages.dynamicEmoji}"><svg><use xlink:href="#iconCalendar"></use></svg></div> <div data-type="tab-dynamic" class="ariaLabel block__icon block__icon--show" aria-label="${window.siyuan.languages.dynamicIcon}"><svg><use xlink:href="#iconCalendar"></use></svg></div>
<div class="fn__flex-1"></div> <div class="fn__flex-1"></div>
<span class="block__icon block__icon--show fn__flex-center ariaLabel" data-action="remove" aria-label="${window.siyuan.languages.remove}"><svg><use xlink:href="#iconTrashcan"></use></svg></span> <span class="block__icon block__icon--show fn__flex-center ariaLabel" data-action="remove" aria-label="${window.siyuan.languages.remove}"><svg><use xlink:href="#iconTrashcan"></use></svg></span>
</div> </div>
@ -334,6 +334,8 @@ export const openEmojiPanel = (id: string, type: "doc" | "notebook" | "av", posi
<span class="fn__flex-center ft__on-surface" style="width: 89px">${window.siyuan.languages.date}</span> <span class="fn__flex-center ft__on-surface" style="width: 89px">${window.siyuan.languages.date}</span>
<span class="fn__space--small"></span> <span class="fn__space--small"></span>
<input type="date" max="9999-12-31" class="b3-text-field fn__flex-1" value="${dynamicCurrentObj.date}"/> <input type="date" max="9999-12-31" class="b3-text-field fn__flex-1" value="${dynamicCurrentObj.date}"/>
<span class="fn__space--small"></span>
<span data-action="clearDate" class="ariaLabel block__icon block__icon--show" aria-label="${window.siyuan.languages.dynamicIconDateEmptyInfo}"><svg><use xlink:href="#iconTrashcan"></use></svg></span>
<span class="fn__space"></span> <span class="fn__space"></span>
</div> </div>
<div class="fn__hr"></div> <div class="fn__hr"></div>
@ -628,6 +630,10 @@ export const openEmojiPanel = (id: string, type: "doc" | "notebook" | "av", posi
dynamicTextElements[0].value = target.getAttribute("style").replace("background-color:", ""); dynamicTextElements[0].value = target.getAttribute("style").replace("background-color:", "");
dynamicTextElements[0].dispatchEvent(new CustomEvent("input")); dynamicTextElements[0].dispatchEvent(new CustomEvent("input"));
break; break;
} else if ("clearDate" === target.dataset.action) {
dynamicDateElement.value = "";
dynamicDateElement.dispatchEvent(new CustomEvent("change"));
break;
} }
target = target.parentElement; target = target.parentElement;
} }

View file

@ -866,7 +866,7 @@ data-type="navigation-root" data-path="/">
} }
window.siyuan.storage[Constants.LOCAL_FILESPATHS].forEach((item: IFilesPath) => { window.siyuan.storage[Constants.LOCAL_FILESPATHS].forEach((item: IFilesPath) => {
item.openPaths.forEach((openPath) => { item.openPaths.forEach((openPath) => {
this.selectItem(item.notebookId, openPath, undefined, false); this.selectItem(item.notebookId, openPath, undefined, false, false);
}); });
}); });
if (!init) { if (!init) {
@ -1081,7 +1081,11 @@ data-type="navigation-root" data-path="/">
}, 2); }, 2);
} }
private onLsSelect(data: { files: IFile[], box: string, path: string }, filePath: string, setStorage: boolean) { private async onLsSelect(data: {
files: IFile[],
box: string,
path: string
}, filePath: string, setStorage: boolean, isSetCurrent: boolean) {
let fileHTML = ""; let fileHTML = "";
data.files.forEach((item: IFile) => { data.files.forEach((item: IFile) => {
fileHTML += this.genFileHTML(item); fileHTML += this.genFileHTML(item);
@ -1102,28 +1106,30 @@ data-type="navigation-root" data-path="/">
emojiElement.textContent = unicode2Emoji(window.siyuan.storage[Constants.LOCAL_IMAGES].folder); emojiElement.textContent = unicode2Emoji(window.siyuan.storage[Constants.LOCAL_IMAGES].folder);
} }
liElement.insertAdjacentHTML("afterend", `<ul>${fileHTML}</ul>`); liElement.insertAdjacentHTML("afterend", `<ul>${fileHTML}</ul>`);
data.files.forEach((item: IFile) => { let newLiElement;
for (let i = 0; i < data.files.length; i++) {
const item = data.files[i];
if (filePath === item.path) { if (filePath === item.path) {
this.selectItem(data.box, filePath, undefined, setStorage); newLiElement = await this.selectItem(data.box, filePath, undefined, setStorage, isSetCurrent);
} else if (filePath.startsWith(item.path.replace(".sy", ""))) { } else if (filePath.startsWith(item.path.replace(".sy", ""))) {
fetchPost("/api/filetree/listDocsByPath", { const response = await fetchSyncPost("/api/filetree/listDocsByPath", {
notebook: data.box, notebook: data.box,
path: item.path path: item.path
}, response => {
this.selectItem(response.data.box, filePath, response.data, setStorage);
}); });
newLiElement = await this.selectItem(response.data.box, filePath, response.data, setStorage, isSetCurrent);
} }
});
if (setStorage) {
this.setCurrent(this.element.querySelector(`ul[data-url="${data.box}"] li[data-path="${filePath}"]`));
} }
if (isSetCurrent) {
this.setCurrent(newLiElement);
}
return newLiElement;
} }
private setCurrent(target: HTMLElement, isScroll = true) { public setCurrent(target: HTMLElement, isScroll = true) {
if (!target) { if (!target) {
return; return;
} }
this.element.querySelectorAll("li").forEach((liItem) => { this.element.querySelectorAll("li.b3-list-item--focus").forEach((liItem) => {
liItem.classList.remove("b3-list-item--focus"); liItem.classList.remove("b3-list-item--focus");
}); });
target.classList.add("b3-list-item--focus"); target.classList.add("b3-list-item--focus");
@ -1147,7 +1153,13 @@ data-type="navigation-root" data-path="/">
path: liElement.getAttribute("data-path"), path: liElement.getAttribute("data-path"),
}, response => { }, response => {
if (response.data.path === "/" && response.data.files.length === 0) { if (response.data.path === "/" && response.data.files.length === 0) {
showMessage(window.siyuan.languages.emptyContent); newFile({
app: this.app,
notebookId,
currentPath: "/",
useSavePath: false,
listDocTree: true,
});
return; return;
} }
this.onLsHTML(response.data); this.onLsHTML(response.data);
@ -1155,11 +1167,11 @@ data-type="navigation-root" data-path="/">
}); });
} }
public selectItem(notebookId: string, filePath: string, data?: { public async selectItem(notebookId: string, filePath: string, data?: {
files: IFile[], files: IFile[],
box: string, box: string,
path: string path: string
}, setStorage = true) { }, setStorage = true, isSetCurrent = true) {
const treeElement = this.element.querySelector(`[data-url="${notebookId}"]`); const treeElement = this.element.querySelector(`[data-url="${notebookId}"]`);
if (!treeElement) { if (!treeElement) {
// 有文件树和编辑器的布局初始化时,文件树还未挂载 // 有文件树和编辑器的布局初始化时,文件树还未挂载
@ -1181,24 +1193,24 @@ data-type="navigation-root" data-path="/">
if (liElement.getAttribute("data-path") === filePath) { if (liElement.getAttribute("data-path") === filePath) {
if (setStorage) { if (setStorage) {
this.setCurrent(liElement);
this.getOpenPaths(); this.getOpenPaths();
} else {
this.element.querySelector(".b3-list-item--focus")?.classList.remove("b3-list-item--focus");
} }
return; if (isSetCurrent) {
this.setCurrent(liElement);
}
return liElement;
} }
if (data && data.path === currentPath) { if (data && data.path === currentPath) {
this.onLsSelect(data, filePath, setStorage); liElement = await this.onLsSelect(data, filePath, setStorage, isSetCurrent);
} else { } else {
fetchPost("/api/filetree/listDocsByPath", { const response = await fetchSyncPost("/api/filetree/listDocsByPath", {
notebook: notebookId, notebook: notebookId,
path: currentPath path: currentPath
}, response => {
this.onLsSelect(response.data, filePath, setStorage);
}); });
liElement = await this.onLsSelect(response.data, filePath, setStorage, isSetCurrent);
} }
return liElement;
} }
private getOpenPaths() { private getOpenPaths() {

View file

@ -4,8 +4,7 @@ import {Model} from "../../layout/Model";
import {Constants} from "../../constants"; import {Constants} from "../../constants";
import {getDisplayName, pathPosix, setNoteBook} from "../../util/pathName"; import {getDisplayName, pathPosix, setNoteBook} from "../../util/pathName";
import {initFileMenu, initNavigationMenu, sortMenu} from "../../menus/navigation"; import {initFileMenu, initNavigationMenu, sortMenu} from "../../menus/navigation";
import {showMessage} from "../../dialog/message"; import {fetchPost, fetchSyncPost} from "../../util/fetch";
import {fetchPost} from "../../util/fetch";
import {genUUID} from "../../util/genID"; import {genUUID} from "../../util/genID";
import {openMobileFileById} from "../editor"; import {openMobileFileById} from "../editor";
import {unicode2Emoji} from "../../emoji"; import {unicode2Emoji} from "../../emoji";
@ -361,7 +360,7 @@ export class MobileFiles extends Model {
} }
window.siyuan.storage[Constants.LOCAL_FILESPATHS].forEach((item: IFilesPath) => { window.siyuan.storage[Constants.LOCAL_FILESPATHS].forEach((item: IFilesPath) => {
item.openPaths.forEach((openPath) => { item.openPaths.forEach((openPath) => {
this.selectItem(item.notebookId, openPath, undefined, false); this.selectItem(item.notebookId, openPath, undefined, false, false);
}); });
}); });
if (!init) { if (!init) {
@ -577,20 +576,14 @@ export class MobileFiles extends Model {
}, 2); }, 2);
} }
private onLsSelect(data: { files: IFile[], box: string, path: string }, filePath: string, setStorage: boolean) { private async onLsSelect(data: {
files: IFile[],
box: string,
path: string
}, filePath: string, setStorage: boolean, isSetCurrent: boolean) {
let fileHTML = ""; let fileHTML = "";
data.files.forEach((item: IFile) => { data.files.forEach((item: IFile) => {
fileHTML += this.genFileHTML(item); fileHTML += this.genFileHTML(item);
if (filePath === item.path) {
this.selectItem(data.box, filePath, undefined, setStorage);
} else if (filePath.startsWith(item.path.replace(".sy", ""))) {
fetchPost("/api/filetree/listDocsByPath", {
notebook: data.box,
path: item.path
}, response => {
this.selectItem(response.data.box, filePath, response.data, setStorage);
});
}
}); });
if (fileHTML === "") { if (fileHTML === "") {
return; return;
@ -600,26 +593,45 @@ export class MobileFiles extends Model {
// 文件展开时,刷新 // 文件展开时,刷新
liElement.nextElementSibling.remove(); liElement.nextElementSibling.remove();
} }
liElement.querySelector(".b3-list-item__arrow").classList.add("b3-list-item__arrow--open"); const arrowElement = liElement.querySelector(".b3-list-item__arrow");
liElement.insertAdjacentHTML("afterend", `<ul>${fileHTML}</ul>`); arrowElement.classList.add("b3-list-item__arrow--open");
if (setStorage) { arrowElement.parentElement.classList.remove("fn__hidden");
this.setCurrent(this.element.querySelector(`ul[data-url="${data.box}"] li[data-path="${filePath}"]`)); const emojiElement = liElement.querySelector(".b3-list-item__icon");
if (emojiElement.textContent === unicode2Emoji(window.siyuan.storage[Constants.LOCAL_IMAGES].file)) {
emojiElement.textContent = unicode2Emoji(window.siyuan.storage[Constants.LOCAL_IMAGES].folder);
} }
liElement.insertAdjacentHTML("afterend", `<ul>${fileHTML}</ul>`);
let newLiElement;
for (let i = 0; i < data.files.length; i++) {
const item = data.files[i];
if (filePath === item.path) {
newLiElement = await this.selectItem(data.box, filePath, undefined, setStorage, isSetCurrent);
} else if (filePath.startsWith(item.path.replace(".sy", ""))) {
const response = await fetchSyncPost("/api/filetree/listDocsByPath", {
notebook: data.box,
path: item.path
});
newLiElement = await this.selectItem(response.data.box, filePath, response.data, setStorage, isSetCurrent);
}
}
if (isSetCurrent) {
this.setCurrent(newLiElement);
}
return newLiElement;
} }
private setCurrent(target: HTMLElement) { public setCurrent(target: HTMLElement, isScroll = true) {
if (!target) { if (!target) {
return; return;
} }
this.element.querySelectorAll("li").forEach((liItem) => { this.element.querySelectorAll("li.b3-list-item--focus").forEach((liItem) => {
liItem.classList.remove("b3-list-item--focus"); liItem.classList.remove("b3-list-item--focus");
}); });
target.classList.add("b3-list-item--focus"); target.classList.add("b3-list-item--focus");
const titleHeight = this.actionsElement.clientHeight;
if (target.offsetTop - titleHeight < this.element.scrollTop) { if (isScroll) {
this.element.scrollTop = target.offsetTop - titleHeight; const elementRect = this.element.getBoundingClientRect();
} else if (target.offsetTop - this.element.clientHeight - titleHeight + target.clientHeight > this.element.scrollTop) { this.element.scrollTop = this.element.scrollTop + (target.getBoundingClientRect().top - (elementRect.top + elementRect.height / 2));
this.element.scrollTop = target.offsetTop - this.element.clientHeight - titleHeight + target.clientHeight;
} }
} }
@ -636,7 +648,13 @@ export class MobileFiles extends Model {
path: liElement.getAttribute("data-path"), path: liElement.getAttribute("data-path"),
}, response => { }, response => {
if (response.data.path === "/" && response.data.files.length === 0) { if (response.data.path === "/" && response.data.files.length === 0) {
showMessage(window.siyuan.languages.emptyContent); newFile({
app: this.app,
notebookId,
currentPath: "/",
useSavePath: false,
listDocTree: true,
});
return; return;
} }
this.onLsHTML(response.data); this.onLsHTML(response.data);
@ -644,11 +662,11 @@ export class MobileFiles extends Model {
}); });
} }
public selectItem(notebookId: string, filePath: string, data?: { public async selectItem(notebookId: string, filePath: string, data?: {
files: IFile[], files: IFile[],
box: string, box: string,
path: string path: string
}, setStorage = true) { }, setStorage = true, isSetCurrent = true) {
const treeElement = this.element.querySelector(`[data-url="${notebookId}"]`); const treeElement = this.element.querySelector(`[data-url="${notebookId}"]`);
if (!treeElement) { if (!treeElement) {
// 有文件树和编辑器的布局初始化时,文件树还未挂载 // 有文件树和编辑器的布局初始化时,文件树还未挂载
@ -670,24 +688,24 @@ export class MobileFiles extends Model {
if (liElement.getAttribute("data-path") === filePath) { if (liElement.getAttribute("data-path") === filePath) {
if (setStorage) { if (setStorage) {
this.setCurrent(liElement);
this.getOpenPaths(); this.getOpenPaths();
} else {
this.element.querySelector(".b3-list-item--focus")?.classList.remove("b3-list-item--focus");
} }
return; if (isSetCurrent) {
this.setCurrent(liElement);
}
return liElement;
} }
if (data && data.path === currentPath) { if (data && data.path === currentPath) {
this.onLsSelect(data, filePath, setStorage); liElement = await this.onLsSelect(data, filePath, setStorage, isSetCurrent);
} else { } else {
fetchPost("/api/filetree/listDocsByPath", { const response = await fetchSyncPost("/api/filetree/listDocsByPath", {
notebook: notebookId, notebook: notebookId,
path: currentPath path: currentPath
}, response => {
this.onLsSelect(response.data, filePath, setStorage);
}); });
liElement = await this.onLsSelect(response.data, filePath, setStorage, isSetCurrent);
} }
return liElement;
} }
private getOpenPaths() { private getOpenPaths() {

View file

@ -59,6 +59,7 @@ export const openMobileFileById = (app: App, id: string, action: TProtyleAction[
render: { render: {
scroll: true, scroll: true,
title: true, title: true,
titleShowTop: true,
background: true, background: true,
gutter: true, gutter: true,
}, },

View file

@ -186,7 +186,7 @@ ${unicode2Emoji(getNotebookIcon(item.box) || window.siyuan.storage[Constants.LOC
<svg class="b3-list-item__graphic"><use xlink:href="#${getIconByType(childItem.type)}"></use></svg> <svg class="b3-list-item__graphic"><use xlink:href="#${getIconByType(childItem.type)}"></use></svg>
${unicode2Emoji(childItem.ial.icon, "b3-list-item__graphic", true)} ${unicode2Emoji(childItem.ial.icon, "b3-list-item__graphic", true)}
<span class="b3-list-item__text">${childItem.content}</span> <span class="b3-list-item__text">${childItem.content}</span>
${childItem.tag ? `<span class="b3-list-item__meta b3-list-item__meta--ellipsis">${childItem.tag.split("# #").map(tag => `${tag.replace("#", "")}`).join(" ").replace("#", "")}</span>` : ""} ${childItem.tag ? `<span class="b3-list-item__meta b3-list-item__meta--ellipsis">${childItem.tag.replace(/#/g, "")}</span>` : ""}
</div>`; </div>`;
}); });
resultHTML += "</div>"; resultHTML += "</div>";
@ -206,7 +206,7 @@ ${childItem.tag ? `<span class="b3-list-item__meta b3-list-item__meta--ellipsis"
<span class="b3-list-item__text">${item.content}</span> <span class="b3-list-item__text">${item.content}</span>
</div> </div>
<div class="fn__flex"> <div class="fn__flex">
${item.tag ? `<span class="b3-list-item__meta b3-list-item__meta--ellipsis">${item.tag.split("# #").map(tag => `${tag.replace("#", "")}`).join(" ").replace("#", "")}</span><span class="fn__space"></span>` : ""} ${item.tag ? `<span class="b3-list-item__meta b3-list-item__meta--ellipsis">${item.tag.replace(/#/g, "")}</span><span class="fn__space"></span>` : ""}
<span class="b3-list-item__text b3-list-item__meta">${escapeGreat(title)}</span> <span class="b3-list-item__text b3-list-item__meta">${escapeGreat(title)}</span>
</div> </div>
</div>`; </div>`;

View file

@ -30,6 +30,7 @@ import {globalCommand} from "../boot/globalEvent/command/global";
import {exportLayout} from "../layout/util"; import {exportLayout} from "../layout/util";
import {saveScroll} from "../protyle/scroll/saveScroll"; import {saveScroll} from "../protyle/scroll/saveScroll";
import {hasClosestByClassName} from "../protyle/util/hasClosest"; import {hasClosestByClassName} from "../protyle/util/hasClosest";
import {Files} from "../layout/dock/Files";
let openTab; let openTab;
let openWindow; let openWindow;
@ -235,19 +236,72 @@ const getActiveEditor = (wndActive = true) => {
if (!editor && !wndActive) { if (!editor && !wndActive) {
let activeTime = 0; let activeTime = 0;
allEditor.forEach(item => { allEditor.forEach(item => {
const headerElement = item.protyle?.model.parent.headElement; let headerElement = item.protyle.model?.parent.headElement;
if (headerElement && headerElement.classList.contains("item--focus") && parseInt(headerElement.dataset.activetime) > activeTime) { if (!headerElement && item.protyle.element.getBoundingClientRect().height > 0) {
activeTime = parseInt(headerElement.dataset.activetime); const tabBodyElement = item.protyle.element.closest(".fn__flex-1[data-id]");
if (tabBodyElement) {
headerElement = document.querySelector(`.layout-tab-bar .item[data-id="${tabBodyElement.getAttribute("data-id")}"]`);
}
}
if (headerElement) {
if (headerElement.classList.contains("item--focus") && parseInt(headerElement.dataset.activetime) > activeTime) {
activeTime = parseInt(headerElement.dataset.activetime);
editor = item;
}
} else if (item.protyle.element.getBoundingClientRect().height > 0) {
editor = item; editor = item;
} }
}); });
} }
/// #else /// #else
editor = window.siyuan.mobile.popEditor || window.siyuan.mobile.editor; editor = window.siyuan.mobile.popEditor || window.siyuan.mobile.editor;
if (editor?.protyle.element.classList.contains("fn__none")) {
return undefined;
}
/// #endif /// #endif
return editor; return editor;
}; };
export const expandDocTree = async (options: {
id: string,
isSetCurrent?: boolean
}) => {
let isNotebook = false;
window.siyuan.notebooks.find(item => {
if (options.id === item.id) {
isNotebook = true;
return true;
}
});
let liElement: HTMLElement;
let notebookId = options.id;
const file = getModelByDockType("file") as Files;
if (typeof options.isSetCurrent === "undefined") {
options.isSetCurrent = true;
}
if (isNotebook) {
liElement = file.element.querySelector(`.b3-list[data-url="${options.id}"]`)?.firstElementChild as HTMLElement;
} else {
const response = await fetchSyncPost("api/block/getBlockInfo", {id: options.id});
if (response.code === -1) {
return;
}
notebookId = response.data.box;
liElement = await file.selectItem(response.data.box, response.data.path, undefined, undefined, options.isSetCurrent);
}
if (!liElement) {
return;
}
if (options.isSetCurrent || typeof options.isSetCurrent === "undefined") {
file.setCurrent(liElement);
}
const toggleElement = liElement.querySelector(".b3-list-item__arrow");
if (toggleElement.classList.contains("b3-list-item__arrow--open")) {
return;
}
file.getLeaf(liElement, notebookId);
};
export const API = { export const API = {
adaptHotkey: updateHotkeyTip, adaptHotkey: updateHotkeyTip,
confirm: confirmDialog, confirm: confirmDialog,
@ -281,4 +335,5 @@ export const API = {
openAttributePanel, openAttributePanel,
saveLayout, saveLayout,
globalCommand, globalCommand,
expandDocTree
}; };

View file

@ -18,7 +18,7 @@ export const openTopBarMenu = (app: App, target?: Element) => {
openSetting(app).element.querySelector('.b3-tab-bar [data-name="bazaar"]').dispatchEvent(new CustomEvent("click")); openSetting(app).element.querySelector('.b3-tab-bar [data-name="bazaar"]').dispatchEvent(new CustomEvent("click"));
} }
}); });
menu.addSeparator({id: "separator_1"}, isHuawei() || window.siyuan.config.readonly); menu.addSeparator({id: "separator_1", ignore: isHuawei() || window.siyuan.config.readonly});
/// #endif /// #endif
let hasPlugin = false; let hasPlugin = false;
app.plugins.forEach((plugin) => { app.plugins.forEach((plugin) => {

View file

@ -111,7 +111,6 @@ const renderPDF = async (id: string) => {
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="mobile-web-app-capable" content="yes"/> <meta name="mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-status-bar-style" content="black"> <meta name="apple-mobile-web-app-status-bar-style" content="black">
<link rel="stylesheet" type="text/css" id="baseStyle" href="${servePath}/stage/build/export/base.css?v=${Constants.SIYUAN_VERSION}"/> <link rel="stylesheet" type="text/css" id="baseStyle" href="${servePath}/stage/build/export/base.css?v=${Constants.SIYUAN_VERSION}"/>
@ -663,7 +662,6 @@ const onExport = async (data: IWebSocketData, filePath: string, exportOption: IE
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="mobile-web-app-capable" content="yes"/> <meta name="mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-status-bar-style" content="black"> <meta name="apple-mobile-web-app-status-bar-style" content="black">
<link rel="stylesheet" type="text/css" id="baseStyle" href="stage/build/export/base.css?v=${Constants.SIYUAN_VERSION}"/> <link rel="stylesheet" type="text/css" id="baseStyle" href="stage/build/export/base.css?v=${Constants.SIYUAN_VERSION}"/>

View file

@ -1682,7 +1682,7 @@ export class Gutter {
icon: "iconCopy", icon: "iconCopy",
label: `${window.siyuan.languages.copy} ${window.siyuan.languages.headings1}`, label: `${window.siyuan.languages.copy} ${window.siyuan.languages.headings1}`,
click() { click() {
fetchPost("/api/block/getHeadingChildrenDOM", {id}, (response) => { fetchPost("/api/block/getHeadingChildrenDOM", {id, removeFoldAttr: true}, (response) => {
if (isInAndroid()) { if (isInAndroid()) {
window.JSAndroid.writeHTMLClipboard(protyle.lute.BlockDOM2StdMd(response.data).trimEnd(), response.data + Constants.ZWSP); window.JSAndroid.writeHTMLClipboard(protyle.lute.BlockDOM2StdMd(response.data).trimEnd(), response.data + Constants.ZWSP);
} else if (isInHarmony()) { } else if (isInHarmony()) {
@ -1698,7 +1698,7 @@ export class Gutter {
icon: "iconCut", icon: "iconCut",
label: `${window.siyuan.languages.cut} ${window.siyuan.languages.headings1}`, label: `${window.siyuan.languages.cut} ${window.siyuan.languages.headings1}`,
click() { click() {
fetchPost("/api/block/getHeadingChildrenDOM", {id}, (response) => { fetchPost("/api/block/getHeadingChildrenDOM", {id, removeFoldAttr: true}, (response) => {
if (isInAndroid()) { if (isInAndroid()) {
window.JSAndroid.writeHTMLClipboard(protyle.lute.BlockDOM2StdMd(response.data).trimEnd(), response.data + Constants.ZWSP); window.JSAndroid.writeHTMLClipboard(protyle.lute.BlockDOM2StdMd(response.data).trimEnd(), response.data + Constants.ZWSP);
} else if (isInHarmony()) { } else if (isInHarmony()) {

View file

@ -14,7 +14,9 @@ import {Constants} from "../../constants";
import {matchHotKey} from "../util/hotKey"; import {matchHotKey} from "../util/hotKey";
import {isMac, readText} from "../util/compatibility"; import {isMac, readText} from "../util/compatibility";
import * as dayjs from "dayjs"; import * as dayjs from "dayjs";
/// #if !MOBILE
import {openFileById} from "../../editor/util"; import {openFileById} from "../../editor/util";
/// #endif
import {setTitle} from "../../dialog/processSystem"; import {setTitle} from "../../dialog/processSystem";
import {getContenteditableElement, getNoContainerElement} from "../wysiwyg/getBlock"; import {getContenteditableElement, getNoContainerElement} from "../wysiwyg/getBlock";
import {commonHotkey} from "../wysiwyg/commonHotkey"; import {commonHotkey} from "../wysiwyg/commonHotkey";
@ -38,232 +40,68 @@ export class Title {
if (window.siyuan.config.editor.displayBookmarkIcon) { if (window.siyuan.config.editor.displayBookmarkIcon) {
this.element.classList.add("protyle-wysiwyg--attr"); this.element.classList.add("protyle-wysiwyg--attr");
} }
/// #if !MOBILE if (protyle.options.render?.titleShowTop) {
// 标题内需要一个空格,避免首次加载出现`请输入文档名`干扰 this.element.innerHTML = '<div class="protyle-attr"></div>';
this.element.innerHTML = `<span aria-label="${isMac() ? window.siyuan.languages.gutterTip2 : window.siyuan.languages.gutterTip2.replace("⇧", "Shift+")}" data-position="west" class="protyle-title__icon ariaLabel"><svg><use xlink:href="#iconFile"></use></svg></span> } else {
// 标题内需要一个空格,避免首次加载出现`请输入文档名`干扰
this.element.innerHTML = `<span aria-label="${isMac() ? window.siyuan.languages.gutterTip2 : window.siyuan.languages.gutterTip2.replace("⇧", "Shift+")}" data-position="west" class="protyle-title__icon ariaLabel"><svg><use xlink:href="#iconFile"></use></svg></span>
<div contenteditable="true" spellcheck="${window.siyuan.config.editor.spellcheck}" class="protyle-title__input" data-tip="${window.siyuan.languages._kernel[16]}"> </div><div class="protyle-attr"></div>`; <div contenteditable="true" spellcheck="${window.siyuan.config.editor.spellcheck}" class="protyle-title__input" data-tip="${window.siyuan.languages._kernel[16]}"> </div><div class="protyle-attr"></div>`;
this.editElement = this.element.querySelector(".protyle-title__input"); this.editElement = this.element.querySelector(".protyle-title__input");
this.editElement.addEventListener("paste", (event: ClipboardEvent) => { this.editElement.addEventListener("paste", (event: ClipboardEvent) => {
event.stopPropagation();
event.preventDefault();
// 不能使用 range.insertNode否则无法撤销
let text = event.clipboardData.getData("text/siyuan");
if (text) {
try {
JSON.parse(text);
text = event.clipboardData.getData("text/plain");
} catch (e) {
// 不为数据库,保持 text 不变
}
text = protyle.lute.BlockDOM2Content(text);
} else {
text = event.clipboardData.getData("text/plain");
}
// 阻止右键复制菜单报错
setTimeout(function () {
document.execCommand("insertText", false, replaceFileName(text));
}, 0);
this.rename(protyle);
});
this.editElement.addEventListener("click", () => {
protyle.toolbar?.element.classList.add("fn__none");
});
this.editElement.addEventListener("input", (event: InputEvent) => {
if (event.isComposing) {
return;
}
if (this.editElement.textContent === "") {
this.editElement.querySelectorAll("br").forEach(item => {
item.remove();
});
}
this.rename(protyle);
});
this.editElement.addEventListener("compositionend", () => {
this.rename(protyle);
});
this.editElement.addEventListener("drop", (event: DragEvent) => {
// https://ld246.com/article/1661911210429
event.stopPropagation();
event.preventDefault();
});
this.editElement.addEventListener("keydown", (event: KeyboardEvent) => {
if (event.isComposing) {
return;
}
if (commonHotkey(protyle, event)) {
return true;
}
if (matchHotKey("⇧⌘V", event)) {
navigator.clipboard.readText().then(textPlain => {
// 对 HTML 标签进行内部转义,避免被 Lute 解析以后变为小写 https://github.com/siyuan-note/siyuan/issues/10620
textPlain = textPlain.replace(/</g, ";;;lt;;;").replace(/>/g, ";;;gt;;;");
enableLuteMarkdownSyntax(protyle);
let content = protyle.lute.BlockDOM2EscapeMarkerContent(protyle.lute.Md2BlockDOM(textPlain));
restoreLuteMarkdownSyntax(protyle);
// 移除 ;;;lt;;; 和 ;;;gt;;; 转义及其包裹的内容
content = content.replace(/;;;lt;;;[^;]+;;;gt;;;/g, "");
document.execCommand("insertText", false, replaceFileName(content));
this.rename(protyle);
});
event.preventDefault();
event.stopPropagation(); event.stopPropagation();
} event.preventDefault();
if (matchHotKey(window.siyuan.config.keymap.general.enterBack.custom, event)) { // 不能使用 range.insertNode否则无法撤销
const ids = protyle.path.split("/"); let text = event.clipboardData.getData("text/siyuan");
if (ids.length > 2) { if (text) {
openFileById({ try {
app: protyle.app, JSON.parse(text);
id: ids[ids.length - 2], text = event.clipboardData.getData("text/plain");
action: [Constants.CB_GET_FOCUS, Constants.CB_GET_SCROLL] } catch (e) {
// 不为数据库,保持 text 不变
}
text = protyle.lute.BlockDOM2Content(text);
} else {
text = event.clipboardData.getData("text/plain");
}
// 阻止右键复制菜单报错
setTimeout(function () {
document.execCommand("insertText", false, replaceFileName(text));
}, 0);
this.rename(protyle);
});
this.editElement.addEventListener("click", () => {
protyle.toolbar?.element.classList.add("fn__none");
});
this.editElement.addEventListener("input", (event: InputEvent) => {
if (event.isComposing) {
return;
}
if (this.editElement.textContent === "") {
this.editElement.querySelectorAll("br").forEach(item => {
item.remove();
}); });
} }
event.preventDefault(); this.rename(protyle);
});
this.editElement.addEventListener("compositionend", () => {
this.rename(protyle);
});
this.editElement.addEventListener("drop", (event: DragEvent) => {
// https://ld246.com/article/1661911210429
event.stopPropagation(); event.stopPropagation();
return; event.preventDefault();
} });
if (electronUndo(event)) { this.editElement.addEventListener("keydown", (event: KeyboardEvent) => {
return; if (event.isComposing) {
} return;
if (event.key === "ArrowDown") {
const rects = getSelection().getRangeAt(0).getClientRects();
// https://github.com/siyuan-note/siyuan/issues/11729
if (rects.length === 0 // 标题为空时时
|| this.editElement.getBoundingClientRect().bottom - rects[rects.length - 1].bottom < 25) {
const noContainerElement = getNoContainerElement(protyle.wysiwyg.element.firstElementChild);
// https://github.com/siyuan-note/siyuan/issues/4923
if (noContainerElement) {
focusBlock(noContainerElement, protyle.wysiwyg.element);
}
event.preventDefault();
event.stopPropagation();
} }
} else if (event.key === "Enter") {
const editElement = getContenteditableElement(protyle.wysiwyg.element.firstElementChild); if (commonHotkey(protyle, event)) {
if (editElement && editElement.textContent === "" && editElement.getAttribute("placeholder")) { return true;
// 配合提示文本使用,避免提示文本挤压到第二个块中
focusBlock(protyle.wysiwyg.element.firstElementChild, protyle.wysiwyg.element);
} else {
const newId = Lute.NewNodeID();
const newElement = genEmptyElement(false, true, newId);
protyle.wysiwyg.element.insertAdjacentElement("afterbegin", newElement);
focusByWbr(newElement, protyle.toolbar.range || getEditorRange(newElement));
transaction(protyle, [{
action: "insert",
data: newElement.outerHTML,
id: newId,
parentID: protyle.block.parentID
}], [{
action: "delete",
id: newId,
}]);
} }
event.preventDefault(); if (matchHotKey("⇧⌘V", event)) {
event.stopPropagation();
} else if (matchHotKey(window.siyuan.config.keymap.editor.general.attr.custom, event)) {
fetchPost("/api/block/getDocInfo", {
id: protyle.block.rootID
}, (response) => {
openFileAttr(response.data.ial, "bookmark", protyle);
});
event.preventDefault();
event.stopPropagation();
} else if (matchHotKey("⌘A", event)) {
getEditorRange(this.editElement).selectNodeContents(this.editElement);
event.preventDefault();
event.stopPropagation();
}
});
const iconElement = this.element.querySelector(".protyle-title__icon");
iconElement.addEventListener("click", () => {
if (window.siyuan.shiftIsPressed) {
fetchPost("/api/block/getDocInfo", {
id: protyle.block.rootID
}, (response) => {
openFileAttr(response.data.ial, "bookmark", protyle);
});
} else {
const iconRect = iconElement.getBoundingClientRect();
openTitleMenu(protyle, {x: iconRect.left, y: iconRect.bottom});
}
});
this.element.addEventListener("contextmenu", (event) => {
if (event.shiftKey) {
return;
}
if (getSelection().rangeCount === 0) {
openTitleMenu(protyle, {x: event.clientX, y: event.clientY});
return;
}
protyle.toolbar?.element.classList.add("fn__none");
window.siyuan.menus.menu.remove();
const range = getEditorRange(this.editElement);
if (range.toString() !== "") {
window.siyuan.menus.menu.append(new MenuItem({
id: "copy",
icon: "iconCopy",
accelerator: "⌘C",
label: window.siyuan.languages.copy,
click: () => {
focusByRange(getEditorRange(this.editElement));
document.execCommand("copy");
}
}).element);
window.siyuan.menus.menu.append(new MenuItem({
id: "cut",
icon: "iconCut",
accelerator: "⌘X",
label: window.siyuan.languages.cut,
click: () => {
focusByRange(getEditorRange(this.editElement));
document.execCommand("cut");
setTimeout(() => {
this.rename(protyle);
}, Constants.TIMEOUT_INPUT);
}
}).element);
window.siyuan.menus.menu.append(new MenuItem({
id: "delete",
icon: "iconTrashcan",
accelerator: "⌫",
label: window.siyuan.languages.delete,
click: () => {
const range = getEditorRange(this.editElement);
range.extractContents();
focusByRange(range);
setTimeout(() => {
this.rename(protyle);
}, Constants.TIMEOUT_INPUT);
}
}).element);
}
window.siyuan.menus.menu.append(new MenuItem({
id: "paste",
label: window.siyuan.languages.paste,
icon: "iconPaste",
accelerator: "⌘V",
click: async () => {
focusByRange(getEditorRange(this.editElement));
if (document.queryCommandSupported("paste")) {
document.execCommand("paste");
} else {
try {
const text = await readText();
document.execCommand("insertText", false, replaceFileName(text));
this.rename(protyle);
} catch (e) {
console.log(e);
}
}
}
}).element);
window.siyuan.menus.menu.append(new MenuItem({
id: "pasteAsPlainText",
label: window.siyuan.languages.pasteAsPlainText,
accelerator: "⇧⌘V",
click: async () => {
navigator.clipboard.readText().then(textPlain => { navigator.clipboard.readText().then(textPlain => {
// 对 HTML 标签进行内部转义,避免被 Lute 解析以后变为小写 https://github.com/siyuan-note/siyuan/issues/10620
textPlain = textPlain.replace(/</g, ";;;lt;;;").replace(/>/g, ";;;gt;;;"); textPlain = textPlain.replace(/</g, ";;;lt;;;").replace(/>/g, ";;;gt;;;");
enableLuteMarkdownSyntax(protyle); enableLuteMarkdownSyntax(protyle);
let content = protyle.lute.BlockDOM2EscapeMarkerContent(protyle.lute.Md2BlockDOM(textPlain)); let content = protyle.lute.BlockDOM2EscapeMarkerContent(protyle.lute.Md2BlockDOM(textPlain));
@ -273,23 +111,189 @@ export class Title {
document.execCommand("insertText", false, replaceFileName(content)); document.execCommand("insertText", false, replaceFileName(content));
this.rename(protyle); this.rename(protyle);
}); });
event.preventDefault();
event.stopPropagation();
} }
}).element); if (matchHotKey(window.siyuan.config.keymap.general.enterBack.custom, event)) {
window.siyuan.menus.menu.append(new MenuItem({ const ids = protyle.path.split("/");
id: "selectAll", if (ids.length > 2) {
label: window.siyuan.languages.selectAll, /// #if !MOBILE
icon: "iconSelect", openFileById({
accelerator: "⌘A", app: protyle.app,
click: () => { id: ids[ids.length - 2],
range.selectNodeContents(this.editElement); action: [Constants.CB_GET_FOCUS, Constants.CB_GET_SCROLL]
focusByRange(range); });
/// #endif
}
event.preventDefault();
event.stopPropagation();
return;
} }
}).element); if (electronUndo(event)) {
window.siyuan.menus.menu.popup({x: event.clientX, y: event.clientY}); return;
}); }
/// #else if (event.key === "ArrowDown") {
this.element.innerHTML = '<div class="protyle-attr"></div>'; const rects = getSelection().getRangeAt(0).getClientRects();
/// #endif // https://github.com/siyuan-note/siyuan/issues/11729
if (rects.length === 0 // 标题为空时时
|| this.editElement.getBoundingClientRect().bottom - rects[rects.length - 1].bottom < 25) {
const noContainerElement = getNoContainerElement(protyle.wysiwyg.element.firstElementChild);
// https://github.com/siyuan-note/siyuan/issues/4923
if (noContainerElement) {
focusBlock(noContainerElement, protyle.wysiwyg.element);
}
event.preventDefault();
event.stopPropagation();
}
} else if (event.key === "Enter") {
const editElement = getContenteditableElement(protyle.wysiwyg.element.firstElementChild);
if (editElement && editElement.textContent === "" && editElement.getAttribute("placeholder")) {
// 配合提示文本使用,避免提示文本挤压到第二个块中
focusBlock(protyle.wysiwyg.element.firstElementChild, protyle.wysiwyg.element);
} else {
const newId = Lute.NewNodeID();
const newElement = genEmptyElement(false, true, newId);
protyle.wysiwyg.element.insertAdjacentElement("afterbegin", newElement);
focusByWbr(newElement, protyle.toolbar.range || getEditorRange(newElement));
transaction(protyle, [{
action: "insert",
data: newElement.outerHTML,
id: newId,
parentID: protyle.block.parentID
}], [{
action: "delete",
id: newId,
}]);
}
event.preventDefault();
event.stopPropagation();
} else if (matchHotKey(window.siyuan.config.keymap.editor.general.attr.custom, event)) {
fetchPost("/api/block/getDocInfo", {
id: protyle.block.rootID
}, (response) => {
openFileAttr(response.data.ial, "bookmark", protyle);
});
event.preventDefault();
event.stopPropagation();
} else if (matchHotKey("⌘A", event)) {
getEditorRange(this.editElement).selectNodeContents(this.editElement);
event.preventDefault();
event.stopPropagation();
}
});
const iconElement = this.element.querySelector(".protyle-title__icon");
iconElement.addEventListener("click", () => {
if (window.siyuan.shiftIsPressed) {
fetchPost("/api/block/getDocInfo", {
id: protyle.block.rootID
}, (response) => {
openFileAttr(response.data.ial, "bookmark", protyle);
});
} else {
const iconRect = iconElement.getBoundingClientRect();
openTitleMenu(protyle, {x: iconRect.left, y: iconRect.bottom});
}
});
this.element.addEventListener("contextmenu", (event) => {
if (event.shiftKey) {
return;
}
if (getSelection().rangeCount === 0) {
openTitleMenu(protyle, {x: event.clientX, y: event.clientY});
return;
}
protyle.toolbar?.element.classList.add("fn__none");
window.siyuan.menus.menu.remove();
const range = getEditorRange(this.editElement);
if (range.toString() !== "") {
window.siyuan.menus.menu.append(new MenuItem({
id: "copy",
icon: "iconCopy",
accelerator: "⌘C",
label: window.siyuan.languages.copy,
click: () => {
focusByRange(getEditorRange(this.editElement));
document.execCommand("copy");
}
}).element);
window.siyuan.menus.menu.append(new MenuItem({
id: "cut",
icon: "iconCut",
accelerator: "⌘X",
label: window.siyuan.languages.cut,
click: () => {
focusByRange(getEditorRange(this.editElement));
document.execCommand("cut");
setTimeout(() => {
this.rename(protyle);
}, Constants.TIMEOUT_INPUT);
}
}).element);
window.siyuan.menus.menu.append(new MenuItem({
id: "delete",
icon: "iconTrashcan",
accelerator: "⌫",
label: window.siyuan.languages.delete,
click: () => {
const range = getEditorRange(this.editElement);
range.extractContents();
focusByRange(range);
setTimeout(() => {
this.rename(protyle);
}, Constants.TIMEOUT_INPUT);
}
}).element);
}
window.siyuan.menus.menu.append(new MenuItem({
id: "paste",
label: window.siyuan.languages.paste,
icon: "iconPaste",
accelerator: "⌘V",
click: async () => {
focusByRange(getEditorRange(this.editElement));
if (document.queryCommandSupported("paste")) {
document.execCommand("paste");
} else {
try {
const text = await readText();
document.execCommand("insertText", false, replaceFileName(text));
this.rename(protyle);
} catch (e) {
console.log(e);
}
}
}
}).element);
window.siyuan.menus.menu.append(new MenuItem({
id: "pasteAsPlainText",
label: window.siyuan.languages.pasteAsPlainText,
accelerator: "⇧⌘V",
click: async () => {
navigator.clipboard.readText().then(textPlain => {
textPlain = textPlain.replace(/</g, ";;;lt;;;").replace(/>/g, ";;;gt;;;");
enableLuteMarkdownSyntax(protyle);
let content = protyle.lute.BlockDOM2EscapeMarkerContent(protyle.lute.Md2BlockDOM(textPlain));
restoreLuteMarkdownSyntax(protyle);
// 移除 ;;;lt;;; 和 ;;;gt;;; 转义及其包裹的内容
content = content.replace(/;;;lt;;;[^;]+;;;gt;;;/g, "");
document.execCommand("insertText", false, replaceFileName(content));
this.rename(protyle);
});
}
}).element);
window.siyuan.menus.menu.append(new MenuItem({
id: "selectAll",
label: window.siyuan.languages.selectAll,
icon: "iconSelect",
accelerator: "⌘A",
click: () => {
range.selectNodeContents(this.editElement);
focusByRange(range);
}
}).element);
window.siyuan.menus.menu.popup({x: event.clientX, y: event.clientY});
});
}
this.element.querySelector(".protyle-attr").addEventListener("click", (event: MouseEvent & { this.element.querySelector(".protyle-attr").addEventListener("click", (event: MouseEvent & {
target: HTMLElement target: HTMLElement
}) => { }) => {
@ -329,9 +333,15 @@ export class Title {
public setTitle(title: string) { public setTitle(title: string) {
/// #if MOBILE /// #if MOBILE
const inputElement = document.getElementById("toolbarName") as HTMLInputElement; if (this.editElement) {
if (code160to32(title) !== code160to32(inputElement.value)) { if (code160to32(title) !== code160to32(this.editElement.textContent)) {
inputElement.value = title === window.siyuan.languages.untitled ? "" : title; this.editElement.textContent = title === window.siyuan.languages.untitled ? "" : title;
}
} else {
const inputElement = document.getElementById("toolbarName") as HTMLInputElement;
if (code160to32(title) !== code160to32(inputElement.value)) {
inputElement.value = title === window.siyuan.languages.untitled ? "" : title;
}
} }
/// #else /// #else
if (code160to32(title) !== code160to32(this.editElement.textContent)) { if (code160to32(title) !== code160to32(this.editElement.textContent)) {

View file

@ -6,6 +6,8 @@ import {updateHotkeyTip} from "../util/compatibility";
/// #if !MOBILE /// #if !MOBILE
import {openBacklink, openGraph, openOutline} from "../../layout/dock/util"; import {openBacklink, openGraph, openOutline} from "../../layout/dock/util";
import * as path from "path"; import * as path from "path";
/// #else
import {openMobileFileById} from "../../mobile/editor";
/// #endif /// #endif
import {Constants} from "../../constants"; import {Constants} from "../../constants";
import {openCardByData} from "../../card/openCard"; import {openCardByData} from "../../card/openCard";
@ -214,22 +216,24 @@ export const openTitleMenu = (protyle: IProtyle, position: IPosition) => {
transferBlockRef(protyle.block.rootID); transferBlockRef(protyle.block.rootID);
} }
window.siyuan.menus.menu.append(new MenuItem({id: "separator_3", type: "separator"}).element); window.siyuan.menus.menu.append(new MenuItem({id: "separator_3", type: "separator"}).element);
/// #if !MOBILE
if (!protyle.model) { if (!protyle.model) {
window.siyuan.menus.menu.append(new MenuItem({ window.siyuan.menus.menu.append(new MenuItem({
id: "openBy", id: "openBy",
label: window.siyuan.languages.openBy, label: window.siyuan.languages.openBy,
icon: "iconOpen", icon: "iconOpen",
click() { click() {
/// #if !MOBILE
openFileById({ openFileById({
app: protyle.app, app: protyle.app,
id: protyle.block.id, id: protyle.block.id,
action: protyle.block.rootID !== protyle.block.id ? [Constants.CB_GET_ALL, Constants.CB_GET_FOCUS] : [Constants.CB_GET_CONTEXT], action: protyle.block.rootID !== protyle.block.id ? [Constants.CB_GET_ALL, Constants.CB_GET_FOCUS] : [Constants.CB_GET_CONTEXT],
}); });
/// #else
openMobileFileById(protyle.app, protyle.block.id, protyle.block.rootID !== protyle.block.id ? [Constants.CB_GET_ALL] : [Constants.CB_GET_CONTEXT]);
/// #endif
} }
}).element); }).element);
} }
/// #endif
/// #if !BROWSER /// #if !BROWSER
window.siyuan.menus.menu.append(new MenuItem({ window.siyuan.menus.menu.append(new MenuItem({
id: "openByNewWindow", id: "openByNewWindow",

View file

@ -415,10 +415,14 @@ export const genHintItemHTML = (item: IBlock) => {
if (attrHTML) { if (attrHTML) {
attrHTML = `<div class="fn__flex b3-list-item__meta b3-list-item__showall">${attrHTML}</div>`; attrHTML = `<div class="fn__flex b3-list-item__meta b3-list-item__showall">${attrHTML}</div>`;
} }
let countHTML = "";
return `${attrHTML}<div class="b3-list-item__first"> if (item.refCount) {
countHTML = `<span class="popover__block counter b3-tooltips b3-tooltips__w" aria-label="${window.siyuan.languages.ref}">${item.refCount}</span>`;
}
// data-node-id 用于获取引用面板
return `${attrHTML}<div class="b3-list-item__first" data-node-id="${item.id}">
${iconHTML} ${iconHTML}
<span class="b3-list-item__text">${item.content}</span> <span class="b3-list-item__text">${item.content}</span>${countHTML}
</div> </div>
<div class="b3-list-item__meta b3-list-item__showall">${item.hPath}</div>`; <div class="b3-list-item__meta b3-list-item__showall">${item.hPath}</div>`;
}; };

View file

@ -6,7 +6,7 @@ import {
focusByWbr, focusByWbr,
getEditorRange, getEditorRange,
getSelectionOffset, getSelectionOffset,
getSelectionPosition, setLastNodeRange getSelectionPosition,
} from "../util/selection"; } from "../util/selection";
import {genHintItemHTML, hintEmbed, hintRef, hintSlash} from "./extend"; import {genHintItemHTML, hintEmbed, hintRef, hintSlash} from "./extend";
import {getSavePath, newFile} from "../../util/newFile"; import {getSavePath, newFile} from "../../util/newFile";
@ -559,16 +559,12 @@ ${genHintItemHTML(item)}
}, response => { }, response => {
// https://github.com/siyuan-note/siyuan/issues/10133 // https://github.com/siyuan-note/siyuan/issues/10133
protyle.toolbar.range = range; protyle.toolbar.range = range;
protyle.toolbar.setInlineMark(protyle, "block-ref", "range", { const refElement = protyle.toolbar.setInlineMark(protyle, "block-ref", "range", {
type: "id", type: "id",
color: `${response.data}${Constants.ZWSP}${refIsS ? "s" : "d"}${Constants.ZWSP}${(refIsS ? fileNames[0] : realFileName).substring(0, window.siyuan.config.editor.blockRefDynamicAnchorTextMaxLen)}` color: `${response.data}${Constants.ZWSP}${refIsS ? "s" : "d"}${Constants.ZWSP}${(refIsS ? fileNames[0] : realFileName).substring(0, window.siyuan.config.editor.blockRefDynamicAnchorTextMaxLen)}`
}); });
if (protyle.toolbar.range.endContainer.nodeType === 1 && if (refElement[0]) {
protyle.toolbar.range.endContainer.childNodes[protyle.toolbar.range.endOffset]) { protyle.toolbar.range.setEnd(refElement[0].lastChild, refElement[0].lastChild.textContent.length);
const refElement = hasPreviousSibling(protyle.toolbar.range.endContainer.childNodes[protyle.toolbar.range.endOffset]) as HTMLElement;
if (refElement && refElement.nodeType === 1 && refElement.getAttribute("data-type") === "block-ref") {
setLastNodeRange(refElement as HTMLElement, protyle.toolbar.range, false);
}
} }
protyle.toolbar.range.collapse(false); protyle.toolbar.range.collapse(false);
}); });
@ -600,16 +596,12 @@ ${genHintItemHTML(item)}
tempElement.innerText = dynamicTexts[1]; tempElement.innerText = dynamicTexts[1];
} }
} }
protyle.toolbar.setInlineMark(protyle, "block-ref", "range", { const refElement = protyle.toolbar.setInlineMark(protyle, "block-ref", "range", {
type: "id", type: "id",
color: `${tempElement.getAttribute("data-id")}${Constants.ZWSP}${tempElement.getAttribute("data-subtype")}${Constants.ZWSP}${tempElement.textContent}` color: `${tempElement.getAttribute("data-id")}${Constants.ZWSP}${tempElement.getAttribute("data-subtype")}${Constants.ZWSP}${tempElement.textContent}`
}); });
if (protyle.toolbar.range.endContainer.nodeType === 1 && if (refElement[0]) {
protyle.toolbar.range.endContainer.childNodes[protyle.toolbar.range.endOffset]) { protyle.toolbar.range.setEnd(refElement[0].lastChild, refElement[0].lastChild.textContent.length);
const refElement = hasPreviousSibling(protyle.toolbar.range.endContainer.childNodes[protyle.toolbar.range.endOffset]) as HTMLElement;
if (refElement && refElement.nodeType === 1 && refElement.getAttribute("data-type") === "block-ref") {
setLastNodeRange(refElement as HTMLElement, protyle.toolbar.range, false);
}
} }
protyle.toolbar.range.collapse(false); protyle.toolbar.range.collapse(false);
return; return;

View file

@ -47,7 +47,6 @@ import {getAllModels} from "../layout/getAll";
/// #endif /// #endif
import {isSupportCSSHL} from "./render/searchMarkRender"; import {isSupportCSSHL} from "./render/searchMarkRender";
import {renderAVAttribute} from "./render/av/blockAttr"; import {renderAVAttribute} from "./render/av/blockAttr";
import {genEmptyElement} from "../block/util";
import {zoomOut} from "../menus/protyle"; import {zoomOut} from "../menus/protyle";
export class Protyle { export class Protyle {
@ -159,50 +158,7 @@ export class Protyle {
} }
break; break;
case "transactions": case "transactions":
data.data[0].doOperations.find((item: IOperation) => { this.onTransaction(data);
if (!this.protyle.preview.element.classList.contains("fn__none")) {
this.protyle.preview.render(this.protyle);
} else if (options.backlinkData && ["delete", "move"].includes(item.action)) {
// 只对特定情况刷新,否则展开、编辑等操作刷新会频繁
/// #if !MOBILE
getAllModels().backlink.find(backlinkItem => {
if (backlinkItem.element.contains(this.protyle.element)) {
backlinkItem.refresh();
return true;
}
});
/// #endif
return true;
} else {
onTransaction(this.protyle, item, false);
// 反链面板移除元素后,文档为空
if (this.protyle.wysiwyg.element.childElementCount === 0 && this.protyle.block.parentID &&
!(item.action === "delete" && typeof item.data?.createEmptyParagraph === "boolean" && !item.data.createEmptyParagraph)) {
if (item.action === "delete" && this.protyle.block.showAll) {
if (this.protyle.options.handleEmptyContent) {
this.protyle.options.handleEmptyContent();
} else {
zoomOut({
protyle: this.protyle,
id: this.protyle.block.rootID,
focusId: this.protyle.block.id
});
}
} else {
const newID = Lute.NewNodeID();
const emptyElement = genEmptyElement(false, false, newID);
this.protyle.wysiwyg.element.append(emptyElement);
transaction(this.protyle, [{
action: "insert",
data: emptyElement.outerHTML,
id: newID,
parentID: this.protyle.block.parentID
}]);
this.protyle.undo.clear();
}
}
}
});
break; break;
case "readonly": case "readonly":
window.siyuan.config.editor.readOnly = data.data; window.siyuan.config.editor.readOnly = data.data;
@ -329,6 +285,52 @@ export class Protyle {
} }
} }
private onTransaction(data: IWebSocketData) {
let needCreateAction = "";
data.data[0].doOperations.find((item: IOperation) => {
if (!this.protyle.preview.element.classList.contains("fn__none")) {
this.protyle.preview.render(this.protyle);
if (item.action === "updateAttrs") {
onTransaction(this.protyle, item, false);
}
} else if (this.protyle.options.backlinkData && ["delete", "move"].includes(item.action)) {
// 只对特定情况刷新,否则展开、编辑等操作刷新会频繁
/// #if !MOBILE
getAllModels().backlink.find(backlinkItem => {
if (backlinkItem.element.contains(this.protyle.element)) {
backlinkItem.refresh();
return true;
}
});
/// #endif
return true;
} else {
onTransaction(this.protyle, item, false);
// 反链面板移除元素后,文档为空
if (!(item.action === "delete" && typeof item.data?.createEmptyParagraph === "boolean" && !item.data.createEmptyParagraph)) {
needCreateAction = item.action;
}
}
});
if (this.protyle.wysiwyg.element.childElementCount === 0 && this.protyle.block.parentID && needCreateAction) {
if (needCreateAction === "delete" && this.protyle.block.showAll) {
if (this.protyle.options.handleEmptyContent) {
this.protyle.options.handleEmptyContent();
} else {
zoomOut({
protyle: this.protyle,
id: this.protyle.block.rootID,
focusId: this.protyle.block.id
});
}
} else {
// 不能使用 transaction否则分屏后会重复添加
this.protyle.undo.clear();
this.reload(false);
}
}
}
private getDoc(mergedOptions: IProtyleOptions) { private getDoc(mergedOptions: IProtyleOptions) {
fetchPost("/api/filetree/getDoc", { fetchPost("/api/filetree/getDoc", {
id: mergedOptions.blockId, id: mergedOptions.blockId,

View file

@ -440,7 +440,7 @@ class="fn__flex-1 fn__flex${["url", "text", "number", "email", "phone", "block"]
fetchPost("/api/av/setAttributeViewBlockAttr", { fetchPost("/api/av/setAttributeViewBlockAttr", {
avID: item.parentElement.dataset.avId, avID: item.parentElement.dataset.avId,
keyID: item.parentElement.dataset.colId, keyID: item.parentElement.dataset.colId,
rowID: item.parentElement.dataset.rowId, itemID: item.parentElement.dataset.rowId,
value value
}, (setResponse) => { }, (setResponse) => {
if (type === "number") { if (type === "number") {

View file

@ -309,7 +309,7 @@ export const genCellValue = (colType: TAVCol, value: string | any) => {
content2: dateObj2.valueOf() || 0, content2: dateObj2.valueOf() || 0,
isNotEmpty2: !isNaN(dateObj2.valueOf()), isNotEmpty2: !isNaN(dateObj2.valueOf()),
hasEndDate: !isNaN(dateObj2.valueOf()), hasEndDate: !isNaN(dateObj2.valueOf()),
isNotTime: dateObj1.hour() === 0, isNotTime: dateObj1.hour() === 0 && values[0].split(":").length === 1,
formattedContent: "", formattedContent: "",
} }
}; };
@ -517,6 +517,9 @@ export const popTextCell = (protyle: IProtyle, cellElements: HTMLElement[], type
html = `<input type="number" spellcheck="false" value="${cellElements[0].firstElementChild.getAttribute("data-content")}" ${style} class="b3-text-field">`; html = `<input type="number" spellcheck="false" value="${cellElements[0].firstElementChild.getAttribute("data-content")}" ${style} class="b3-text-field">`;
} else { } else {
if (["select", "mSelect"].includes(type)) { if (["select", "mSelect"].includes(type)) {
if (blockElement.getAttribute("data-rendering") === "true") {
return;
}
openMenuPanel({protyle, blockElement, type: "select", cellElements}); openMenuPanel({protyle, blockElement, type: "select", cellElements});
} else if (type === "mAsset") { } else if (type === "mAsset") {
openMenuPanel({protyle, blockElement, type: "asset", cellElements}); openMenuPanel({protyle, blockElement, type: "asset", cellElements});

View file

@ -192,11 +192,7 @@ export const getEditHTML = (options: {
<input type="checkbox" data-type="wrap" class="b3-switch b3-switch--menu"${colData.wrap ? " checked" : ""}> <input type="checkbox" data-type="wrap" class="b3-switch b3-switch--menu"${colData.wrap ? " checked" : ""}>
</label>`; </label>`;
if (colData.type !== "block") { if (colData.type !== "block") {
html += `<button class="b3-menu__item" data-type="${colData.hidden ? "showCol" : "hideCol"}"> html += `<button class="b3-menu__item${colData.type === "relation" ? " fn__none" : ""}" data-type="duplicateCol">
<svg class="b3-menu__icon" style=""><use xlink:href="#icon${colData.hidden ? "Eye" : "Eyeoff"}"></use></svg>
<span class="b3-menu__label">${colData.hidden ? window.siyuan.languages.showCol : window.siyuan.languages.hideCol}</span>
</button>
<button class="b3-menu__item${colData.type === "relation" ? " fn__none" : ""}" data-type="duplicateCol">
<svg class="b3-menu__icon" style=""><use xlink:href="#iconCopy"></use></svg> <svg class="b3-menu__icon" style=""><use xlink:href="#iconCopy"></use></svg>
<span class="b3-menu__label">${window.siyuan.languages.duplicate}</span> <span class="b3-menu__label">${window.siyuan.languages.duplicate}</span>
</button> </button>
@ -468,11 +464,11 @@ export const bindEditEvent = (options: {
}); });
if (oldValue.avID) { if (oldValue.avID) {
fetchPost("/api/av/getAttributeView", {id: oldValue.avID}, (response) => { fetchPost("/api/av/getAttributeView", {id: oldValue.avID}, (response) => {
goSearchElement.querySelector(".b3-menu__accelerator").textContent = oldValue.avID === avID ? window.siyuan.languages.thisDatabase : (response.data.av.name || window.siyuan.languages.title); goSearchElement.querySelector(".b3-menu__accelerator").textContent = oldValue.avID === avID ? window.siyuan.languages.thisDatabase : (response.data.av.name || window.siyuan.languages._kernel[267]);
response.data.av.keyValues.find((item: { key: { id: string, name: string } }) => { response.data.av.keyValues.find((item: { key: { id: string, name: string } }) => {
if (item.key.id === oldValue.backKeyID) { if (item.key.id === oldValue.backKeyID) {
inputElement.setAttribute("data-old-value", item.key.name || window.siyuan.languages.title); inputElement.setAttribute("data-old-value", item.key.name || window.siyuan.languages._kernel[272]);
inputElement.value = item.key.name || window.siyuan.languages.title; inputElement.value = item.key.name || window.siyuan.languages._kernel[272];
return true; return true;
} }
}); });
@ -877,8 +873,88 @@ export const showColMenu = (protyle: IProtyle, blockElement: Element, cellElemen
}); });
} }
}); });
menu.addSeparator({id: "separator_2"});
} }
const isPin = cellElement.dataset.pin === "true";
menu.addItem({
id: isPin ? "unfreezeCol" : "freezeCol",
icon: isPin ? "iconUnpin" : "iconPin",
label: isPin ? window.siyuan.languages.unfreezeCol : window.siyuan.languages.freezeCol,
click() {
transaction(protyle, [{
action: "setAttrViewColPin",
id: colId,
avID,
data: !isPin,
blockID
}], [{
action: "setAttrViewColPin",
id: colId,
avID,
data: isPin,
blockID
}]);
updateAttrViewCellAnimation(blockElement.querySelector(`.av__row--header .av__cell[data-col-id="${colId}"]`), undefined, {pin: !isPin});
}
});
if (type !== "block") {
menu.addItem({
id: "hide",
icon: "iconEyeoff",
label: window.siyuan.languages.hide,
click() {
transaction(protyle, [{
action: "setAttrViewColHidden",
id: colId,
avID,
data: true,
blockID
}], [{
action: "setAttrViewColHidden",
id: colId,
avID,
data: false,
blockID
}]);
}
});
}
menu.addItem({
icon: "iconRefresh",
label: window.siyuan.languages.syncColWidth,
click() {
transaction(protyle, [{
action: "syncAttrViewTableColWidth",
keyID: colId,
avID,
id: blockElement.getAttribute(Constants.CUSTOM_SY_AV_VIEW),
}]);
}
});
menu.addItem({
icon: "iconSoftWrap",
label: `<label class="fn__flex" style="margin-bottom: 4px"><span>${window.siyuan.languages.wrap}</span><span class="fn__space fn__flex-1"></span>
<input type="checkbox" class="b3-switch b3-switch--menu"${cellElement.dataset.wrap === "true" ? " checked" : ""}></label>`,
bind(element) {
const wrapElement = element.querySelector(".b3-switch") as HTMLInputElement;
wrapElement.addEventListener("change", () => {
transaction(protyle, [{
action: "setAttrViewColWrap",
id: colId,
avID,
data: wrapElement.checked,
blockID
}], [{
action: "setAttrViewColWrap",
id: colId,
avID,
data: !wrapElement.checked,
blockID
}]);
menu.close();
});
}
});
menu.addSeparator({id: "separator_2"});
menu.addItem({ menu.addItem({
id: "insertColumnLeft", id: "insertColumnLeft",
icon: "iconInsertLeft", icon: "iconInsertLeft",
@ -913,62 +989,6 @@ export const showColMenu = (protyle: IProtyle, blockElement: Element, cellElemen
}); });
} }
}); });
if (type !== "block") {
menu.addItem({
id: "hide",
icon: "iconEyeoff",
label: window.siyuan.languages.hide,
click() {
transaction(protyle, [{
action: "setAttrViewColHidden",
id: colId,
avID,
data: true,
blockID
}], [{
action: "setAttrViewColHidden",
id: colId,
avID,
data: false,
blockID
}]);
}
});
}
const isPin = cellElement.dataset.pin === "true";
menu.addItem({
id: isPin ? "unfreezeCol" : "freezeCol",
icon: isPin ? "iconUnpin" : "iconPin",
label: isPin ? window.siyuan.languages.unfreezeCol : window.siyuan.languages.freezeCol,
click() {
transaction(protyle, [{
action: "setAttrViewColPin",
id: colId,
avID,
data: !isPin,
blockID
}], [{
action: "setAttrViewColPin",
id: colId,
avID,
data: isPin,
blockID
}]);
updateAttrViewCellAnimation(blockElement.querySelector(`.av__row--header .av__cell[data-col-id="${colId}"]`), undefined, {pin: !isPin});
}
});
menu.addItem({
icon: "iconRefresh",
label: window.siyuan.languages.syncColWidth,
click() {
transaction(protyle, [{
action: "syncAttrViewTableColWidth",
keyID: colId,
avID,
id: blockElement.getAttribute(Constants.CUSTOM_SY_AV_VIEW),
}]);
}
});
if (type !== "block") { if (type !== "block") {
if (type !== "relation") { if (type !== "relation") {
menu.addItem({ menu.addItem({
@ -1003,16 +1023,22 @@ export const showColMenu = (protyle: IProtyle, blockElement: Element, cellElemen
if (colData.key.relation?.isTwoWay) { if (colData.key.relation?.isTwoWay) {
const relResponse = await fetchSyncPost("/api/av/getAttributeView", {id: colData.key.relation.avID}); const relResponse = await fetchSyncPost("/api/av/getAttributeView", {id: colData.key.relation.avID});
const dialog = new Dialog({ const dialog = new Dialog({
title: window.siyuan.languages.removeCol.replace("${x}", colData.key.name), title: window.siyuan.languages.removeColConfirm,
content: `<div class="b3-dialog__content"> content: `<div class="b3-dialog__content">
${window.siyuan.languages.confirmRemoveRelationField.replace("${x}", relResponse.data.av.name)} ${window.siyuan.languages.confirmRemoveRelationField
.replace("${x}", colData.key.name || window.siyuan.languages._kernel[272])
.replace("${y}", relResponse.data.av.name || window.siyuan.languages._kernel[267])
.replace("${z}", relResponse.data.av.keyValues.find((item: {
key: { id: string }
}) => item.key.id === colData.key.relation.backKeyID).key.name || window.siyuan.languages._kernel[272])}
<div class="fn__hr--b"></div> <div class="fn__hr--b"></div>
<button class="fn__block b3-button b3-button--remove" data-action="delete">${window.siyuan.languages.delete}</button> <button class="fn__block b3-button b3-button--remove" data-action="delete">${window.siyuan.languages.removeBothRelationField}</button>
<div class="fn__hr"></div> <div class="fn__hr"></div>
<button class="fn__block b3-button b3-button--remove" data-action="keep-relation">${window.siyuan.languages.removeButKeepRelationField}</button> <button class="fn__block b3-button b3-button--remove" data-action="keep-relation">${window.siyuan.languages.removeButKeepRelationField}</button>
<div class="fn__hr"></div> <div class="fn__hr"></div>
<button class="fn__block b3-button b3-button--cancel">${window.siyuan.languages.cancel}</button> <button class="fn__block b3-button b3-button--cancel">${window.siyuan.languages.cancel}</button>
</div>`, </div>`,
width: "520px",
}); });
dialog.element.addEventListener("click", (event) => { dialog.element.addEventListener("click", (event) => {
let target = event.target as HTMLElement; let target = event.target as HTMLElement;

View file

@ -18,9 +18,9 @@ export const getDateHTML = (cellElements: HTMLElement[]) => {
let value2 = ""; let value2 = "";
if (cellValue.isNotEmpty2) { if (cellValue.isNotEmpty2) {
value2 = dayjs(cellValue.content2).format(isNotTime ? "YYYY-MM-DD" : "YYYY-MM-DD HH:mm"); value2 = dayjs(cellValue.content2).format(isNotTime ? "YYYY-MM-DD" : "YYYY-MM-DD HH:mm");
const year = value.split("-")[0]; const year = value2.split("-")[0];
if (year.length !== 4) { if (year.length !== 4) {
value = new Array(4 - year.length).fill(0).join("") + value; value2 = new Array(4 - year.length).fill(0).join("") + value2;
} }
} else if (cellValue.hasEndDate) { } else if (cellValue.hasEndDate) {
value2 = dayjs(currentDate).format(isNotTime ? "YYYY-MM-DD" : "YYYY-MM-DD HH:mm"); value2 = dayjs(currentDate).format(isNotTime ? "YYYY-MM-DD" : "YYYY-MM-DD HH:mm");
@ -94,6 +94,8 @@ export const bindDateEvent = (options: {
} }
}); });
inputElements[3].addEventListener("change", () => { inputElements[3].addEventListener("change", () => {
inputElements[0].value = "";
inputElements[1].value = "";
if (inputElements[3].checked) { if (inputElements[3].checked) {
inputElements[0].setAttribute("type", "datetime-local"); inputElements[0].setAttribute("type", "datetime-local");
inputElements[1].setAttribute("type", "datetime-local"); inputElements[1].setAttribute("type", "datetime-local");

View file

@ -83,10 +83,10 @@ export const setFilter = async (options: {
rectTarget = options.protyle.wysiwyg.element.querySelector(`[data-col-id="${options.target.dataset.colId}"]`).getBoundingClientRect(); rectTarget = options.protyle.wysiwyg.element.querySelector(`[data-col-id="${options.target.dataset.colId}"]`).getBoundingClientRect();
} }
const blockID = options.blockElement.getAttribute("data-node-id"); const blockID = options.blockElement.getAttribute("data-node-id");
let operationElement: HTMLSelectElement = undefined;
const menu = new Menu("set-filter-" + options.filter.column, () => { const menu = new Menu("set-filter-" + options.filter.column, () => {
const oldFilters = JSON.parse(JSON.stringify(options.data.view.filters)); const oldFilters = JSON.parse(JSON.stringify(options.data.view.filters));
const selectElement = menu.element.querySelector(".b3-select") as HTMLSelectElement; if (!operationElement || !operationElement.value) {
if (!selectElement || !selectElement.value) {
return; return;
} }
const newFilter: IAVFilter = { const newFilter: IAVFilter = {
@ -94,7 +94,7 @@ export const setFilter = async (options: {
value: { value: {
type: options.filter.value.type type: options.filter.value.type
}, },
operator: selectElement.value as TAVFilterOperator operator: operationElement.value as TAVFilterOperator
}; };
let hasMatch = false; let hasMatch = false;
let newValue; let newValue;
@ -132,8 +132,8 @@ export const setFilter = async (options: {
newValue = genCellValue(filterValue.type, { newValue = genCellValue(filterValue.type, {
isNotEmpty2: textElements[2].value !== "", isNotEmpty2: textElements[2].value !== "",
isNotEmpty: textElements[0].value !== "", isNotEmpty: textElements[0].value !== "",
content: textElements[0].value ? new Date(textElements[0].value + " 00:00").getTime() : null, content: textElements[0].value ? new Date(textElements[0].value + " 00:00").getTime() : 0,
content2: textElements[2].value ? new Date(textElements[2].value + " 00:00").getTime() : null, content2: textElements[2].value ? new Date(textElements[2].value + " 00:00").getTime() : 0,
hasEndDate: newFilter.operator === "Is between", hasEndDate: newFilter.operator === "Is between",
isNotTime: true, isNotTime: true,
}); });
@ -156,6 +156,7 @@ export const setFilter = async (options: {
}, },
type: "rollup" type: "rollup"
}; };
newFilter.quantifier = (menu.element.querySelector('.b3-select[data-type="quantifier"]') as HTMLSelectElement).value;
} else { } else {
newFilter.value = newValue; newFilter.value = newValue;
} }
@ -211,6 +212,7 @@ export const setFilter = async (options: {
if (colData.type === "rollup") { if (colData.type === "rollup") {
if (!colData.rollup || !colData.rollup.relationKeyID || !colData.rollup.keyID) { if (!colData.rollup || !colData.rollup.relationKeyID || !colData.rollup.keyID) {
showMessage(window.siyuan.languages.plsChoose); showMessage(window.siyuan.languages.plsChoose);
document.querySelector(".av__panel")?.remove();
openMenuPanel({ openMenuPanel({
protyle: options.protyle, protyle: options.protyle,
blockElement: options.blockElement, blockElement: options.blockElement,
@ -219,33 +221,46 @@ export const setFilter = async (options: {
}); });
return; return;
} }
let targetAVId = ""; if (colData.rollup.calc?.operator && colData.rollup.calc.operator !== "Range") {
fields.find((column) => { if (["Count all", "Count empty", "Count not empty", "Count values", "Count unique values", "Percent empty",
if (column.id === colData.rollup.relationKeyID) { "Percent not empty", "Percent unique values", "Percent checked", "Percent unchecked", "Sum", "Average", "Median",
targetAVId = column.relation.avID; "Min", "Max"].includes(colData.rollup.calc.operator)) {
return true; filterValue.type = "number";
} else if (["Checked", "Unchecked"].includes(colData.rollup.calc.operator)) {
filterValue.type = "checkbox";
} else if (["Earliest", "Latest"].includes(colData.rollup.calc.operator)) {
filterValue.type = "date";
} }
}); } else {
const response = await fetchSyncPost("/api/av/getAttributeView", {id: targetAVId}); let targetAVId = "";
response.data.av.keyValues.find((item: { fields.find((column) => {
key: { if (column.id === colData.rollup.relationKeyID) {
id: string, targetAVId = column.relation.avID;
name: string, return true;
type: TAVCol,
options: {
name: string,
color: string,
}[]
}
}) => {
if (item.key.id === colData.rollup.keyID) {
filterValue.type = item.key.type;
if (item.key.type === "select") {
colData.options = item.key.options;
} }
return true; });
} const response = await fetchSyncPost("/api/av/getAttributeView", {id: targetAVId});
}); response.data.av.keyValues.find((item: {
key: {
id: string,
name: string,
type: TAVCol,
options: {
name: string,
color: string,
}[]
}
}) => {
if (item.key.id === colData.rollup.keyID) {
filterValue.type = item.key.type;
if (item.key.type === "select") {
colData.options = item.key.options;
}
return true;
}
});
}
options.data.view.filters.find(item => { options.data.view.filters.find(item => {
if (item.column === colData.id && item.value.type === "rollup") { if (item.column === colData.id && item.value.type === "rollup") {
if (!item.value.rollup || !item.value.rollup.contents || item.value.rollup.contents.length === 0) { if (!item.value.rollup || !item.value.rollup.contents || item.value.rollup.contents.length === 0) {
@ -336,10 +351,21 @@ export const setFilter = async (options: {
<option ${"Is not empty" === options.filter.operator ? "selected" : ""} value="Is not empty">${window.siyuan.languages.filterOperatorIsNotEmpty}</option>`; <option ${"Is not empty" === options.filter.operator ? "selected" : ""} value="Is not empty">${window.siyuan.languages.filterOperatorIsNotEmpty}</option>`;
break; break;
} }
if (options.filter.value.type === "rollup") {
menu.addItem({
iconHTML: "",
type: "readonly",
label: ` <select style="margin: 4px 0" class="b3-select fn__size200" data-type="quantifier">
<option ${(options.filter.quantifier === "" || options.filter.quantifier === "Any") ? "selected" : ""} value="Any">${window.siyuan.languages.filterQuantifierAny}</option>
<option ${"All" === options.filter.quantifier ? "selected" : ""} value="All">${window.siyuan.languages.filterQuantifierAll}</option>
<option ${"None" === options.filter.quantifier ? "selected" : ""} value="None">${window.siyuan.languages.filterQuantifierNone}</option>
</select>`
});
}
menu.addItem({ menu.addItem({
iconHTML: "", iconHTML: "",
type: "readonly", type: "readonly",
label: `<select style="margin: 4px 0" class="b3-select fn__size200">${selectHTML}</select>` label: `<select style="margin: 4px 0" class="b3-select fn__size200" data-type="operation">${selectHTML}</select>`
}); });
if (filterValue.type === "select" || filterValue.type === "mSelect") { if (filterValue.type === "select" || filterValue.type === "mSelect") {
if (colData.options?.length > 0) { if (colData.options?.length > 0) {
@ -506,9 +532,9 @@ export const setFilter = async (options: {
} }
} }
}); });
const selectElement = (menu.element.querySelector(".b3-select") as HTMLSelectElement); operationElement = (menu.element.querySelector('.b3-select[data-type="operation"]') as HTMLSelectElement);
selectElement.addEventListener("change", () => { operationElement?.addEventListener("change", () => {
toggleEmpty(selectElement, selectElement.value, filterValue.type); toggleEmpty(operationElement, operationElement.value, filterValue.type);
}); });
const dateTypeElement = menu.element.querySelector('.b3-select[data-type="dateType"]') as HTMLSelectElement; const dateTypeElement = menu.element.querySelector('.b3-select[data-type="dateType"]') as HTMLSelectElement;
dateTypeElement?.addEventListener("change", () => { dateTypeElement?.addEventListener("change", () => {
@ -557,7 +583,7 @@ export const setFilter = async (options: {
}); });
}); });
} }
toggleEmpty(selectElement, selectElement.value, filterValue.type); toggleEmpty(operationElement, operationElement.value, filterValue.type);
menu.open({x: rectTarget.left, y: rectTarget.bottom}); menu.open({x: rectTarget.left, y: rectTarget.bottom});
if (textElements.length > 0) { if (textElements.length > 0) {
textElements[0].select(); textElements[0].select();
@ -625,18 +651,27 @@ export const getFiltersHTML = (data: IAV) => {
fields.find((item) => { fields.find((item) => {
if (item.id === filter.column && item.type === filter.value.type) { if (item.id === filter.column && item.type === filter.value.type) {
let filterText = ""; let filterText = "";
if (item.type === "rollup") {
if (filter.quantifier === "" || filter.quantifier === "Any") {
filterText = window.siyuan.languages.filterQuantifierAny + " ";
} else if (filter.quantifier === "All") {
filterText = window.siyuan.languages.filterQuantifierAll + " ";
} else if (filter.quantifier === "None") {
filterText = window.siyuan.languages.filterQuantifierNone + " ";
}
}
const filterValue = item.type === "rollup" ? (filter.value.rollup?.contents?.length > 0 ? filter.value.rollup.contents[0] : {type: "rollup"} as IAVCellValue) : filter.value; const filterValue = item.type === "rollup" ? (filter.value.rollup?.contents?.length > 0 ? filter.value.rollup.contents[0] : {type: "rollup"} as IAVCellValue) : filter.value;
if (filter.operator === "Is empty") { if (filter.operator === "Is empty") {
filterText = ": " + window.siyuan.languages.filterOperatorIsEmpty; filterText = ": " + filterText + window.siyuan.languages.filterOperatorIsEmpty;
} else if (filter.operator === "Is not empty") { } else if (filter.operator === "Is not empty") {
filterText = ": " + window.siyuan.languages.filterOperatorIsNotEmpty; filterText = ": " + filterText + window.siyuan.languages.filterOperatorIsNotEmpty;
} else if (filter.operator === "Is false") { } else if (filter.operator === "Is false") {
if (filterValue.type !== "checkbox" || typeof filterValue.checkbox.checked === "boolean") { if (filterValue.type !== "checkbox" || typeof filterValue.checkbox.checked === "boolean") {
filterText = ": " + window.siyuan.languages.unchecked; filterText = ": " + filterText + window.siyuan.languages.unchecked;
} }
} else if (filter.operator === "Is true") { } else if (filter.operator === "Is true") {
if (filterValue.type !== "checkbox" || typeof filterValue.checkbox.checked === "boolean") { if (filterValue.type !== "checkbox" || typeof filterValue.checkbox.checked === "boolean") {
filterText = ": " + window.siyuan.languages.checked; filterText = ": " + filterText + window.siyuan.languages.checked;
} }
} else if (["created", "updated", "date"].includes(filterValue.type)) { } else if (["created", "updated", "date"].includes(filterValue.type)) {
let dateValue = ""; let dateValue = "";
@ -660,15 +695,15 @@ export const getFiltersHTML = (data: IAV) => {
} }
if (dateValue) { if (dateValue) {
if (filter.operator === "Is between" && dateValue2) { if (filter.operator === "Is between" && dateValue2) {
filterText = ` ${window.siyuan.languages.filterOperatorIsBetween} ${dateValue} ${dateValue2}`; filterText = ` ${filterText}${window.siyuan.languages.filterOperatorIsBetween} ${dateValue} ${dateValue2}`;
} else if ("=" === filter.operator) { } else if ("=" === filter.operator) {
filterText = `: ${dateValue}`; filterText = `: ${filterText}${dateValue}`;
} else if ([">", "<"].includes(filter.operator)) { } else if ([">", "<"].includes(filter.operator)) {
filterText = ` ${filter.operator} ${dateValue}`; filterText = ` ${filterText}${filter.operator} ${dateValue}`;
} else if (">=" === filter.operator) { } else if (">=" === filter.operator) {
filterText = ` ${dateValue}`; filterText = ` ${filterText}${dateValue}`;
} else if ("<=" === filter.operator) { } else if ("<=" === filter.operator) {
filterText = ` ${dateValue}`; filterText = ` ${filterText}${dateValue}`;
} }
} }
} else if (["mSelect", "select"].includes(filterValue.type) && filterValue.mSelect?.length > 0) { } else if (["mSelect", "select"].includes(filterValue.type) && filterValue.mSelect?.length > 0) {
@ -680,41 +715,41 @@ export const getFiltersHTML = (data: IAV) => {
} }
}); });
if ("Contains" === filter.operator) { if ("Contains" === filter.operator) {
filterText = `: ${selectContent}`; filterText = `: ${filterText}${selectContent}`;
} else if (filter.operator === "Does not contains") { } else if (filter.operator === "Does not contains") {
filterText = ` ${window.siyuan.languages.filterOperatorDoesNotContain} ${selectContent}`; filterText = ` ${filterText}${window.siyuan.languages.filterOperatorDoesNotContain} ${selectContent}`;
} else if (filter.operator === "=") { } else if (filter.operator === "=") {
filterText = `: ${selectContent}`; filterText = `: ${filterText}${selectContent}`;
} else if (filter.operator === "!=") { } else if (filter.operator === "!=") {
filterText = ` ${window.siyuan.languages.filterOperatorIsNot} ${selectContent}`; filterText = ` ${filterText}${window.siyuan.languages.filterOperatorIsNot} ${selectContent}`;
} }
} else if (filterValue.type === "number" && filterValue.number && filterValue.number.isNotEmpty) { } else if (filterValue.type === "number" && filterValue.number && filterValue.number.isNotEmpty) {
if (["=", "!=", ">", "<"].includes(filter.operator)) { if (["=", "!=", ">", "<"].includes(filter.operator)) {
filterText = ` ${filter.operator} ${filterValue.number.content}`; filterText = ` ${filterText}${filter.operator} ${filterValue.number.content}`;
} else if (">=" === filter.operator) { } else if (">=" === filter.operator) {
filterText = ` ${filterValue.number.content}`; filterText = ` ${filterText}${filterValue.number.content}`;
} else if ("<=" === filter.operator) { } else if ("<=" === filter.operator) {
filterText = ` ${filterValue.number.content}`; filterText = ` ${filterText}${filterValue.number.content}`;
} }
} else if (["text", "block", "url", "phone", "email", "relation", "template"].includes(filterValue.type) && filterValue[filterValue.type as "text"]) { } else if (["text", "block", "url", "phone", "email", "relation", "template"].includes(filterValue.type) && filterValue[filterValue.type as "text"]) {
const content = filterValue[filterValue.type as "text"].content || filterValue.relation?.blockIDs[0] || ""; const content = filterValue[filterValue.type as "text"].content || filterValue.relation?.blockIDs[0] || "";
if (content) { if (content) {
if (["=", "Contains"].includes(filter.operator)) { if (["=", "Contains"].includes(filter.operator)) {
filterText = `: ${content}`; filterText = `: ${filterText}${content}`;
} else if (filter.operator === "Does not contains") { } else if (filter.operator === "Does not contains") {
filterText = ` ${window.siyuan.languages.filterOperatorDoesNotContain} ${content}`; filterText = ` ${filterText}${window.siyuan.languages.filterOperatorDoesNotContain} ${content}`;
} else if (filter.operator === "!=") { } else if (filter.operator === "!=") {
filterText = ` ${window.siyuan.languages.filterOperatorIsNot} ${content}`; filterText = ` ${filterText}${window.siyuan.languages.filterOperatorIsNot} ${content}`;
} else if ("Starts with" === filter.operator) { } else if ("Starts with" === filter.operator) {
filterText = ` ${window.siyuan.languages.filterOperatorStartsWith} ${content}`; filterText = ` ${filterText}${window.siyuan.languages.filterOperatorStartsWith} ${content}`;
} else if ("Ends with" === filter.operator) { } else if ("Ends with" === filter.operator) {
filterText = ` ${window.siyuan.languages.filterOperatorEndsWith} ${content}`; filterText = ` ${filterText}${window.siyuan.languages.filterOperatorEndsWith} ${content}`;
} else if ([">", "<"].includes(filter.operator)) { } else if ([">", "<"].includes(filter.operator)) {
filterText = ` ${filter.operator} ${content}`; filterText = ` ${filterText}${filter.operator} ${content}`;
} else if (">=" === filter.operator) { } else if (">=" === filter.operator) {
filterText = ` ${content}`; filterText = ` ${filterText}${content}`;
} else if ("<=" === filter.operator) { } else if ("<=" === filter.operator) {
filterText = ` ${content}`; filterText = ` ${filterText}${content}`;
} }
} }
} }

View file

@ -1198,16 +1198,21 @@ export const openMenuPanel = (options: {
const isTwoWay = colData.type === "relation" && colData.relation?.isTwoWay; const isTwoWay = colData.type === "relation" && colData.relation?.isTwoWay;
if (isCustomAttr || isTwoWay) { if (isCustomAttr || isTwoWay) {
const dialog = new Dialog({ const dialog = new Dialog({
title: isTwoWay ? window.siyuan.languages.removeCol.replace("${x}", menuElement.querySelector("input").value) : window.siyuan.languages.deleteOpConfirm, title: isTwoWay ? window.siyuan.languages.removeColConfirm : window.siyuan.languages.deleteOpConfirm,
content: `<div class="b3-dialog__content"> content: `<div class="b3-dialog__content">
${isTwoWay ? window.siyuan.languages.confirmRemoveRelationField.replace("${x}", menuElement.querySelector('.b3-menu__item[data-type="goSearchAV"] .b3-menu__accelerator').textContent) : window.siyuan.languages.removeCol.replace("${x}", menuElement.querySelector("input").value)} ${isTwoWay ? window.siyuan.languages.confirmRemoveRelationField
.replace("${x}", menuElement.querySelector("input").value || window.siyuan.languages._kernel[272])
.replace("${y}", menuElement.querySelector('.b3-menu__item[data-type="goSearchAV"] .b3-menu__accelerator').textContent)
.replace("${z}", (menuElement.querySelector('input[data-type="colName"]') as HTMLInputElement).value || window.siyuan.languages._kernel[272])
: window.siyuan.languages.removeCol.replace("${x}", menuElement.querySelector("input").value || window.siyuan.languages._kernel[272])}
<div class="fn__hr--b"></div> <div class="fn__hr--b"></div>
<button class="fn__block b3-button b3-button--remove" data-action="delete">${window.siyuan.languages.delete}</button> <button class="fn__block b3-button b3-button--remove" data-action="delete">${isTwoWay ? window.siyuan.languages.removeBothRelationField : window.siyuan.languages.delete}</button>
<div class="fn__hr"></div> <div class="fn__hr"></div>
<button class="fn__block b3-button b3-button--remove${isTwoWay ? "" : " fn__none"}" data-action="keep-relation">${window.siyuan.languages.removeButKeepRelationField}</button> <button class="fn__block b3-button b3-button--remove${isTwoWay ? "" : " fn__none"}" data-action="keep-relation">${window.siyuan.languages.removeButKeepRelationField}</button>
<div class="fn__hr"></div> <div class="fn__hr"></div>
<button class="fn__block b3-button b3-button--cancel">${window.siyuan.languages.cancel}</button> <button class="fn__block b3-button b3-button--cancel">${window.siyuan.languages.cancel}</button>
</div>`, </div>`,
width: "520px",
}); });
dialog.element.addEventListener("click", (dialogEvent) => { dialog.element.addEventListener("click", (dialogEvent) => {
let target = dialogEvent.target as HTMLElement; let target = dialogEvent.target as HTMLElement;

View file

@ -243,12 +243,13 @@ export const getGroupTitleHTML = (group: IAVView, counter: number) => {
} else { } else {
nameHTML = group.name; nameHTML = group.name;
} }
// av__group-name 为第三方需求,本应用内没有使用,但不能移除 https://github.com/siyuan-note/siyuan/issues/15736
return `<div class="av__group-title"> return `<div class="av__group-title">
<div class="av__group-icon" data-type="av-group-fold" data-id="${group.id}"> <div class="av__group-icon" data-type="av-group-fold" data-id="${group.id}">
<svg class="${group.groupFolded ? "" : "av__group-arrow--open"}"><use xlink:href="#iconRight"></use></svg> <svg class="${group.groupFolded ? "" : "av__group-arrow--open"}"><use xlink:href="#iconRight"></use></svg>
</div> </div>
<span class="fn__space"></span> <span class="fn__space"></span>
${nameHTML} <span class="av__group-name">${nameHTML}</span>
${counter === 0 ? '<span class="fn__space"></span>' : `<span class="av__group-counter">${counter}</span>`} ${counter === 0 ? '<span class="fn__space"></span>' : `<span class="av__group-counter">${counter}</span>`}
<span class="av__group-icon av__group-icon--hover ariaLabel" data-type="av-add-top" data-position="north" aria-label="${window.siyuan.languages.newRow}"><svg><use xlink:href="#iconAdd"></use></svg></span> <span class="av__group-icon av__group-icon--hover ariaLabel" data-type="av-add-top" data-position="north" aria-label="${window.siyuan.languages.newRow}"><svg><use xlink:href="#iconAdd"></use></svg></span>
</div>`; </div>`;
@ -263,7 +264,7 @@ const renderGroupTable = (options: ITableOptions) => {
options.data.view.groups.forEach((group: IAVTable) => { options.data.view.groups.forEach((group: IAVTable) => {
if (group.groupHidden === 0) { if (group.groupHidden === 0) {
avBodyHTML += `${getGroupTitleHTML(group, group.rows.length)} avBodyHTML += `${getGroupTitleHTML(group, group.rows.length)}
<div data-group-id="${group.id}" data-page-size="${group.pageSize}" data-dtype="${group.groupKey.type}" data-content="${group.groupValue.text?.content}" style="float: left" class="av__body${group.groupFolded ? " fn__none" : ""}">${getTableHTMLs(group, options.blockElement)}</div>`; <div data-group-id="${group.id}" data-page-size="${group.pageSize}" data-dtype="${group.groupKey.type}" data-content="${Lute.EscapeHTMLStr(group.groupValue.text?.content)}" style="float: left" class="av__body${group.groupFolded ? " fn__none" : ""}">${getTableHTMLs(group, options.blockElement)}</div>`;
} }
}); });
if (options.renderAll) { if (options.renderAll) {
@ -450,6 +451,7 @@ export const avRender = (element: Element, protyle: IProtyle, cb?: (data: IAV) =
} }
if (avElements.length > 0) { if (avElements.length > 0) {
avElements.forEach((e: HTMLElement) => { avElements.forEach((e: HTMLElement) => {
e.removeAttribute("data-rendering");
if (e.getAttribute("data-render") === "true" || hasClosestByClassName(e, "av__gallery-content")) { if (e.getAttribute("data-render") === "true" || hasClosestByClassName(e, "av__gallery-content")) {
return; return;
} }
@ -783,7 +785,8 @@ export const refreshAV = (protyle: IProtyle, operation: IOperation) => {
} }
} }
if (popCellElement && popCellElement.getAttribute("data-detached") === "true" && if (popCellElement && popCellElement.getAttribute("data-detached") === "true" &&
popCellElement.querySelector(".av__celltext").textContent === "") { popCellElement.querySelector(".av__celltext").textContent === "" &&
popCellElement.getBoundingClientRect().height !== 0) {
popTextCell(protyle, [popCellElement], "block"); popTextCell(protyle, [popCellElement], "block");
} }
} }

View file

@ -633,6 +633,7 @@ export const addColOptionOrCell = (protyle: IProtyle, data: IAV, cellElements: H
transaction(protyle, cellDoOperations, cellUndoOperations); transaction(protyle, cellDoOperations, cellUndoOperations);
} }
if (colData.type === "select") { if (colData.type === "select") {
blockElement.setAttribute("data-rendering", "true");
menuElement.parentElement.dispatchEvent(new CustomEvent("click", {detail: "close"})); menuElement.parentElement.dispatchEvent(new CustomEvent("click", {detail: "close"}));
} else { } else {
const oldScroll = menuElement.querySelector(".b3-menu__items").scrollTop; const oldScroll = menuElement.querySelector(".b3-menu__items").scrollTop;

View file

@ -1232,7 +1232,7 @@ export class Toolbar {
const eventDetail = {languages: hljsLanguages}; const eventDetail = {languages: hljsLanguages};
if (protyle.app && protyle.app.plugins) { if (protyle.app && protyle.app.plugins) {
protyle.app.plugins.forEach((plugin: any) => { protyle.app.plugins.forEach((plugin: any) => {
plugin.eventBus.emit("code-language-before", eventDetail); plugin.eventBus.emit("code-language-update", eventDetail);
}); });
} }
@ -1273,23 +1273,34 @@ export class Toolbar {
let html = ""; let html = "";
// sort // sort
let matchInput = false; let matchInput = false;
matchLanguages.sort((a, b) => { if (lowerCaseValue) {
if (a.startsWith(lowerCaseValue) && b.startsWith(lowerCaseValue)) { matchLanguages.sort((a, b) => {
if (a.length < b.length) { if (a.startsWith(lowerCaseValue) && b.startsWith(lowerCaseValue)) {
if (a.length < b.length) {
return -1;
} else if (a.length === b.length) {
return 0;
} else {
return 1;
}
} else if (a.startsWith(lowerCaseValue)) {
return -1; return -1;
} else if (a.length === b.length) { } else if (b.startsWith(lowerCaseValue)) {
return 0;
} else {
return 1; return 1;
} else {
return 0;
} }
} else if (a.startsWith(lowerCaseValue)) { });
return -1; }
} else if (b.startsWith(lowerCaseValue)) {
return 1; const eventDetail = {languages: matchLanguages};
} else { if (protyle.app && protyle.app.plugins) {
return 0; protyle.app.plugins.forEach((plugin: any) => {
} plugin.eventBus.emit("code-language-update", eventDetail);
}).forEach((item) => { });
}
matchLanguages.forEach((item) => {
if (inputElement.value === item) { if (inputElement.value === item) {
matchInput = true; matchInput = true;
} }

View file

@ -11,11 +11,12 @@ export class Options {
render: { render: {
background: false, background: false,
title: false, title: false,
titleShowTop: false,
hideTitleOnZoom: false,
gutter: true, gutter: true,
scroll: false, scroll: false,
breadcrumb: true, breadcrumb: true,
breadcrumbDocName: false, breadcrumbDocName: false,
hideTitleOnZoom: false,
}, },
action: [], action: [],
after: undefined, after: undefined,

View file

@ -1,6 +1,9 @@
import {focusByRange} from "./selection"; import {focusByRange} from "./selection";
import {fetchPost} from "../../util/fetch"; import {fetchPost, fetchSyncPost} from "../../util/fetch";
import {Constants} from "../../constants"; import {Constants} from "../../constants";
/// #if !BROWSER
import {clipboard} from "electron";
/// #endif
export const encodeBase64 = (text: string): string => { export const encodeBase64 = (text: string): string => {
if (typeof Buffer !== "undefined") { if (typeof Buffer !== "undefined") {
@ -20,24 +23,30 @@ export const encodeBase64 = (text: string): string => {
} }
}; };
const getSiyuanHTML = (text: IClipboardData) => { export const getTextSiyuanFromTextHTML = (html: string) => {
const siyuanMatch = text.textHTML.match(/<!--data-siyuan='([^']+)'-->/); const siyuanMatch = html.match(/<!--data-siyuan='([^']+)'-->/);
let textSiyuan = "";
let textHtml = html;
if (siyuanMatch) { if (siyuanMatch) {
try { try {
if (typeof Buffer !== "undefined") { if (typeof Buffer !== "undefined") {
const decodedBytes = Buffer.from(siyuanMatch[1], "base64"); const decodedBytes = Buffer.from(siyuanMatch[1], "base64");
text.siyuanHTML = decodedBytes.toString("utf8"); textSiyuan = decodedBytes.toString("utf8");
} else { } else {
const decoder = new TextDecoder(); const decoder = new TextDecoder();
const bytes = Uint8Array.from(atob(siyuanMatch[1]), char => char.charCodeAt(0)); const bytes = Uint8Array.from(atob(siyuanMatch[1]), char => char.charCodeAt(0));
text.siyuanHTML = decoder.decode(bytes); textSiyuan = decoder.decode(bytes);
} }
// 移除注释节点,保持原有的 text/html 内容 // 移除注释节点,保持原有的 text/html 内容
text.textHTML = text.textHTML.replace(/<!--data-siyuan='[^']+'-->/, ""); textHtml = html.replace(/<!--data-siyuan='[^']+'-->/, "");
} catch (e) { } catch (e) {
console.log("Failed to decode siyuan data from HTML comment:", e); console.log("Failed to decode siyuan data from HTML comment:", e);
} }
} }
return {
textSiyuan,
textHtml
};
}; };
export const openByMobile = (uri: string) => { export const openByMobile = (uri: string) => {
@ -92,6 +101,27 @@ export const readText = () => {
return navigator.clipboard.readText(); return navigator.clipboard.readText();
}; };
/// #if !BROWSER
export const getLocalFiles = async () => {
// 不再支持 PC 浏览器 https://github.com/siyuan-note/siyuan/issues/7206
let localFiles: string[] = [];
if ("darwin" === window.siyuan.config.system.os) {
const xmlString = clipboard.read("NSFilenamesPboardType");
const domParser = new DOMParser();
const xmlDom = domParser.parseFromString(xmlString, "application/xml");
Array.from(xmlDom.getElementsByTagName("string")).forEach(item => {
localFiles.push(item.childNodes[0].nodeValue);
});
} else {
const xmlString = await fetchSyncPost("/api/clipboard/readFilePaths", {});
if (xmlString.data.length > 0) {
localFiles = xmlString.data;
}
}
return localFiles;
};
/// #endif
export const readClipboard = async () => { export const readClipboard = async () => {
const text: IClipboardData = {textPlain: "", textHTML: "", siyuanHTML: ""}; const text: IClipboardData = {textPlain: "", textHTML: "", siyuanHTML: ""};
try { try {
@ -100,7 +130,9 @@ export const readClipboard = async () => {
if (item.types.includes("text/html")) { if (item.types.includes("text/html")) {
const blob = await item.getType("text/html"); const blob = await item.getType("text/html");
text.textHTML = await blob.text(); text.textHTML = await blob.text();
getSiyuanHTML(text); const textObj = getTextSiyuanFromTextHTML(text.textHTML);
text.textHTML = textObj.textHtml;
text.siyuanHTML = textObj.textSiyuan;
} }
if (item.types.includes("text/plain")) { if (item.types.includes("text/plain")) {
const blob = await item.getType("text/plain"); const blob = await item.getType("text/plain");
@ -111,16 +143,25 @@ export const readClipboard = async () => {
text.files = [new File([blob], "image.png", {type: "image/png", lastModified: Date.now()})]; text.files = [new File([blob], "image.png", {type: "image/png", lastModified: Date.now()})];
} }
} }
/// #if !BROWSER
if (!text.textHTML && !text.files) {
text.localFiles = await getLocalFiles();
}
/// #endif
return text; return text;
} catch (e) { } catch (e) {
if (isInAndroid()) { if (isInAndroid()) {
text.textPlain = window.JSAndroid.readClipboard(); text.textPlain = window.JSAndroid.readClipboard();
text.textHTML = window.JSAndroid.readHTMLClipboard(); text.textHTML = window.JSAndroid.readHTMLClipboard();
getSiyuanHTML(text); const textObj = getTextSiyuanFromTextHTML(text.textHTML);
text.textHTML = textObj.textHtml;
text.siyuanHTML = textObj.textSiyuan;
} else if (isInHarmony()) { } else if (isInHarmony()) {
text.textPlain = window.JSHarmony.readClipboard(); text.textPlain = window.JSHarmony.readClipboard();
text.textHTML = window.JSHarmony.readHTMLClipboard(); text.textHTML = window.JSHarmony.readHTMLClipboard();
getSiyuanHTML(text); const textObj = getTextSiyuanFromTextHTML(text.textHTML);
text.textHTML = textObj.textHtml;
text.siyuanHTML = textObj.textSiyuan;
} }
return text; return text;
} }

View file

@ -1418,6 +1418,7 @@ export const dropEvent = (protyle: IProtyle, editorElement: HTMLElement) => {
targetElement.classList.remove("dragover__bottom", "dragover__top", "dragover__left", "dragover__right"); targetElement.classList.remove("dragover__bottom", "dragover__top", "dragover__left", "dragover__right");
} }
} else if (!window.siyuan.dragElement && (event.dataTransfer.types[0] === "Files" || event.dataTransfer.types.includes("text/html"))) { } else if (!window.siyuan.dragElement && (event.dataTransfer.types[0] === "Files" || event.dataTransfer.types.includes("text/html"))) {
event.preventDefault();
// 外部文件拖入编辑器中或者编辑器内选中文字拖拽 // 外部文件拖入编辑器中或者编辑器内选中文字拖拽
// https://github.com/siyuan-note/siyuan/issues/9544 // https://github.com/siyuan-note/siyuan/issues/9544
const avElement = hasClosestByClassName(event.target, "av"); const avElement = hasClosestByClassName(event.target, "av");

View file

@ -446,12 +446,33 @@ export const insertHTML = (html: string, protyle: IProtyle, isBlock = false,
insertBefore = true; insertBefore = true;
} }
} }
(insertBefore ? Array.from(tempElement.content.children) : Array.from(tempElement.content.children).reverse()).forEach((item) => { // https://github.com/siyuan-note/siyuan/issues/15768
// https://github.com/siyuan-note/siyuan/issues/13232 if (tempElement.content.firstChild.nodeType === 3 || (tempElement.content.firstChild.nodeType === 1 && tempElement.content.firstElementChild.tagName !== "DIV")) {
if (item.getAttribute("data-type") === "NodeHeading" && item.getAttribute("fold") === "1") { tempElement.innerHTML = protyle.lute.SpinBlockDOM(tempElement.innerHTML);
item.removeAttribute("fold"); }
} // let foldHeadingId = "";
// let foldHTML = "";
// 粘贴内容中包含折叠的子节点需后端插入到原节点中
// Array.from(tempElement.content.children).forEach((item) => {
// if (!item.getAttribute("parent-heading") && foldHeadingId && foldHTML) {
// fetchPost("/api/block/appendHeadingChildren", {id: foldHeadingId, dom: foldHTML});
// foldHeadingId = "";
// foldHTML = "";
// }
// if (item.getAttribute("data-type") === "NodeHeading" && item.getAttribute("fold") === "1") {
// foldHeadingId = item.getAttribute("data-node-id");
// return true;
// }
// if (foldHeadingId && item.getAttribute("parent-heading")) {
// foldHTML += item.outerHTML;
// }
// });
// if (foldHeadingId && foldHTML) {
// fetchPost("/api/block/appendHeadingChildren", {id: foldHeadingId, dom: foldHTML});
// }
(insertBefore ? Array.from(tempElement.content.children) : Array.from(tempElement.content.children).reverse()).find((item) => {
let addId = item.getAttribute("data-node-id"); let addId = item.getAttribute("data-node-id");
const hasParentHeading = item.getAttribute("parent-heading");
if (addId === id) { if (addId === id) {
doOperation.push({ doOperation.push({
action: "update", action: "update",
@ -476,10 +497,12 @@ export const insertHTML = (html: string, protyle: IProtyle, isBlock = false,
liElement.append(item); liElement.append(item);
item = liElement; item = liElement;
} }
item.removeAttribute("parent-heading");
doOperation.push({ doOperation.push({
action: "insert", action: "insert",
data: item.outerHTML, data: item.outerHTML,
id: addId, id: addId,
context: {ignoreProcess: hasParentHeading ? "true" : "false"},
nextID: insertBefore ? id : undefined, nextID: insertBefore ? id : undefined,
previousID: insertBefore ? undefined : id previousID: insertBefore ? undefined : id
}); });
@ -488,10 +511,12 @@ export const insertHTML = (html: string, protyle: IProtyle, isBlock = false,
id: addId, id: addId,
}); });
} }
if (insertBefore) { if (!hasParentHeading) {
blockElement.before(item); if (insertBefore) {
} else { blockElement.before(item);
blockElement.after(item); } else {
blockElement.after(item);
}
} }
if (!lastElement) { if (!lastElement) {
lastElement = item; lastElement = item;

View file

@ -1,15 +1,12 @@
import {Constants} from "../../constants"; import {Constants} from "../../constants";
import {uploadFiles, uploadLocalFiles} from "../upload"; import {uploadFiles, uploadLocalFiles} from "../upload";
import {processPasteCode, processRender} from "./processCode"; import {processPasteCode, processRender} from "./processCode";
import {readText} from "./compatibility"; import {getLocalFiles, getTextSiyuanFromTextHTML, readText} from "./compatibility";
/// #if !BROWSER
import {clipboard} from "electron";
/// #endif
import {hasClosestBlock, hasClosestByAttribute, hasClosestByClassName} from "./hasClosest"; import {hasClosestBlock, hasClosestByAttribute, hasClosestByClassName} from "./hasClosest";
import {getEditorRange} from "./selection"; import {getEditorRange} from "./selection";
import {blockRender} from "../render/blockRender"; import {blockRender} from "../render/blockRender";
import {highlightRender} from "../render/highlightRender"; import {highlightRender} from "../render/highlightRender";
import {fetchPost, fetchSyncPost} from "../../util/fetch"; import {fetchPost} from "../../util/fetch";
import {isDynamicRef, isFileAnnotation} from "../../util/functions"; import {isDynamicRef, isFileAnnotation} from "../../util/functions";
import {insertHTML} from "./insertHTML"; import {insertHTML} from "./insertHTML";
import {scrollCenter} from "../../util/highlightById"; import {scrollCenter} from "../../util/highlightById";
@ -145,19 +142,7 @@ export const pasteEscaped = async (protyle: IProtyle, nodeElement: Element) => {
export const pasteAsPlainText = async (protyle: IProtyle) => { export const pasteAsPlainText = async (protyle: IProtyle) => {
let localFiles: string[] = []; let localFiles: string[] = [];
/// #if !BROWSER /// #if !BROWSER
if ("darwin" === window.siyuan.config.system.os) { localFiles = await getLocalFiles();
const xmlString = clipboard.read("NSFilenamesPboardType");
const domParser = new DOMParser();
const xmlDom = domParser.parseFromString(xmlString, "application/xml");
Array.from(xmlDom.getElementsByTagName("string")).forEach(item => {
localFiles.push(item.childNodes[0].nodeValue);
});
} else {
const xmlString = await fetchSyncPost("/api/clipboard/readFilePaths", {});
if (xmlString.data.length > 0) {
localFiles = xmlString.data;
}
}
if (localFiles.length > 0) { if (localFiles.length > 0) {
uploadLocalFiles(localFiles, protyle, false); uploadLocalFiles(localFiles, protyle, false);
return; return;
@ -269,6 +254,10 @@ export const paste = async (protyle: IProtyle, event: (ClipboardEvent | DragEven
files = event.dataTransfer.items; files = event.dataTransfer.items;
} }
} else { } else {
if (event.localFiles?.length > 0) {
readLocalFile(protyle, event.localFiles);
return;
}
textHTML = event.textHTML; textHTML = event.textHTML;
textPlain = event.textPlain; textPlain = event.textPlain;
siyuanHTML = event.siyuanHTML; siyuanHTML = event.siyuanHTML;
@ -279,26 +268,11 @@ export const paste = async (protyle: IProtyle, event: (ClipboardEvent | DragEven
textPlain = textPlain.replace(/\r\n|\r|\u2028|\u2029/g, "\n"); textPlain = textPlain.replace(/\r\n|\r|\u2028|\u2029/g, "\n");
/// #if !BROWSER /// #if !BROWSER
// 不再支持 PC 浏览器 https://github.com/siyuan-note/siyuan/issues/7206
if (!siyuanHTML && !textHTML && !textPlain && ("clipboardData" in event)) { if (!siyuanHTML && !textHTML && !textPlain && ("clipboardData" in event)) {
if ("darwin" === window.siyuan.config.system.os) { const localFiles: string[] = await getLocalFiles();
const xmlString = clipboard.read("NSFilenamesPboardType"); if (localFiles.length > 0) {
const domParser = new DOMParser(); readLocalFile(protyle, localFiles);
const xmlDom = domParser.parseFromString(xmlString, "application/xml"); return;
const localFiles: string[] = [];
Array.from(xmlDom.getElementsByTagName("string")).forEach(item => {
localFiles.push(item.childNodes[0].nodeValue);
});
if (localFiles.length > 0) {
readLocalFile(protyle, localFiles);
return;
}
} else {
const xmlString = await fetchSyncPost("/api/clipboard/readFilePaths", {});
if (xmlString.data.length > 0) {
readLocalFile(protyle, xmlString.data);
return;
}
} }
} }
/// #endif /// #endif
@ -314,6 +288,12 @@ export const paste = async (protyle: IProtyle, event: (ClipboardEvent | DragEven
if (textPlain.endsWith(Constants.ZWSP) && !textHTML && !siyuanHTML) { if (textPlain.endsWith(Constants.ZWSP) && !textHTML && !siyuanHTML) {
siyuanHTML = textPlain.substr(0, textPlain.length - 1); siyuanHTML = textPlain.substr(0, textPlain.length - 1);
} }
// 复制/剪切折叠标题需获取 siyuanHTML
if (textHTML && textPlain && !siyuanHTML) {
const textObj = getTextSiyuanFromTextHTML(textHTML);
siyuanHTML = textObj.textSiyuan;
textHTML = textObj.textHtml;
}
// 剪切复制中首位包含空格或仅有空格 https://github.com/siyuan-note/siyuan/issues/5667 // 剪切复制中首位包含空格或仅有空格 https://github.com/siyuan-note/siyuan/issues/5667
if (!siyuanHTML) { if (!siyuanHTML) {
// process word // process word
@ -406,10 +386,13 @@ export const paste = async (protyle: IProtyle, event: (ClipboardEvent | DragEven
} }
if (types.includes("block-ref")) { if (types.includes("block-ref")) {
protyle.toolbar.setInlineMark(protyle, "block-ref", "range", { const refElement = protyle.toolbar.setInlineMark(protyle, "block-ref", "range", {
type: "id", type: "id",
color: `${linkElement.dataset.id}${Constants.ZWSP}s${Constants.ZWSP}${range.toString()}` color: `${linkElement.dataset.id}${Constants.ZWSP}s${Constants.ZWSP}${range.toString()}`
}); });
if (refElement[0]) {
protyle.toolbar.range.selectNodeContents(refElement[0]);
}
return; return;
} }
if (types.includes("a")) { if (types.includes("a")) {
@ -528,11 +511,15 @@ export const paste = async (protyle: IProtyle, event: (ClipboardEvent | DragEven
} }
if (linkElement) { if (linkElement) {
const selectText = range.toString(); const selectText = range.toString();
protyle.toolbar.setInlineMark(protyle, "a", "range", { const aElements = protyle.toolbar.setInlineMark(protyle, "a", "range", {
type: "a", type: "a",
color: `${linkElement.getAttribute("href")}${Constants.ZWSP}${selectText || linkElement.textContent}` color: `${linkElement.getAttribute("href")}${Constants.ZWSP}${selectText || linkElement.textContent}`
}); });
if (!selectText) { if (!selectText) {
if (aElements[0].lastChild) {
// https://github.com/siyuan-note/siyuan/issues/15801
range.setEnd(aElements[0].lastChild, aElements[0].lastChild.textContent.length);
}
range.collapse(false); range.collapse(false);
} }
return; return;
@ -562,11 +549,14 @@ export const paste = async (protyle: IProtyle, event: (ClipboardEvent | DragEven
if (range.toString() !== "") { if (range.toString() !== "") {
const firstLine = textPlain.split("\n")[0]; const firstLine = textPlain.split("\n")[0];
if (isDynamicRef(textPlain)) { if (isDynamicRef(textPlain)) {
protyle.toolbar.setInlineMark(protyle, "block-ref", "range", { const refElement = protyle.toolbar.setInlineMark(protyle, "block-ref", "range", {
type: "id", type: "id",
// range 不能 escape否则 https://github.com/siyuan-note/siyuan/issues/8359 // range 不能 escape否则 https://github.com/siyuan-note/siyuan/issues/8359
color: `${textPlain.substring(2, 22 + 2)}${Constants.ZWSP}s${Constants.ZWSP}${range.toString()}` color: `${textPlain.substring(2, 22 + 2)}${Constants.ZWSP}s${Constants.ZWSP}${range.toString()}`
}); });
if (refElement[0]) {
protyle.toolbar.range.selectNodeContents(refElement[0]);
}
return; return;
} else if (isFileAnnotation(firstLine)) { } else if (isFileAnnotation(firstLine)) {
protyle.toolbar.setInlineMark(protyle, "file-annotation-ref", "range", { protyle.toolbar.setInlineMark(protyle, "file-annotation-ref", "range", {

View file

@ -68,7 +68,7 @@ import {popSearch} from "../../mobile/menu/search";
import {BlockPanel} from "../../block/Panel"; import {BlockPanel} from "../../block/Panel";
import {copyPlainText, isInIOS, isMac, isOnlyMeta, readClipboard, encodeBase64} from "../util/compatibility"; import {copyPlainText, isInIOS, isMac, isOnlyMeta, readClipboard, encodeBase64} from "../util/compatibility";
import {MenuItem} from "../../menus/Menu"; import {MenuItem} from "../../menus/Menu";
import {fetchPost} from "../../util/fetch"; import {fetchPost, fetchSyncPost} from "../../util/fetch";
import {onGet} from "../util/onGet"; import {onGet} from "../util/onGet";
import {clearTableCell, isIncludeCell, setTableAlign} from "../util/table"; import {clearTableCell, isIncludeCell, setTableAlign} from "../util/table";
import {countBlockWord, countSelectWord} from "../../layout/status"; import {countBlockWord, countSelectWord} from "../../layout/status";
@ -256,7 +256,7 @@ export class WYSIWYG {
} }
private bindCommonEvent(protyle: IProtyle) { private bindCommonEvent(protyle: IProtyle) {
this.element.addEventListener("copy", (event: ClipboardEvent & { target: HTMLElement }) => { this.element.addEventListener("copy", async (event: ClipboardEvent & { target: HTMLElement }) => {
window.siyuan.ctrlIsPressed = false; // https://github.com/siyuan-note/siyuan/issues/6373 window.siyuan.ctrlIsPressed = false; // https://github.com/siyuan-note/siyuan/issues/6373
// https://github.com/siyuan-note/siyuan/issues/4600 // https://github.com/siyuan-note/siyuan/issues/4600
if (event.target.tagName === "PROTYLE-HTML" || event.target.localName === "input") { if (event.target.tagName === "PROTYLE-HTML" || event.target.localName === "input") {
@ -282,6 +282,8 @@ export class WYSIWYG {
} }
let html = ""; let html = "";
let textPlain = ""; let textPlain = "";
let isInCodeBlock = false;
let needClipboardWrite = false;
if (selectElements.length > 0) { if (selectElements.length > 0) {
const isRefText = selectElements[0].getAttribute("data-reftext") === "true"; const isRefText = selectElements[0].getAttribute("data-reftext") === "true";
if (selectElements[0].getAttribute("data-type") === "NodeListItem" && if (selectElements[0].getAttribute("data-type") === "NodeListItem" &&
@ -293,14 +295,24 @@ export class WYSIWYG {
html = selectElements[0].parentElement.outerHTML; html = selectElements[0].parentElement.outerHTML;
} }
} else { } else {
selectElements.forEach((item: HTMLElement, index) => { for (let i = 0; i < selectElements.length; i++) {
const item = selectElements[i] as HTMLElement;
// 复制列表项中的块会变为复制列表项,因此不能使用 getTopAloneElement https://github.com/siyuan-note/siyuan/issues/8925 // 复制列表项中的块会变为复制列表项,因此不能使用 getTopAloneElement https://github.com/siyuan-note/siyuan/issues/8925
if (isRefText && index === 0) { if (isRefText && i === 0) {
html += getTextStar(item) + "\n\n"; html += getTextStar(item) + "\n\n";
} else { } else {
html += removeEmbed(item); if (item.getAttribute("data-type") === "NodeHeading" && item.getAttribute("fold") === "1") {
needClipboardWrite = true;
const response = await fetchSyncPost("/api/block/getHeadingChildrenDOM", {
id: item.getAttribute("data-node-id"),
removeFoldAttr: false
});
html += response.data;
} else {
html += removeEmbed(item);
}
} }
}); }
} }
if (isRefText) { if (isRefText) {
selectElements[0].removeAttribute("data-reftext"); selectElements[0].removeAttribute("data-reftext");
@ -380,6 +392,8 @@ export class WYSIWYG {
if (matchHeading) { if (matchHeading) {
// 复制标题 https://github.com/siyuan-note/insider/issues/297 // 复制标题 https://github.com/siyuan-note/insider/issues/297
tempElement.append(headingElement.cloneNode(true)); tempElement.append(headingElement.cloneNode(true));
// https://github.com/siyuan-note/siyuan/issues/13232
headingElement.removeAttribute("fold");
} else if (!["DIV", "TD", "TH", "TR"].includes(range.startContainer.parentElement.tagName)) { } else if (!["DIV", "TD", "TH", "TR"].includes(range.startContainer.parentElement.tagName)) {
// 复制行内元素 https://github.com/siyuan-note/insider/issues/191 // 复制行内元素 https://github.com/siyuan-note/insider/issues/191
tempElement.append(range.startContainer.parentElement.cloneNode(true)); tempElement.append(range.startContainer.parentElement.cloneNode(true));
@ -427,7 +441,7 @@ export class WYSIWYG {
if (isEndOfBlock(range)) { if (isEndOfBlock(range)) {
textPlain = textPlain.replace(/\n$/, ""); textPlain = textPlain.replace(/\n$/, "");
} }
html = textPlain; isInCodeBlock = true;
} else if (hasClosestByTag(range.startContainer, "TD") || hasClosestByTag(range.startContainer, "TH")) { } else if (hasClosestByTag(range.startContainer, "TD") || hasClosestByTag(range.startContainer, "TH")) {
tempElement.innerHTML = tempElement.innerHTML.replace(/<br>/g, "\n").replace(/<br\/>/g, "\n"); tempElement.innerHTML = tempElement.innerHTML.replace(/<br>/g, "\n").replace(/<br\/>/g, "\n");
textPlain = tempElement.textContent.endsWith("\n") ? tempElement.textContent.replace(/\n$/, "") : tempElement.textContent; textPlain = tempElement.textContent.endsWith("\n") ? tempElement.textContent.replace(/\n$/, "") : tempElement.textContent;
@ -445,14 +459,25 @@ export class WYSIWYG {
.replace(new RegExp(Constants.ZWSP, "g"), ""); .replace(new RegExp(Constants.ZWSP, "g"), "");
event.clipboardData.setData("text/plain", textPlain); event.clipboardData.setData("text/plain", textPlain);
// 设置 text/siyuan 数据 if (!isInCodeBlock) {
enableLuteMarkdownSyntax(protyle); enableLuteMarkdownSyntax(protyle);
const siyuanHTML = selectTableElement ? protyle.lute.HTML2BlockDOM(html) : html; const textSiyuan = selectTableElement ? protyle.lute.HTML2BlockDOM(html) : html;
event.clipboardData.setData("text/siyuan", siyuanHTML); event.clipboardData.setData("text/siyuan", textSiyuan);
restoreLuteMarkdownSyntax(protyle); restoreLuteMarkdownSyntax(protyle);
// 在 text/html 中插入注释节点,用于右键菜单粘贴时获取 text/siyuan 数据
// 在 text/html 中插入注释节点,用于右键菜单粘贴时获取 text/siyuan 数据 const textHTML = `<!--data-siyuan='${encodeBase64(textSiyuan)}'-->` + (selectTableElement ? html : protyle.lute.BlockDOM2HTML(selectAVElement ? textPlain : html));
event.clipboardData.setData("text/html", `<!--data-siyuan='${encodeBase64(siyuanHTML)}'-->` + (selectTableElement ? html : protyle.lute.BlockDOM2HTML(selectAVElement ? textPlain : html))); event.clipboardData.setData("text/html", textHTML);
if (needClipboardWrite) {
try {
await navigator.clipboard.write([new ClipboardItem({
["text/plain"]: textPlain,
["text/html"]: textHTML,
})]);
} catch (e) {
console.log("Copy write clipboard error:", e);
}
}
}
}); });
this.element.addEventListener("mousedown", (event: MouseEvent) => { this.element.addEventListener("mousedown", (event: MouseEvent) => {
@ -1720,7 +1745,7 @@ export class WYSIWYG {
} }
}); });
this.element.addEventListener("cut", (event: ClipboardEvent & { target: HTMLElement }) => { this.element.addEventListener("cut", async (event: ClipboardEvent & { target: HTMLElement }) => {
window.siyuan.ctrlIsPressed = false; // https://github.com/siyuan-note/siyuan/issues/6373 window.siyuan.ctrlIsPressed = false; // https://github.com/siyuan-note/siyuan/issues/6373
if (protyle.disabled) { if (protyle.disabled) {
return; return;
@ -1758,20 +1783,28 @@ export class WYSIWYG {
} }
let html = ""; let html = "";
let textPlain = ""; let textPlain = "";
let isInCodeBlock = false;
let needClipboardWrite = false;
if (selectElements.length > 0) { if (selectElements.length > 0) {
if (selectElements[0].getAttribute("data-type") === "NodeListItem" && if (selectElements[0].getAttribute("data-type") === "NodeListItem" &&
selectElements[0].parentElement.classList.contains("list") && // 反链复制列表项 https://github.com/siyuan-note/siyuan/issues/6555 selectElements[0].parentElement.classList.contains("list") && // 反链复制列表项 https://github.com/siyuan-note/siyuan/issues/6555
selectElements[0].parentElement.childElementCount - 1 === selectElements.length) { selectElements[0].parentElement.childElementCount - 1 === selectElements.length) {
html = selectElements[0].parentElement.outerHTML; html = selectElements[0].parentElement.outerHTML;
} else { } else {
selectElements.forEach(item => { for (let i = 0; i < selectElements.length; i++) {
const item = selectElements[i];
const topElement = getTopAloneElement(item); const topElement = getTopAloneElement(item);
if (item.getAttribute("data-type") === "NodeHeading" && item.getAttribute("fold") === "1") { if (item.getAttribute("data-type") === "NodeHeading" && item.getAttribute("fold") === "1") {
html += removeEmbed(topElement).replace('fold="1"', ""); needClipboardWrite = true;
const response = await fetchSyncPost("/api/block/getHeadingChildrenDOM", {
id: item.getAttribute("data-node-id"),
removeFoldAttr: false
});
html += response.data;
} else { } else {
html += removeEmbed(topElement); html += removeEmbed(topElement);
} }
}); }
if (selectElements[0].getAttribute("data-type") === "NodeListItem") { if (selectElements[0].getAttribute("data-type") === "NodeListItem") {
html = `<div data-subtype="${selectElements[0].getAttribute("data-subtype")}" data-node-id="${Lute.NewNodeID()}" data-type="NodeList" class="list">${html}<div class="protyle-attr" contenteditable="false">${Constants.ZWSP}</div></div>`; html = `<div data-subtype="${selectElements[0].getAttribute("data-subtype")}" data-node-id="${Lute.NewNodeID()}" data-type="NodeList" class="list">${html}<div class="protyle-attr" contenteditable="false">${Constants.ZWSP}</div></div>`;
} }
@ -1919,6 +1952,7 @@ export class WYSIWYG {
if (hasClosestByAttribute(range.startContainer, "data-type", "NodeCodeBlock") || if (hasClosestByAttribute(range.startContainer, "data-type", "NodeCodeBlock") ||
hasClosestByTag(range.startContainer, "CODE")) { hasClosestByTag(range.startContainer, "CODE")) {
textPlain = tempElement.textContent.replace(Constants.ZWSP, ""); textPlain = tempElement.textContent.replace(Constants.ZWSP, "");
isInCodeBlock = true;
} }
// https://github.com/siyuan-note/siyuan/issues/4321 // https://github.com/siyuan-note/siyuan/issues/4321
if (!nodeElement.classList.contains("table")) { if (!nodeElement.classList.contains("table")) {
@ -1950,14 +1984,25 @@ export class WYSIWYG {
textPlain = textPlain.replace(/\u00A0/g, " "); // Replace non-breaking spaces with normal spaces when copying https://github.com/siyuan-note/siyuan/issues/9382 textPlain = textPlain.replace(/\u00A0/g, " "); // Replace non-breaking spaces with normal spaces when copying https://github.com/siyuan-note/siyuan/issues/9382
event.clipboardData.setData("text/plain", textPlain); event.clipboardData.setData("text/plain", textPlain);
// 设置 text/siyuan 数据 if (!isInCodeBlock) {
enableLuteMarkdownSyntax(protyle); enableLuteMarkdownSyntax(protyle);
const siyuanHTML = selectTableElement ? protyle.lute.HTML2BlockDOM(html) : html; const textSiyuan = selectTableElement ? protyle.lute.HTML2BlockDOM(html) : html;
event.clipboardData.setData("text/siyuan", siyuanHTML); restoreLuteMarkdownSyntax(protyle);
restoreLuteMarkdownSyntax(protyle); event.clipboardData.setData("text/siyuan", textSiyuan);
// 在 text/html 中插入注释节点,用于右键菜单粘贴时获取 text/siyuan 数据
// 在 text/html 中插入注释节点,用于右键菜单粘贴时获取 text/siyuan 数据 const textHTML = `<!--data-siyuan='${encodeBase64(textSiyuan)}'-->` + (selectTableElement ? html : protyle.lute.BlockDOM2HTML(selectAVElement ? textPlain : html));
event.clipboardData.setData("text/html", `<!--data-siyuan='${encodeBase64(siyuanHTML)}'-->` + (selectTableElement ? html : protyle.lute.BlockDOM2HTML(selectAVElement ? textPlain : html))); event.clipboardData.setData("text/html", textHTML);
if (needClipboardWrite) {
try {
await navigator.clipboard.write([new ClipboardItem({
["text/plain"]: textPlain,
["text/html"]: textHTML,
})]);
} catch (e) {
console.log("Cut write clipboard error:", e);
}
}
}
}); });
let beforeContextmenuRange: Range; let beforeContextmenuRange: Range;

View file

@ -37,6 +37,10 @@ export const input = async (protyle: IProtyle, blockElement: HTMLElement, range:
} else if (type === "NodeBlockQueryEmbed") { } else if (type === "NodeBlockQueryEmbed") {
blockElement.lastElementChild.previousElementSibling.innerHTML = "<wbr>" + Constants.ZWSP; blockElement.lastElementChild.previousElementSibling.innerHTML = "<wbr>" + Constants.ZWSP;
} else if (type === "NodeMathBlock" || type === "NodeHTMLBlock") { } else if (type === "NodeMathBlock" || type === "NodeHTMLBlock") {
// https://github.com/siyuan-note/siyuan/issues/15761
if (blockElement.firstElementChild.firstChild.nodeType === 3) {
blockElement.firstElementChild.firstChild.remove();
}
blockElement.lastElementChild.previousElementSibling.lastElementChild.innerHTML = "<wbr>" + Constants.ZWSP; blockElement.lastElementChild.previousElementSibling.lastElementChild.innerHTML = "<wbr>" + Constants.ZWSP;
} else if (type === "NodeIFrame" || type === "NodeWidget") { } else if (type === "NodeIFrame" || type === "NodeWidget") {
blockElement.innerHTML = "<wbr>" + blockElement.firstElementChild.outerHTML + blockElement.lastElementChild.outerHTML; blockElement.innerHTML = "<wbr>" + blockElement.firstElementChild.outerHTML + blockElement.lastElementChild.outerHTML;

View file

@ -855,15 +855,16 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => {
const cloneRange = range.cloneRange(); const cloneRange = range.cloneRange();
const nextElement = getNextBlock(getTopAloneElement(nodeElement)); const nextElement = getNextBlock(getTopAloneElement(nodeElement));
if (nextElement) { if (nextElement) {
if (!nodeElement.classList.contains("code-block")) { const nextRange = focusBlock(nextElement);
const nextRange = focusBlock(nextElement); if (nextRange) {
if (nextRange) { const nextBlockElement = hasClosestBlock(nextRange.startContainer);
const nextBlockElement = hasClosestBlock(nextRange.startContainer); if (nextBlockElement &&
if (nextBlockElement) { (!nextBlockElement.classList.contains("code-block") ||
// 反向删除合并为一个块时,光标应保持在尾部 https://github.com/siyuan-note/siyuan/issues/14290#issuecomment-2849810529 (nextBlockElement.classList.contains("code-block") && getContenteditableElement(nextBlockElement).textContent == "\n"))
cloneRange.insertNode(document.createElement("wbr")); ) {
removeBlock(protyle, nextBlockElement, nextRange, "Delete"); // 反向删除合并为一个块时,光标应保持在尾部 https://github.com/siyuan-note/siyuan/issues/14290#issuecomment-2849810529
} cloneRange.insertNode(document.createElement("wbr"));
removeBlock(protyle, nextBlockElement, nextRange, "Delete");
} }
} }
event.stopPropagation(); event.stopPropagation();
@ -912,7 +913,9 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => {
// 需使用 textContent文本元素没有 innerText // 需使用 textContent文本元素没有 innerText
currentNode.textContent === "") // https://ld246.com/article/1649251218696 currentNode.textContent === "") // https://ld246.com/article/1649251218696
)) { )) {
if (!nodeElement.classList.contains("code-block")) { if (!nodeElement.classList.contains("code-block") ||
(nodeElement.classList.contains("code-block") && editElement.textContent == "\n")
) {
removeBlock(protyle, nodeElement, range, "Backspace"); removeBlock(protyle, nodeElement, range, "Backspace");
} }
event.stopPropagation(); event.stopPropagation();

View file

@ -12,7 +12,7 @@ import {
import {transaction, turnsIntoOneTransaction, turnsIntoTransaction, updateTransaction} from "./transaction"; import {transaction, turnsIntoOneTransaction, turnsIntoTransaction, updateTransaction} from "./transaction";
import {cancelSB, genEmptyElement} from "../../block/util"; import {cancelSB, genEmptyElement} from "../../block/util";
import {listOutdent, updateListOrder} from "./list"; import {listOutdent, updateListOrder} from "./list";
import {setFold, zoomOut} from "../../menus/protyle"; import {zoomOut} from "../../menus/protyle";
import {preventScroll} from "../scroll/preventScroll"; import {preventScroll} from "../scroll/preventScroll";
import {hideElements} from "../ui/hideElements"; import {hideElements} from "../ui/hideElements";
import {Constants} from "../../constants"; import {Constants} from "../../constants";
@ -23,6 +23,7 @@ import {hasClosestByClassName} from "../util/hasClosest";
import {getInstanceById} from "../../layout/util"; import {getInstanceById} from "../../layout/util";
import {Tab} from "../../layout/Tab"; import {Tab} from "../../layout/Tab";
import {Backlink} from "../../layout/dock/Backlink"; import {Backlink} from "../../layout/dock/Backlink";
import {fetchSyncPost} from "../../util/fetch";
export const removeBlock = async (protyle: IProtyle, blockElement: Element, range: Range, type: "Delete" | "Backspace" | "remove") => { export const removeBlock = async (protyle: IProtyle, blockElement: Element, range: Range, type: "Delete" | "Backspace" | "remove") => {
protyle.observerLoad?.disconnect(); protyle.observerLoad?.disconnect();
@ -32,7 +33,7 @@ export const removeBlock = async (protyle: IProtyle, blockElement: Element, rang
if (selectElements?.length > 0) { if (selectElements?.length > 0) {
const deletes: IOperation[] = []; const deletes: IOperation[] = [];
const inserts: IOperation[] = []; const inserts: IOperation[] = [];
let sideElement; let sideElement: Element | boolean;
let sideIsNext = false; let sideIsNext = false;
if (type === "Backspace") { if (type === "Backspace") {
sideElement = selectElements[0].previousElementSibling; sideElement = selectElements[0].previousElementSibling;
@ -52,7 +53,8 @@ export const removeBlock = async (protyle: IProtyle, blockElement: Element, rang
let topParentElement: Element; let topParentElement: Element;
hideElements(["select"], protyle); hideElements(["select"], protyle);
let foldPreviousId: string; let foldPreviousId: string;
selectElements.find((item: HTMLElement) => { for (let i = 0; i < selectElements.length; i++) {
const item = selectElements[i];
const topElement = getTopAloneElement(item); const topElement = getTopAloneElement(item);
topParentElement = topElement.parentElement; topParentElement = topElement.parentElement;
const id = topElement.getAttribute("data-node-id"); const id = topElement.getAttribute("data-node-id");
@ -79,19 +81,23 @@ export const removeBlock = async (protyle: IProtyle, blockElement: Element, rang
sideIsNext = false; sideIsNext = false;
} }
if (topElement.getAttribute("data-type") === "NodeHeading" && topElement.getAttribute("fold") === "1") { if (topElement.getAttribute("data-type") === "NodeHeading" && topElement.getAttribute("fold") === "1") {
// https://github.com/siyuan-note/siyuan/issues/2188 const foldTransaction = await fetchSyncPost("/api/block/getHeadingDeleteTransaction", {
setFold(protyle, topElement, undefined, true); id: topElement.getAttribute("data-node-id"),
});
deletes.push(...foldTransaction.data.doOperations.slice(1));
let previousID = topElement.previousElementSibling ? topElement.previousElementSibling.getAttribute("data-node-id") : ""; let previousID = topElement.previousElementSibling ? topElement.previousElementSibling.getAttribute("data-node-id") : "";
if (typeof foldPreviousId !== "undefined") { if (typeof foldPreviousId !== "undefined") {
previousID = foldPreviousId; previousID = foldPreviousId;
} }
inserts.push({ foldTransaction.data.undoOperations.forEach((operationItem: IOperation, index: number) => {
action: "insert", operationItem.previousID = previousID;
data: topElement.outerHTML, if (index > 0) {
id, operationItem.context = {
previousID: previousID, ignoreProcess: "true"
parentID: topElement.parentElement.getAttribute("data-node-id") || protyle.block.parentID };
}
}); });
inserts.push(...foldTransaction.data.undoOperations);
// 折叠块和非折叠块同时删除时撤销异常 https://github.com/siyuan-note/siyuan/issues/11312 // 折叠块和非折叠块同时删除时撤销异常 https://github.com/siyuan-note/siyuan/issues/11312
let foldPreviousElement = getPreviousBlock(topElement); let foldPreviousElement = getPreviousBlock(topElement);
while (foldPreviousElement && foldPreviousElement.childElementCount === 3) { while (foldPreviousElement && foldPreviousElement.childElementCount === 3) {
@ -104,15 +110,7 @@ export const removeBlock = async (protyle: IProtyle, blockElement: Element, rang
} }
// https://github.com/siyuan-note/siyuan/issues/4422 // https://github.com/siyuan-note/siyuan/issues/4422
topElement.firstElementChild.removeAttribute("contenteditable"); topElement.firstElementChild.removeAttribute("contenteditable");
// 在折叠标题后输入文字,然后全选删除再撤销会重建索引。因此不能删除折叠标题后新输入的输入折叠标题下的内容 topElement.remove();
const nextElement = topElement.nextElementSibling;
if (nextElement) {
const nextType = nextElement.getAttribute("data-type");
if (nextType !== "NodeHeading" ||
(nextType === "NodeHeading" && nextElement.getAttribute("data-subtype") > topElement.getAttribute("data-subtype"))) {
return true;
}
}
} else { } else {
let data = topElement.outerHTML; // 不能 spin ,否则 li 会变为 list let data = topElement.outerHTML; // 不能 spin ,否则 li 会变为 list
if (topElement.classList.contains("render-node") || topElement.querySelector("div.render-node")) { if (topElement.classList.contains("render-node") || topElement.querySelector("div.render-node")) {
@ -136,7 +134,7 @@ export const removeBlock = async (protyle: IProtyle, blockElement: Element, rang
} }
topElement.remove(); topElement.remove();
} }
}); }
if (sideElement) { if (sideElement) {
if (protyle.block.showAll && sideElement.classList.contains("protyle-wysiwyg") && protyle.wysiwyg.element.childElementCount === 0) { if (protyle.block.showAll && sideElement.classList.contains("protyle-wysiwyg") && protyle.wysiwyg.element.childElementCount === 0) {
setTimeout(() => { setTimeout(() => {
@ -164,11 +162,11 @@ export const removeBlock = async (protyle: IProtyle, blockElement: Element, rang
// https://github.com/siyuan-note/siyuan/issues/10389 // https://github.com/siyuan-note/siyuan/issues/10389
// https://github.com/siyuan-note/siyuan/issues/10899 // https://github.com/siyuan-note/siyuan/issues/10899
if (type !== "Backspace" && sideIsNext) { if (type !== "Backspace" && sideIsNext) {
focusBlock(sideElement); focusBlock(sideElement as Element);
} else { } else {
focusBlock(sideElement, undefined, false); focusBlock(sideElement as Element, undefined, false);
} }
scrollCenter(protyle, sideElement); scrollCenter(protyle, sideElement as Element);
if (listElement) { if (listElement) {
inserts.push({ inserts.push({
action: "update", action: "update",

View file

@ -754,6 +754,9 @@ export const onTransaction = (protyle: IProtyle, operation: IOperation, isUndo:
return; return;
} }
if (operation.action === "insert") { if (operation.action === "insert") {
if (operation.context?.ignoreProcess === "true") {
return;
}
const cursorElements = []; const cursorElements = [];
if (operation.previousID) { if (operation.previousID) {
const previousElement = protyle.wysiwyg.element.querySelectorAll(`[data-node-id="${operation.previousID}"]`); const previousElement = protyle.wysiwyg.element.querySelectorAll(`[data-node-id="${operation.previousID}"]`);

View file

@ -1324,6 +1324,7 @@ const onSearch = (data: IBlock[], edit: Protyle, element: Element, config: Confi
let newData; let newData;
data.forEach((item) => { data.forEach((item) => {
const title = getNotebookName(item.box) + getDisplayName(item.hPath, false); const title = getNotebookName(item.box) + getDisplayName(item.hPath, false);
let countHTML = "";
if (item.children) { if (item.children) {
resultHTML += `<div class="b3-list-item"> resultHTML += `<div class="b3-list-item">
<span class="b3-list-item__toggle b3-list-item__toggle--hl"> <span class="b3-list-item__toggle b3-list-item__toggle--hl">
@ -1341,12 +1342,16 @@ ${unicode2Emoji(getNotebookIcon(item.box) || window.siyuan.storage[Constants.LOC
newData = childItem; newData = childItem;
} }
} }
if (childItem.refCount) {
countHTML = `<span class="popover__block counter b3-tooltips b3-tooltips__w" aria-label="${window.siyuan.languages.ref}">${childItem.refCount}</span>`;
}
resultHTML += `<div style="padding-left: 36px" data-type="search-item" class="b3-list-item" data-node-id="${childItem.id}" data-root-id="${childItem.rootID}"> resultHTML += `<div style="padding-left: 36px" data-type="search-item" class="b3-list-item" data-node-id="${childItem.id}" data-root-id="${childItem.rootID}">
<svg class="b3-list-item__graphic popover__block" data-id="${childItem.id}"><use xlink:href="#${getIconByType(childItem.type)}"></use></svg> <svg class="b3-list-item__graphic popover__block" data-id="${childItem.id}"><use xlink:href="#${getIconByType(childItem.type)}"></use></svg>
${unicode2Emoji(childItem.ial.icon, "b3-list-item__graphic", true)} ${unicode2Emoji(childItem.ial.icon, "b3-list-item__graphic", true)}
<span class="b3-list-item__text">${childItem.content}</span> <span class="b3-list-item__text">${childItem.content}</span>
${getAttr(childItem)} ${getAttr(childItem)}
${childItem.tag ? `<span class="b3-list-item__meta b3-list-item__meta--ellipsis">${childItem.tag.split("# #").map(tag => `${tag.replace("#", "")}`).join(" ").replace("#", "")}</span>` : ""} ${childItem.tag ? `<span class="b3-list-item__meta b3-list-item__meta--ellipsis">${childItem.tag.replace(/#/g, "")}</span>` : ""}
${countHTML}
</div>`; </div>`;
}); });
resultHTML += "</div>"; resultHTML += "</div>";
@ -1359,13 +1364,17 @@ ${childItem.tag ? `<span class="b3-list-item__meta b3-list-item__meta--ellipsis"
newData = item; newData = item;
} }
} }
if (item.refCount) {
countHTML = `<span class="popover__block counter b3-tooltips b3-tooltips__w" aria-label="${window.siyuan.languages.ref}">${item.refCount}</span>`;
}
resultHTML += `<div data-type="search-item" class="b3-list-item" data-node-id="${item.id}" data-root-id="${item.rootID}"> resultHTML += `<div data-type="search-item" class="b3-list-item" data-node-id="${item.id}" data-root-id="${item.rootID}">
<svg class="b3-list-item__graphic popover__block" data-id="${item.id}"><use xlink:href="#${getIconByType(item.type)}"></use></svg> <svg class="b3-list-item__graphic popover__block" data-id="${item.id}"><use xlink:href="#${getIconByType(item.type)}"></use></svg>
${unicode2Emoji(item.ial.icon, "b3-list-item__graphic", true)} ${unicode2Emoji(item.ial.icon, "b3-list-item__graphic", true)}
<span class="b3-list-item__text">${item.content}</span> <span class="b3-list-item__text">${item.content}</span>
${getAttr(item)} ${getAttr(item)}
${item.tag ? `<span class="b3-list-item__meta b3-list-item__meta--ellipsis">${item.tag.split("# #").map(tag => `${tag.replace("#", "")}`).join(" ").replace("#", "")}</span>` : ""} ${item.tag ? `<span class="b3-list-item__meta b3-list-item__meta--ellipsis">${item.tag.replace(/#/g, "")}</span>` : ""}
<span class="b3-list-item__meta b3-list-item__meta--ellipsis ariaLabel" aria-label="${escapeAriaLabel(title)}">${escapeGreat(title)}</span> <span class="b3-list-item__meta b3-list-item__meta--ellipsis ariaLabel" aria-label="${escapeAriaLabel(title)}">${escapeGreat(title)}</span>
${countHTML}
</div>`; </div>`;
} }
}); });

View file

@ -64,7 +64,7 @@ declare namespace Config {
*/ */
openHelp: boolean; openHelp: boolean;
/** /**
* Publishing service * Publish service
* *
*/ */
publish: IPublish; publish: IPublish;
@ -1078,29 +1078,29 @@ declare namespace Config {
export type TLogLevel = "off" | "trace" | "debug" | "info" | "warn" | "error" | "fatal"; export type TLogLevel = "off" | "trace" | "debug" | "info" | "warn" | "error" | "fatal";
/** /**
* Publishing service * Publish service
*/ */
export interface IPublish { export interface IPublish {
/** /**
* Whether to open the publishing service * Whether to open the publish service
*/ */
enable: boolean; enable: boolean;
/** /**
* The basic authentication settings of publishing service * The basic authentication settings of publish service
*/ */
auth: IPublishAuth; auth: IPublishAuth;
/** /**
* Port on which the publishing service listens * Port on which the publish service listens
*/ */
port: number; port: number;
} }
/** /**
* Publishing service authentication settings * Publish service authentication settings
*/ */
export interface IPublishAuth { export interface IPublishAuth {
/** /**
* Whether to enable basic authentication for publishing services * Whether to enable basic authentication for publish services
*/ */
enable: boolean; enable: boolean;
/** /**

View file

@ -86,7 +86,7 @@ type TEventBus = "ws-main" | "sync-start" | "sync-end" | "sync-fail" |
"destroy-protyle" | "destroy-protyle" |
"lock-screen" | "lock-screen" |
"mobile-keyboard-show" | "mobile-keyboard-hide" | "mobile-keyboard-show" | "mobile-keyboard-hide" |
"code-language-before" | "code-language-change" "code-language-update" | "code-language-change"
type TAVView = "table" | "gallery" type TAVView = "table" | "gallery"
type TAVCol = type TAVCol =
"text" "text"
@ -274,6 +274,7 @@ interface IClipboardData {
textPlain?: string, textPlain?: string,
siyuanHTML?: string, siyuanHTML?: string,
files?: File[], files?: File[],
localFiles?: string[]
} }
interface IRefDefs { interface IRefDefs {
@ -368,6 +369,7 @@ interface ISnippet {
type: string; type: string;
enabled: boolean; enabled: boolean;
content: string; content: string;
disabledInPublish: boolean;
} }
interface IInbox { interface IInbox {
@ -771,6 +773,7 @@ interface IBlock {
children?: IBlock[] children?: IBlock[]
length?: number length?: number
ial: IObject ial: IObject
refCount?: number
} }
interface IRiffCard { interface IRiffCard {
@ -895,6 +898,7 @@ interface IAVGallery extends IAVView {
interface IAVFilter { interface IAVFilter {
column: string, column: string,
operator: TAVFilterOperator, operator: TAVFilterOperator,
quantifier?: string,
value: IAVCellValue, value: IAVCellValue,
relativeDate?: relativeDate relativeDate?: relativeDate
relativeDate2?: relativeDate relativeDate2?: relativeDate

View file

@ -455,6 +455,7 @@ interface IProtyleOptions {
render?: { render?: {
background?: boolean background?: boolean
title?: boolean title?: boolean
titleShowTop?: boolean
gutter?: boolean gutter?: boolean
scroll?: boolean scroll?: boolean
breadcrumb?: boolean breadcrumb?: boolean

View file

@ -104,6 +104,10 @@ export const objEquals = (a: any, b: any): boolean => {
}; };
export const duplicateNameAddOne = (name:string) => { export const duplicateNameAddOne = (name:string) => {
if (!name) {
return "";
}
const nameMatch = name.match(/^(.*) \((\d+)\)$/); const nameMatch = name.match(/^(.*) \((\d+)\)$/);
if (nameMatch) { if (nameMatch) {
name = `${nameMatch[1]} (${parseInt(nameMatch[2]) + 1})`; name = `${nameMatch[1]} (${parseInt(nameMatch[2]) + 1})`;

View file

@ -249,10 +249,13 @@ export const newFileBySelect = (protyle: IProtyle, selectText: string, nodeEleme
}, (idResponse) => { }, (idResponse) => {
const refText = newFileName.substring(0, window.siyuan.config.editor.blockRefDynamicAnchorTextMaxLen); const refText = newFileName.substring(0, window.siyuan.config.editor.blockRefDynamicAnchorTextMaxLen);
if (idResponse.data && idResponse.data.length > 0) { if (idResponse.data && idResponse.data.length > 0) {
protyle.toolbar.setInlineMark(protyle, "block-ref", "range", { const refElement = protyle.toolbar.setInlineMark(protyle, "block-ref", "range", {
type: "id", type: "id",
color: `${idResponse.data[0]}${Constants.ZWSP}d${Constants.ZWSP}${refText}` color: `${idResponse.data[0]}${Constants.ZWSP}d${Constants.ZWSP}${refText}`
}); });
if (refElement[0]) {
protyle.toolbar.range.selectNodeContents(refElement[0]);
}
} else { } else {
fetchPost("/api/filetree/createDocWithMd", { fetchPost("/api/filetree/createDocWithMd", {
notebook: targetNotebookId, notebook: targetNotebookId,
@ -260,10 +263,13 @@ export const newFileBySelect = (protyle: IProtyle, selectText: string, nodeEleme
parentID: protyle.notebookId === targetNotebookId ? protyle.block.rootID : "", parentID: protyle.notebookId === targetNotebookId ? protyle.block.rootID : "",
markdown: "" markdown: ""
}, response => { }, response => {
protyle.toolbar.setInlineMark(protyle, "block-ref", "range", { const refElement = protyle.toolbar.setInlineMark(protyle, "block-ref", "range", {
type: "id", type: "id",
color: `${response.data}${Constants.ZWSP}d${Constants.ZWSP}${refText}` color: `${response.data}${Constants.ZWSP}d${Constants.ZWSP}${refText}`
}); });
if (refElement[0]) {
protyle.toolbar.range.selectNodeContents(refElement[0]);
}
}); });
} }
hideElements(["toolbar"], protyle); hideElements(["toolbar"], protyle);

View file

@ -1,5 +1,5 @@
const isNormalItem = (currentHintElement: HTMLElement, className: string) => { export const isAbnormalItem = (currentHintElement: HTMLElement, className: string) => {
return !currentHintElement.classList.contains(className) || currentHintElement.getBoundingClientRect().height === 0; return !currentHintElement || !currentHintElement.classList.contains(className) || currentHintElement.getBoundingClientRect().height === 0;
}; };
export const upDownHint = (listElement: Element, event: KeyboardEvent, classActiveName = "b3-list-item--focus", defaultElement?: Element) => { export const upDownHint = (listElement: Element, event: KeyboardEvent, classActiveName = "b3-list-item--focus", defaultElement?: Element) => {
@ -19,13 +19,13 @@ export const upDownHint = (listElement: Element, event: KeyboardEvent, classActi
currentHintElement.classList.remove(classActiveName); currentHintElement.classList.remove(classActiveName);
currentHintElement = currentHintElement.nextElementSibling as HTMLElement; currentHintElement = currentHintElement.nextElementSibling as HTMLElement;
while (currentHintElement && isNormalItem(currentHintElement, className)) { while (isAbnormalItem(currentHintElement, className)) {
currentHintElement = currentHintElement.nextElementSibling as HTMLElement; currentHintElement = currentHintElement.nextElementSibling as HTMLElement;
} }
if (!currentHintElement) { if (!currentHintElement) {
currentHintElement = listElement.children[0] as HTMLElement; currentHintElement = listElement.children[0] as HTMLElement;
while (currentHintElement && isNormalItem(currentHintElement, className)) { while (isAbnormalItem(currentHintElement, className)) {
currentHintElement = currentHintElement.nextElementSibling as HTMLElement; currentHintElement = currentHintElement.nextElementSibling as HTMLElement;
} }
} }
@ -44,7 +44,7 @@ export const upDownHint = (listElement: Element, event: KeyboardEvent, classActi
currentHintElement.classList.remove(classActiveName); currentHintElement.classList.remove(classActiveName);
currentHintElement = currentHintElement.previousElementSibling as HTMLElement; currentHintElement = currentHintElement.previousElementSibling as HTMLElement;
while (currentHintElement && isNormalItem(currentHintElement, className)) { while (isAbnormalItem(currentHintElement, className)) {
currentHintElement = currentHintElement.previousElementSibling as HTMLElement; currentHintElement = currentHintElement.previousElementSibling as HTMLElement;
} }
@ -70,7 +70,7 @@ export const upDownHint = (listElement: Element, event: KeyboardEvent, classActi
event.stopPropagation(); event.stopPropagation();
currentHintElement.classList.remove(classActiveName); currentHintElement.classList.remove(classActiveName);
currentHintElement = listElement.children[0] as HTMLElement; currentHintElement = listElement.children[0] as HTMLElement;
while (currentHintElement && isNormalItem(currentHintElement, className)) { while (isAbnormalItem(currentHintElement, className)) {
currentHintElement = currentHintElement.nextElementSibling as HTMLElement; currentHintElement = currentHintElement.nextElementSibling as HTMLElement;
} }
if (!currentHintElement) { if (!currentHintElement) {
@ -84,7 +84,7 @@ export const upDownHint = (listElement: Element, event: KeyboardEvent, classActi
event.stopPropagation(); event.stopPropagation();
currentHintElement.classList.remove(classActiveName); currentHintElement.classList.remove(classActiveName);
currentHintElement = listElement.children[listElement.children.length - 1] as HTMLElement; currentHintElement = listElement.children[listElement.children.length - 1] as HTMLElement;
while (currentHintElement && isNormalItem(currentHintElement, className)) { while (isAbnormalItem(currentHintElement, className)) {
currentHintElement = currentHintElement.previousElementSibling as HTMLElement; currentHintElement = currentHintElement.previousElementSibling as HTMLElement;
} }
if (!currentHintElement) { if (!currentHintElement) {

File diff suppressed because one or more lines are too long

View file

@ -10,7 +10,7 @@ module.exports = (env, argv) => {
return { return {
mode: argv.mode || "development", mode: argv.mode || "development",
watch: argv.mode !== "production", watch: argv.mode !== "production",
devtool: argv.mode !== "production" ? "cheap-source-map" : false, devtool: argv.mode !== "production" ? "eval-source-map" : false,
target: "electron-renderer", target: "electron-renderer",
output: { output: {
publicPath: "auto", publicPath: "auto",

View file

@ -11,7 +11,7 @@ module.exports = (env, argv) => {
return { return {
mode: argv.mode || "development", mode: argv.mode || "development",
watch: argv.mode !== "production", watch: argv.mode !== "production",
devtool: argv.mode !== "production" ? "cheap-source-map" : false, devtool: argv.mode !== "production" ? "eval-source-map" : false,
output: { output: {
publicPath: "/stage/build/desktop/", publicPath: "/stage/build/desktop/",
filename: "[name].[chunkhash].js", filename: "[name].[chunkhash].js",

View file

@ -10,7 +10,7 @@ module.exports = (env, argv) => {
return { return {
mode: argv.mode || "development", mode: argv.mode || "development",
watch: argv.mode !== "production", watch: argv.mode !== "production",
devtool: argv.mode !== "production" ? "cheap-source-map" : false, devtool: argv.mode !== "production" ? "eval-source-map" : false,
output: { output: {
publicPath: "auto", publicPath: "auto",
filename: "[name].js", filename: "[name].js",

View file

@ -11,7 +11,7 @@ module.exports = (env, argv) => {
return { return {
mode: argv.mode || "development", mode: argv.mode || "development",
watch: argv.mode !== "production", watch: argv.mode !== "production",
devtool: argv.mode !== "production" ? "cheap-source-map" : false, devtool: argv.mode !== "production" ? "eval-source-map" : false,
output: { output: {
// 不能使用 auto否则 ios 导出图片获取不到 css。 https://github.com/siyuan-note/siyuan/issues/8532 // 不能使用 auto否则 ios 导出图片获取不到 css。 https://github.com/siyuan-note/siyuan/issues/8532
publicPath: "/stage/build/mobile/", publicPath: "/stage/build/mobile/",

View file

@ -27,6 +27,44 @@ import (
"github.com/siyuan-note/siyuan/kernel/util" "github.com/siyuan-note/siyuan/kernel/util"
) )
func getAttributeViewItemIDsByBoundIDs(c *gin.Context) {
ret := gulu.Ret.NewResult()
defer c.JSON(http.StatusOK, ret)
arg, ok := util.JsonArg(c, ret)
if !ok {
return
}
avID := arg["avID"].(string)
blockIDsArg := arg["blockIDs"].([]interface{})
var blockIDs []string
for _, v := range blockIDsArg {
blockIDs = append(blockIDs, v.(string))
}
ret.Data = model.GetAttributeViewItemIDs(avID, blockIDs)
}
func getAttributeViewBoundBlockIDsByItemIDs(c *gin.Context) {
ret := gulu.Ret.NewResult()
defer c.JSON(http.StatusOK, ret)
arg, ok := util.JsonArg(c, ret)
if !ok {
return
}
avID := arg["avID"].(string)
itemIDsArg := arg["itemIDs"].([]interface{})
var itemIDs []string
for _, v := range itemIDsArg {
itemIDs = append(itemIDs, v.(string))
}
ret.Data = model.GetAttributeViewBoundBlockIDs(avID, itemIDs)
}
// getAttributeViewAddingBlockDefaultValues 用于获取添加块时的默认值。 // getAttributeViewAddingBlockDefaultValues 用于获取添加块时的默认值。
// 存在过滤或分组条件时,添加块时需要填充默认值到过滤字段或分组字段中,前端需要调用该接口来获取这些默认值以便填充。 // 存在过滤或分组条件时,添加块时需要填充默认值到过滤字段或分组字段中,前端需要调用该接口来获取这些默认值以便填充。
func getAttributeViewAddingBlockDefaultValues(c *gin.Context) { func getAttributeViewAddingBlockDefaultValues(c *gin.Context) {
@ -807,9 +845,15 @@ func setAttributeViewBlockAttr(c *gin.Context) {
avID := arg["avID"].(string) avID := arg["avID"].(string)
keyID := arg["keyID"].(string) keyID := arg["keyID"].(string)
rowID := arg["rowID"].(string) var itemID string
if _, ok := arg["itemID"]; ok {
itemID = arg["itemID"].(string)
} else if _, ok := arg["rowID"]; ok {
// TODO 划于 2026 年 6 月 30 日后删除 https://github.com/siyuan-note/siyuan/issues/15708#issuecomment-3239694546
itemID = arg["rowID"].(string)
}
value := arg["value"].(interface{}) value := arg["value"].(interface{})
updatedVal, err := model.UpdateAttributeViewCell(nil, avID, keyID, rowID, value) updatedVal, err := model.UpdateAttributeViewCell(nil, avID, keyID, itemID, value)
if err != nil { if err != nil {
ret.Code = -1 ret.Code = -1
ret.Msg = err.Error() ret.Msg = err.Error()

View file

@ -189,6 +189,20 @@ func getHeadingChildrenIDs(c *gin.Context) {
ret.Data = ids ret.Data = ids
} }
func appendHeadingChildren(c *gin.Context) {
ret := gulu.Ret.NewResult()
defer c.JSON(http.StatusOK, ret)
arg, ok := util.JsonArg(c, ret)
if !ok {
return
}
id := arg["id"].(string)
childrenDOM := arg["childrenDOM"].(string)
model.AppendHeadingChildren(id, childrenDOM)
}
func getHeadingChildrenDOM(c *gin.Context) { func getHeadingChildrenDOM(c *gin.Context) {
ret := gulu.Ret.NewResult() ret := gulu.Ret.NewResult()
defer c.JSON(http.StatusOK, ret) defer c.JSON(http.StatusOK, ret)
@ -199,7 +213,11 @@ func getHeadingChildrenDOM(c *gin.Context) {
} }
id := arg["id"].(string) id := arg["id"].(string)
dom := model.GetHeadingChildrenDOM(id) removeFoldAttr := true
if nil != arg["removeFoldAttr"] {
removeFoldAttr = arg["removeFoldAttr"].(bool)
}
dom := model.GetHeadingChildrenDOM(id, removeFoldAttr)
ret.Data = dom ret.Data = dom
} }

View file

@ -154,7 +154,7 @@ func extensionCopy(c *gin.Context) {
fName += ext fName += ext
} }
fName = util.AssetName(fName) fName = util.AssetName(fName, ast.NewNodeID())
writePath := filepath.Join(assets, fName) writePath := filepath.Join(assets, fName)
if err = filelock.WriteFile(writePath, data); err != nil { if err = filelock.WriteFile(writePath, data); err != nil {
ret.Code = -1 ret.Code = -1

View file

@ -128,7 +128,7 @@ func listDocTree(c *gin.Context) {
doctree = append(doctree, parent) doctree = append(doctree, parent)
subPath := filepath.Join(root, entry.Name()) subPath := filepath.Join(root, entry.Name())
if err = walkDocTree(subPath, parent, &ids); err != nil { if err = walkDocTree(subPath, parent, ids); err != nil {
ret.Code = -1 ret.Code = -1
ret.Msg = err.Error() ret.Msg = err.Error()
return return
@ -152,7 +152,7 @@ type DocFile struct {
Children []*DocFile `json:"children,omitempty"` Children []*DocFile `json:"children,omitempty"`
} }
func walkDocTree(p string, docFile *DocFile, ids *map[string]bool) (err error) { func walkDocTree(p string, docFile *DocFile, ids map[string]bool) (err error) {
dir, err := os.ReadDir(p) dir, err := os.ReadDir(p)
if err != nil { if err != nil {
return return
@ -169,7 +169,7 @@ func walkDocTree(p string, docFile *DocFile, ids *map[string]bool) (err error) {
} }
parent := &DocFile{ID: entry.Name()} parent := &DocFile{ID: entry.Name()}
(*ids)[parent.ID] = true ids[parent.ID] = true
docFile.Children = append(docFile.Children, parent) docFile.Children = append(docFile.Children, parent)
subPath := filepath.Join(p, entry.Name()) subPath := filepath.Join(p, entry.Name())
@ -178,10 +178,10 @@ func walkDocTree(p string, docFile *DocFile, ids *map[string]bool) (err error) {
} }
} else { } else {
doc := &DocFile{ID: strings.TrimSuffix(entry.Name(), ".sy")} doc := &DocFile{ID: strings.TrimSuffix(entry.Name(), ".sy")}
if !(*ids)[doc.ID] { if !ids[doc.ID] {
docFile.Children = append(docFile.Children, doc) docFile.Children = append(docFile.Children, doc)
} }
(*ids)[doc.ID] = true ids[doc.ID] = true
} }
} }
return return

View file

@ -35,9 +35,9 @@ func loadPetals(c *gin.Context) {
} }
frontend := arg["frontend"].(string) frontend := arg["frontend"].(string)
isPublish := model.IsReadOnlyRole(model.GetGinContextRole(c))
petals := model.LoadPetals(frontend) ret.Data = model.LoadPetals(frontend, isPublish)
ret.Data = petals
} }
func setPetalEnabled(c *gin.Context) { func setPetalEnabled(c *gin.Context) {

View file

@ -222,6 +222,7 @@ func ServeAPI(ginServer *gin.Engine) {
ginServer.Handle("POST", "/api/block/getBlockRelevantIDs", model.CheckAuth, getBlockRelevantIDs) ginServer.Handle("POST", "/api/block/getBlockRelevantIDs", model.CheckAuth, getBlockRelevantIDs)
ginServer.Handle("POST", "/api/block/getBlockTreeInfos", model.CheckAuth, getBlockTreeInfos) ginServer.Handle("POST", "/api/block/getBlockTreeInfos", model.CheckAuth, getBlockTreeInfos)
ginServer.Handle("POST", "/api/block/checkBlockRef", model.CheckAuth, checkBlockRef) ginServer.Handle("POST", "/api/block/checkBlockRef", model.CheckAuth, checkBlockRef)
ginServer.Handle("POST", "/api/block/appendHeadingChildren", model.CheckAuth, appendHeadingChildren)
ginServer.Handle("POST", "/api/file/getFile", model.CheckAuth, getFile) ginServer.Handle("POST", "/api/file/getFile", model.CheckAuth, getFile)
ginServer.Handle("POST", "/api/file/putFile", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, putFile) ginServer.Handle("POST", "/api/file/putFile", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, putFile)
@ -465,6 +466,8 @@ func ServeAPI(ginServer *gin.Engine) {
ginServer.Handle("POST", "/api/av/setAttrViewGroup", model.CheckAuth, setAttrViewGroup) ginServer.Handle("POST", "/api/av/setAttrViewGroup", model.CheckAuth, setAttrViewGroup)
ginServer.Handle("POST", "/api/av/batchReplaceAttributeViewBlocks", model.CheckAuth, batchReplaceAttributeViewBlocks) ginServer.Handle("POST", "/api/av/batchReplaceAttributeViewBlocks", model.CheckAuth, batchReplaceAttributeViewBlocks)
ginServer.Handle("POST", "/api/av/getAttributeViewAddingBlockDefaultValues", model.CheckAuth, getAttributeViewAddingBlockDefaultValues) ginServer.Handle("POST", "/api/av/getAttributeViewAddingBlockDefaultValues", model.CheckAuth, getAttributeViewAddingBlockDefaultValues)
ginServer.Handle("POST", "/api/av/getAttributeViewBoundBlockIDsByItemIDs", model.CheckAuth, getAttributeViewBoundBlockIDsByItemIDs)
ginServer.Handle("POST", "/api/av/getAttributeViewItemIDsByBoundIDs", model.CheckAuth, getAttributeViewItemIDsByBoundIDs)
ginServer.Handle("POST", "/api/ai/chatGPT", model.CheckAuth, model.CheckAdminRole, chatGPT) ginServer.Handle("POST", "/api/ai/chatGPT", model.CheckAuth, model.CheckAdminRole, chatGPT)
ginServer.Handle("POST", "/api/ai/chatGPTWithAction", model.CheckAuth, model.CheckAdminRole, chatGPTWithAction) ginServer.Handle("POST", "/api/ai/chatGPTWithAction", model.CheckAuth, model.CheckAdminRole, chatGPTWithAction)

View file

@ -55,11 +55,20 @@ func getSnippet(c *gin.Context) {
return return
} }
isPublish := model.IsReadOnlyRole(model.GetGinContextRole(c))
var snippets []*conf.Snippet var snippets []*conf.Snippet
for _, s := range confSnippets { for _, s := range confSnippets {
if ("all" == typ || s.Type == typ) && (2 == enabledArg || s.Enabled == enabled) { if isPublish && s.DisabledInPublish {
snippets = append(snippets, s) continue
} }
if "all" != typ && s.Type != typ {
continue
}
if 2 != enabledArg && s.Enabled != enabled {
continue
}
snippets = append(snippets, s)
} }
if "" != keyword { if "" != keyword {
@ -101,6 +110,9 @@ func setSnippet(c *gin.Context) {
Content: m["content"].(string), Content: m["content"].(string),
Enabled: m["enabled"].(bool), Enabled: m["enabled"].(bool),
} }
if nil != m["disabledInPublish"] {
snippet.DisabledInPublish = m["disabledInPublish"].(bool)
}
if "" == snippet.ID { if "" == snippet.ID {
snippet.ID = ast.NewNodeID() snippet.ID = ast.NewNodeID()
} }

View file

@ -42,6 +42,8 @@ type AttributeView struct {
KeyIDs []string `json:"keyIDs"` // 属性视图属性键 ID用于排序 KeyIDs []string `json:"keyIDs"` // 属性视图属性键 ID用于排序
ViewID string `json:"viewID"` // 当前视图 ID ViewID string `json:"viewID"` // 当前视图 ID
Views []*View `json:"views"` // 视图 Views []*View `json:"views"` // 视图
RenderedViewables map[string]Viewable `json:"-"` // 已经渲染好的视图
} }
// KeyValues 描述了属性视图属性键值列表的结构。 // KeyValues 描述了属性视图属性键值列表的结构。
@ -428,7 +430,7 @@ func ParseAttributeView(avID string) (ret *AttributeView, err error) {
return return
} }
ret = &AttributeView{} ret = &AttributeView{RenderedViewables: map[string]Viewable{}}
if err = gulu.JSON.UnmarshalJSON(data, ret); err != nil { if err = gulu.JSON.UnmarshalJSON(data, ret); err != nil {
if strings.Contains(err.Error(), ".relation.contents of type av.Value") { if strings.Contains(err.Error(), ".relation.contents of type av.Value") {
mapAv := map[string]interface{}{} mapAv := map[string]interface{}{}

View file

@ -26,11 +26,12 @@ import (
// ViewFilter 描述了视图过滤规则的结构。 // ViewFilter 描述了视图过滤规则的结构。
type ViewFilter struct { type ViewFilter struct {
Column string `json:"column"` // 列字段ID Column string `json:"column"` // 列字段ID
Operator FilterOperator `json:"operator"` // 过滤操作符 Qualifier FilterQuantifier `json:"quantifier,omitempty"` // 量词
Value *Value `json:"value"` // 过滤值 Operator FilterOperator `json:"operator"` // 操作符
RelativeDate *RelativeDate `json:"relativeDate,omitempty"` // 相对时间 Value *Value `json:"value"` // 过滤值
RelativeDate2 *RelativeDate `json:"relativeDate2,omitempty"` // 第二个相对时间,用于某些操作符,比如 FilterOperatorIsBetween RelativeDate *RelativeDate `json:"relativeDate,omitempty"` // 相对时间
RelativeDate2 *RelativeDate `json:"relativeDate2,omitempty"` // 第二个相对时间,用于某些操作符,比如 FilterOperatorIsBetween
} }
type RelativeDateUnit int type RelativeDateUnit int
@ -76,7 +77,16 @@ const (
FilterOperatorIsFalse FilterOperator = "Is false" FilterOperatorIsFalse FilterOperator = "Is false"
) )
func Filter(viewable Viewable, attrView *AttributeView) { type FilterQuantifier string
const (
FilterQuantifierUndefined FilterQuantifier = "" // 等同于 Any
FilterQuantifierAny FilterQuantifier = "Any"
FilterQuantifierAll FilterQuantifier = "All"
FilterQuantifierNone FilterQuantifier = "None"
)
func Filter(viewable Viewable, attrView *AttributeView, rollupFurtherCollections map[string]Collection, cachedAttrViews map[string]*AttributeView) {
collection := viewable.(Collection) collection := viewable.(Collection)
filters := collection.GetFilters() filters := collection.GetFilters()
if 1 > len(filters) { if 1 > len(filters) {
@ -94,8 +104,6 @@ func Filter(viewable Viewable, attrView *AttributeView) {
} }
var items []Item var items []Item
attrViewCache := map[string]*AttributeView{}
attrViewCache[attrView.ID] = attrView
for _, item := range collection.GetItems() { for _, item := range collection.GetItems() {
pass := true pass := true
values := item.GetValues() values := item.GetValues()
@ -116,7 +124,7 @@ func Filter(viewable Viewable, attrView *AttributeView) {
break break
} }
if !values[index].Filter(filters[j], attrView, item.GetID(), &attrViewCache) { if !values[index].Filter(filters[j], attrView, item.GetID(), rollupFurtherCollections, cachedAttrViews) {
pass = false pass = false
break break
} }
@ -128,7 +136,7 @@ func Filter(viewable Viewable, attrView *AttributeView) {
collection.SetItems(items) collection.SetItems(items)
} }
func (value *Value) Filter(filter *ViewFilter, attrView *AttributeView, rowID string, attrViewCache *map[string]*AttributeView) bool { func (value *Value) Filter(filter *ViewFilter, attrView *AttributeView, itemID string, rollupFurtherCollections map[string]Collection, cachedAttrViews map[string]*AttributeView) bool {
if nil == filter || (nil == filter.Value && nil == filter.RelativeDate) { if nil == filter || (nil == filter.Value && nil == filter.RelativeDate) {
return true return true
} }
@ -149,7 +157,6 @@ func (value *Value) Filter(filter *ViewFilter, attrView *AttributeView, rowID st
nil != filter.Value.Rollup && 0 < len(filter.Value.Rollup.Contents) { nil != filter.Value.Rollup && 0 < len(filter.Value.Rollup.Contents) {
// 单独处理汇总类型的比较 // 单独处理汇总类型的比较
// 处理值比较
key, _ := attrView.GetKey(value.KeyID) key, _ := attrView.GetKey(value.KeyID)
if nil == key { if nil == key {
return false return false
@ -160,16 +167,16 @@ func (value *Value) Filter(filter *ViewFilter, attrView *AttributeView, rowID st
return false return false
} }
relVal := attrView.GetValue(relKey.ID, rowID) relVal := attrView.GetValue(relKey.ID, itemID)
if nil == relVal || nil == relVal.Relation { if nil == relVal || nil == relVal.Relation {
return false return false
} }
destAv := (*attrViewCache)[relKey.Relation.AvID] destAv := cachedAttrViews[relKey.Relation.AvID]
if nil == destAv { if nil == destAv {
destAv, _ = ParseAttributeView(relKey.Relation.AvID) destAv, _ = ParseAttributeView(relKey.Relation.AvID)
if nil != destAv { if nil != destAv {
(*attrViewCache)[relKey.Relation.AvID] = destAv cachedAttrViews[relKey.Relation.AvID] = destAv
} }
} }
if nil == destAv { if nil == destAv {
@ -181,32 +188,29 @@ func (value *Value) Filter(filter *ViewFilter, attrView *AttributeView, rowID st
return false return false
} }
value.Rollup.BuildContents(destAv.KeyValues, destKey, relVal, key.Rollup.Calc, nil) value.Rollup.BuildContents(destAv.KeyValues, destKey, relVal, key.Rollup.Calc, rollupFurtherCollections[key.ID])
for _, content := range value.Rollup.Contents {
switch filter.Operator { switch filter.Qualifier {
case FilterOperatorContains: case FilterQuantifierUndefined, FilterQuantifierAny:
if content.filter(filter.Value.Rollup.Contents[0], filter.RelativeDate, filter.RelativeDate2, filter.Operator) { for _, content := range value.Rollup.Contents {
return true
}
case FilterOperatorDoesNotContain:
ret := content.filter(filter.Value.Rollup.Contents[0], filter.RelativeDate, filter.RelativeDate2, filter.Operator)
if !ret {
return false
}
default:
if content.filter(filter.Value.Rollup.Contents[0], filter.RelativeDate, filter.RelativeDate2, filter.Operator) { if content.filter(filter.Value.Rollup.Contents[0], filter.RelativeDate, filter.RelativeDate2, filter.Operator) {
return true return true
} }
} }
} case FilterQuantifierAll:
for _, content := range value.Rollup.Contents {
switch filter.Operator { if !content.filter(filter.Value.Rollup.Contents[0], filter.RelativeDate, filter.RelativeDate2, filter.Operator) {
case FilterOperatorContains: return false
return false }
case FilterOperatorDoesNotContain: }
return true
case FilterQuantifierNone:
for _, content := range value.Rollup.Contents {
if content.filter(filter.Value.Rollup.Contents[0], filter.RelativeDate, filter.RelativeDate2, filter.Operator) {
return false
}
}
return true return true
default:
return false
} }
} }
@ -523,17 +527,17 @@ func filterRelativeTime(valueMills int64, valueIsNotEmpty bool, operator FilterO
switch operator { switch operator {
case FilterOperatorIsEqual: case FilterOperatorIsEqual:
return (valueTime.After(otherValueStart) || valueTime.Equal(otherValueStart)) && valueTime.Before(otherValueEnd) return (valueTime.After(otherValueStart) || valueTime.Equal(otherValueStart)) && (valueTime.Before(otherValueEnd) || valueTime.Equal(otherValueEnd))
case FilterOperatorIsNotEqual: case FilterOperatorIsNotEqual:
return valueTime.Before(otherValueStart) || valueTime.After(otherValueEnd) return valueTime.Before(otherValueStart) || valueTime.After(otherValueEnd)
case FilterOperatorIsGreater: case FilterOperatorIsGreater:
return valueTime.After(otherValueStart) return valueTime.After(otherValueEnd)
case FilterOperatorIsGreaterOrEqual: case FilterOperatorIsGreaterOrEqual:
return valueTime.After(otherValueStart) || valueTime.Equal(otherValueStart) return valueTime.After(otherValueStart) || valueTime.Equal(otherValueStart)
case FilterOperatorIsLess: case FilterOperatorIsLess:
return valueTime.Before(otherValueStart) return valueTime.Before(otherValueStart)
case FilterOperatorIsLessOrEqual: case FilterOperatorIsLessOrEqual:
return valueTime.Before(otherValueStart) || valueTime.Equal(otherValueStart) return valueTime.Before(otherValueEnd) || valueTime.Equal(otherValueEnd)
case FilterOperatorIsBetween: case FilterOperatorIsBetween:
if RelativeDateDirectionBefore == direction { if RelativeDateDirectionBefore == direction {
if RelativeDateDirectionBefore == direction2 { if RelativeDateDirectionBefore == direction2 {

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