Compare commits

...

248 commits

Author SHA1 Message Date
Daniel
96dfe0bea4
🔖 Release v3.6.5
Some checks are pending
Release Docker Image / build (push) Waiting to run
Signed-off-by: Daniel <845765@qq.com>
2026-04-21 11:15:03 +08:00
Vanessa
e87fb431cc 🎨 https://github.com/siyuan-note/siyuan/issues/17560 2026-04-21 10:53:26 +08:00
Vanessa
0312bb7090 🎨 https://github.com/siyuan-note/siyuan/issues/17556 2026-04-21 10:43:59 +08:00
Vanessa
71610f0109 Merge remote-tracking branch 'origin/dev' into dev 2026-04-21 10:34:33 +08:00
Vanessa
f8cc5d5f29 🎨 https://github.com/siyuan-note/siyuan/issues/17556 2026-04-21 10:34:20 +08:00
Daniel
b01d452d2d
🎨 Clean code
Signed-off-by: Daniel <845765@qq.com>
2026-04-21 10:25:40 +08:00
Vanessa
9f8fb571f5 Merge remote-tracking branch 'origin/dev' into dev 2026-04-21 10:20:07 +08:00
Vanessa
5c43e082d5 🎨 https://github.com/siyuan-note/siyuan/issues/17559 2026-04-21 10:19:54 +08:00
Daniel
3999fd33f8
🎨 https://github.com/siyuan-note/siyuan/issues/17561
Signed-off-by: Daniel <845765@qq.com>
2026-04-21 09:50:58 +08:00
Vanessa
e987e3fb1e Merge remote-tracking branch 'origin/dev' into dev 2026-04-21 09:47:27 +08:00
Vanessa
f4dba03828 🎨 https://github.com/siyuan-note/siyuan/issues/17532 2026-04-21 09:47:14 +08:00
Daniel
321abe8785
🎨 https://github.com/siyuan-note/siyuan/issues/17549
Signed-off-by: Daniel <845765@qq.com>
2026-04-21 09:39:35 +08:00
Vanessa
ed799763d4 🎨 https://github.com/siyuan-note/siyuan/issues/17556 2026-04-21 09:08:35 +08:00
Daniel
237ae6ff97
🎨 https://github.com/siyuan-note/siyuan/issues/17349#issuecomment-4282750929
Signed-off-by: Daniel <845765@qq.com>
2026-04-21 08:55:34 +08:00
Daniel
464b72b24d
🎨 Treat the renaming of tags, bookmarks and assets as a data history Replace operation https://github.com/siyuan-note/siyuan/issues/17407#issuecomment-4283539036
Signed-off-by: Daniel <845765@qq.com>
2026-04-21 08:52:22 +08:00
Jeffrey Chen
1cb44c4d24
🐛 Correct the FTS target table branch of indexNode https://github.com/siyuan-note/siyuan/issues/17536 (#17557) 2026-04-20 23:22:17 +08:00
Vanessa
1995e6d421 🎨 https://github.com/siyuan-note/siyuan/issues/17556 2026-04-20 22:34:09 +08:00
Vanessa
4999feb021 🎨 https://github.com/siyuan-note/siyuan/issues/17555 2026-04-20 22:24:11 +08:00
Vanessa
43d6cb26a5 Merge remote-tracking branch 'origin/dev' into dev 2026-04-20 22:02:46 +08:00
Vanessa
0dc545607b 🎨 https://github.com/siyuan-note/siyuan/issues/17555 2026-04-20 22:02:23 +08:00
Daniel
53bcf77106
🎨 https://github.com/siyuan-note/siyuan/issues/17555#issuecomment-4280872035
Signed-off-by: Daniel <845765@qq.com>
2026-04-20 22:00:05 +08:00
Daniel
5cedae40ba
🎨 https://github.com/siyuan-note/siyuan/issues/17555#issuecomment-4280872035
Signed-off-by: Daniel <845765@qq.com>
2026-04-20 21:22:45 +08:00
Daniel
4bbcc82998
🎨 https://github.com/siyuan-note/siyuan/issues/17555#issuecomment-4280872035
Signed-off-by: Daniel <845765@qq.com>
2026-04-20 21:09:41 +08:00
Daniel
7c182042e7
📝 Update changelogs
Signed-off-by: Daniel <845765@qq.com>
2026-04-20 20:36:02 +08:00
Daniel
59019a29c6
🎨 https://github.com/siyuan-note/siyuan/issues/17555
Signed-off-by: Daniel <845765@qq.com>
2026-04-20 20:25:47 +08:00
Daniel
75a6eba371
🎨 https://github.com/siyuan-note/siyuan/issues/17555
Signed-off-by: Daniel <845765@qq.com>
2026-04-20 20:22:00 +08:00
Jeffrey Chen
c8a093fe1d
♻️ Skip subdoc dir scan when parent doc is hidden https://github.com/siyuan-note/siyuan/issues/17533 (#17554) 2026-04-20 20:10:29 +08:00
Daniel
0ddcf82eb2
🎨 Improve input method compatibility https://github.com/siyuan-note/siyuan/issues/17546
Signed-off-by: Daniel <845765@qq.com>
2026-04-20 20:06:11 +08:00
Vanessa
e9cc256964 Merge remote-tracking branch 'origin/dev' into dev 2026-04-20 19:44:27 +08:00
Vanessa
26681f8fb5 🎨 https://github.com/siyuan-note/siyuan/issues/17505 2026-04-20 19:44:14 +08:00
Daniel
bfe9f5cf72
🎨 https://github.com/siyuan-note/siyuan/issues/10313
Signed-off-by: Daniel <845765@qq.com>
2026-04-20 18:23:08 +08:00
Daniel
32c2c242e2
♻️ Extract const
Signed-off-by: Daniel <845765@qq.com>
2026-04-20 12:21:32 +08:00
Daniel
ea53f18519
🎨 https://github.com/siyuan-note/siyuan/issues/17533 03
Signed-off-by: Daniel <845765@qq.com>
2026-04-20 12:12:04 +08:00
Daniel
d43aa6b4c2
🎨 https://github.com/siyuan-note/siyuan/issues/17533 02
Signed-off-by: Daniel <845765@qq.com>
2026-04-20 12:00:43 +08:00
Daniel
3b3fed1f27
🎨 https://github.com/siyuan-note/siyuan/issues/17533 01
Signed-off-by: Daniel <845765@qq.com>
2026-04-20 11:51:26 +08:00
Daniel
fa4e160482
📝 Update changelogs
Signed-off-by: Daniel <845765@qq.com>
2026-04-20 11:41:39 +08:00
Vanessa
4926ba156a Merge remote-tracking branch 'origin/dev' into dev 2026-04-20 11:34:56 +08:00
Vanessa
9edbaf8cd7 🐛 https://github.com/siyuan-note/siyuan/issues/17509 2026-04-20 11:34:42 +08:00
Daniel
325dd69a10
🎨 https://github.com/siyuan-note/siyuan/issues/17549
Signed-off-by: Daniel <845765@qq.com>
2026-04-20 11:32:41 +08:00
Daniel
2e84f55957
📝 Update changelogs
Signed-off-by: Daniel <845765@qq.com>
2026-04-20 11:32:40 +08:00
Daniel
0d09c84317
🎨 https://github.com/siyuan-note/siyuan/issues/17549
Signed-off-by: Daniel <845765@qq.com>
2026-04-20 11:32:40 +08:00
Vanessa
0e1071f4f4 🎨 https://github.com/siyuan-note/siyuan/issues/17552 2026-04-20 10:48:39 +08:00
Vanessa
0cce5aa0da 🐛 https://github.com/siyuan-note/siyuan/issues/17551 2026-04-20 10:40:03 +08:00
Vanessa
bb0a4e8358 Merge remote-tracking branch 'origin/dev' into dev 2026-04-20 10:25:22 +08:00
Vanessa
647d830a3f 🐛 layout 2026-04-20 10:25:09 +08:00
Daniel
a02d3b86ba
🎨 https://github.com/siyuan-note/siyuan/issues/17550
Signed-off-by: Daniel <845765@qq.com>
2026-04-20 08:56:43 +08:00
Daniel
6e9e8dae07
⬆️ Upgrade lute
Signed-off-by: Daniel <845765@qq.com>
2026-04-19 22:06:22 +08:00
Daniel
cea611fee5
⬆️ Upgrade lute
Signed-off-by: Daniel <845765@qq.com>
2026-04-19 21:58:13 +08:00
Daniel
b40541dfda
📝 Update changelogs
Signed-off-by: Daniel <845765@qq.com>
2026-04-19 21:43:01 +08:00
Daniel
f9ab713141
🐛 logging
Signed-off-by: Daniel <845765@qq.com>
2026-04-19 21:15:30 +08:00
Vanessa
673d767ffc Merge remote-tracking branch 'origin/dev' into dev 2026-04-19 21:01:31 +08:00
Vanessa
04bf0acf5c 💄 https://github.com/siyuan-note/siyuan/issues/17517 2026-04-19 21:01:08 +08:00
Daniel
039128e21c
🎨 https://github.com/siyuan-note/siyuan/issues/17535
Signed-off-by: Daniel <845765@qq.com>
2026-04-19 20:47:17 +08:00
Daniel
d24e512f63
⬆️ Upgrade lute
Signed-off-by: Daniel <845765@qq.com>
2026-04-19 20:44:26 +08:00
Vanessa
700ed3c647 https://github.com/siyuan-note/siyuan/issues/17542 2026-04-19 19:05:32 +08:00
Vanessa
72e590e75e Merge remote-tracking branch 'origin/dev' into dev 2026-04-19 18:00:15 +08:00
Vanessa
1af11b7d90 https://github.com/siyuan-note/siyuan/issues/17542 2026-04-19 17:59:58 +08:00
Daniel
bb481e1290
🔒 https://github.com/siyuan-note/siyuan/security/advisories/GHSA-hjh7-r5w8-5872
Signed-off-by: Daniel <845765@qq.com>
2026-04-19 17:59:07 +08:00
Daniel
c66018958e
🎨 https://github.com/siyuan-note/siyuan/issues/17545
Signed-off-by: Daniel <845765@qq.com>
2026-04-19 17:34:22 +08:00
Daniel
1486804d67
🎨 https://github.com/siyuan-note/siyuan/issues/17534 https://github.com/siyuan-note/siyuan/issues/17545
Signed-off-by: Daniel <845765@qq.com>
2026-04-19 17:21:55 +08:00
Daniel
77d30f5fa7
🎨 https://github.com/siyuan-note/siyuan/issues/17407
Signed-off-by: Daniel <845765@qq.com>
2026-04-19 16:20:07 +08:00
Daniel
2d052a9400
🎨 https://github.com/siyuan-note/siyuan/issues/17536 https://github.com/siyuan-note/siyuan/issues/5889
Signed-off-by: Daniel <845765@qq.com>
2026-04-19 11:42:43 +08:00
Daniel
9fee2993f9
🐛 https://github.com/siyuan-note/siyuan/issues/17537
Signed-off-by: Daniel <845765@qq.com>
2026-04-19 11:23:59 +08:00
Vanessa
d552dc67ed Merge remote-tracking branch 'origin/dev' into dev 2026-04-19 11:02:08 +08:00
Vanessa
b0bba1ac93 🎨 https://github.com/siyuan-note/siyuan/issues/17532 2026-04-19 11:01:52 +08:00
Daniel
f5998d84b8
https://github.com/siyuan-note/siyuan/issues/17539
Signed-off-by: Daniel <845765@qq.com>
2026-04-19 10:40:38 +08:00
Vanessa
4abf412304 Merge remote-tracking branch 'origin/dev' into dev 2026-04-18 23:25:15 +08:00
Vanessa
4f4c19954c 🎨 https://github.com/siyuan-note/siyuan/issues/17518 2026-04-18 23:24:50 +08:00
Daniel
e63f6d2066
🎨 https://github.com/siyuan-note/siyuan/issues/17531
Signed-off-by: Daniel <845765@qq.com>
2026-04-18 23:17:56 +08:00
Vanessa
0f83e59272 Merge remote-tracking branch 'origin/dev' into dev 2026-04-18 20:44:33 +08:00
Vanessa
358dd34b68 🎨 https://github.com/siyuan-note/siyuan/issues/17518 2026-04-18 20:44:17 +08:00
Daniel
3b13cc420b
🎨 https://github.com/siyuan-note/siyuan/pull/17529
Signed-off-by: Daniel <845765@qq.com>
2026-04-18 17:31:56 +08:00
Jiacheng
e9f92d2a06
🎨 Refresh block updated time when updating task list item marker (#17529)
* 🐛 Refresh block updated time when updating task list item marker via API

* ♻️ Refactor task list item marker update operations for improved clarity and efficiency
2026-04-18 17:06:44 +08:00
未来方舟
21ff9ecf5f
👷 Fix AUR auto release fail (#17530)
* temp disable the repo owner lim so i can debug

* bump

* get the owner limit back

* remove my name
2026-04-18 17:01:37 +08:00
Daniel
1654612867
🎨 Treat the renaming of tags and assets as a data history Replace operation https://github.com/siyuan-note/siyuan/issues/17407
Signed-off-by: Daniel <845765@qq.com>
2026-04-18 12:27:01 +08:00
Daniel
935458d039
🎨 https://github.com/siyuan-note/siyuan/issues/17407
Signed-off-by: Daniel <845765@qq.com>
2026-04-18 12:18:51 +08:00
Daniel
8f4a07d6c7
🎨 Clean code
Signed-off-by: Daniel <845765@qq.com>
2026-04-18 12:03:25 +08:00
Vanessa
b3aadec1f8 Merge remote-tracking branch 'origin/dev' into dev 2026-04-18 10:47:34 +08:00
Vanessa
9e4f467464 🎨 https://github.com/siyuan-note/siyuan/issues/17523 2026-04-18 10:47:20 +08:00
Daniel
48456518ff
🎨 https://github.com/siyuan-note/siyuan/issues/17349
Signed-off-by: Daniel <845765@qq.com>
2026-04-17 22:58:28 +08:00
Daniel
28e6305261
♻️ Rename func
Signed-off-by: Daniel <845765@qq.com>
2026-04-17 22:42:53 +08:00
Daniel
f62080da41
📱 #17477
Signed-off-by: Daniel <845765@qq.com>
2026-04-17 22:41:31 +08:00
Jeffrey Chen
9893d3b41d
🎨 Improve input method compatibility https://ld246.com/article/1776401793390 (#17521) 2026-04-17 21:51:25 +08:00
Vanessa
b36b911964 🐛 https://github.com/siyuan-note/siyuan/issues/17499 2026-04-17 18:51:48 +08:00
Vanessa
597e56cb61 🐛 https://github.com/siyuan-note/siyuan/issues/17510 2026-04-17 12:15:58 +08:00
Vanessa
99feef9d48 🎨 https://github.com/siyuan-note/siyuan/issues/17508 2026-04-17 11:40:07 +08:00
Vanessa
e53670fb47 Merge remote-tracking branch 'origin/dev' into dev 2026-04-17 11:36:06 +08:00
Vanessa
bf47790a5f 📱 https://github.com/siyuan-note/siyuan/issues/17454 2026-04-17 11:35:53 +08:00
Daniel
b3f752172f
⬆️ Upgrade lute
Signed-off-by: Daniel <845765@qq.com>
2026-04-16 22:57:05 +08:00
Daniel
d87ae1ce6e
🐛 Authentication failed due to an excessively long cookie https://github.com/siyuan-note/siyuan/issues/17512
Signed-off-by: Daniel <845765@qq.com>
2026-04-16 20:13:41 +08:00
Daniel
9fc3ca302a
🐛 The IFrame block cannot be edited https://github.com/siyuan-note/siyuan/issues/17486
Signed-off-by: Daniel <845765@qq.com>
2026-04-16 12:22:24 +08:00
Vanessa
5d29b2e65a Merge remote-tracking branch 'origin/dev' into dev 2026-04-16 11:51:53 +08:00
Vanessa
32a260e3ac 🎨 https://github.com/siyuan-note/siyuan/issues/17478 2026-04-16 11:51:40 +08:00
Daniel
d1898a1343
🐛 The IFrame block cannot be edited https://github.com/siyuan-note/siyuan/issues/17486
Signed-off-by: Daniel <845765@qq.com>
2026-04-16 11:40:15 +08:00
Daniel
b5e9c9e83e
🔒 https://github.com/siyuan-note/siyuan/security/advisories/GHSA-grjj-6f6g-cq8q
Signed-off-by: Daniel <845765@qq.com>
2026-04-16 11:06:53 +08:00
Daniel
43b9f9f8f0
♻️ Upgrade to Electron v40.9.1 https://github.com/siyuan-note/siyuan/issues/17501
Signed-off-by: Daniel <845765@qq.com>
2026-04-16 10:35:58 +08:00
Daniel
df6da2976d
🎨 Improve task list item markdown indexing for data-task marker https://github.com/siyuan-note/siyuan/issues/17502
Signed-off-by: Daniel <845765@qq.com>
2026-04-16 09:32:04 +08:00
Jeffrey Chen
0456ea154e
🎨 Support HTTP/2 over HTTPS (#17500) 2026-04-16 08:23:58 +08:00
Vanessa
0a0a4a3b22 Merge remote-tracking branch 'origin/dev' into dev 2026-04-15 22:21:10 +08:00
Vanessa
b7f1d12b8f 🐛 https://github.com/siyuan-note/siyuan/issues/17492 2026-04-15 22:20:47 +08:00
Daniel
95e96ac41c
Improve ristretto NumCounters
Signed-off-by: Daniel <845765@qq.com>
2026-04-15 21:56:43 +08:00
Emptylight
7cdda2f750
📝 language selector for contributing.md (#17496) 2026-04-15 17:24:59 +08:00
Daniel
57a867d1b9
🐛 The outline does not refresh automatically https://github.com/siyuan-note/siyuan/issues/17493
Signed-off-by: Daniel <845765@qq.com>
2026-04-15 11:22:01 +08:00
Vanessa
16d7b7dc60 🐛 https://github.com/siyuan-note/siyuan/issues/17495 2026-04-15 10:55:04 +08:00
Daniel
62eed37a32
🔖 Release v3.6.4
Signed-off-by: Daniel <845765@qq.com>
2026-04-14 09:39:42 +08:00
Vanessa
3e6ae6589a 🚨 2026-04-14 09:30:18 +08:00
Vanessa
a5a59d94df Merge remote-tracking branch 'origin/dev' into dev 2026-04-14 09:29:10 +08:00
Vanessa
ab5c9c6927 🎨 有 iframe 时,无法拖拽列表圆点 2026-04-14 09:28:57 +08:00
Daniel
d167442c7a
🎨 Clean code
Signed-off-by: Daniel <845765@qq.com>
2026-04-14 09:18:48 +08:00
Jeffrey Chen
8f3b9992c2
🎨 Prevent modification of the data-task attribute https://github.com/siyuan-note/siyuan/issues/17343#issuecomment-4223807048 (#17466) 2026-04-14 08:01:45 +08:00
Vanessa
097480ed78 🎨 https://github.com/siyuan-note/siyuan/pull/17465 2026-04-13 22:10:51 +08:00
Jeffrey Chen
e9a2dc2e4d
Add error details to the abnormal status pop-up window (#17465)
* 🎨 Add error details to the abnormal status pop-up window

* 🎨 Add error details to the abnormal status pop-up window
2026-04-13 21:47:57 +08:00
Vanessa
08ef8f37f6 Merge remote-tracking branch 'origin/dev' into dev 2026-04-13 21:46:34 +08:00
Vanessa
f1849d7ad6 🎨 https://github.com/siyuan-note/siyuan/issues/17425 2026-04-13 21:46:20 +08:00
Daniel
c53fa23816
⬆️ Upgrade lute
Signed-off-by: Daniel <845765@qq.com>
2026-04-13 20:49:35 +08:00
Vanessa
34048eb212 Merge remote-tracking branch 'origin/dev' into dev 2026-04-13 20:42:38 +08:00
Vanessa
dd01d26b59 🎨 https://github.com/siyuan-note/siyuan/issues/17425 2026-04-13 20:42:21 +08:00
Daniel
53eee57b4d
🎨 https://github.com/siyuan-note/siyuan/pull/17481
Signed-off-by: Daniel <845765@qq.com>
2026-04-13 20:28:26 +08:00
Daniel
6c277e8a23
📝 Update changelogs
Signed-off-by: Daniel <845765@qq.com>
2026-04-13 20:24:28 +08:00
Vanessa
490a3cab33 💄 https://github.com/siyuan-note/siyuan/issues/17358 2026-04-13 19:36:41 +08:00
Vanessa
dfb038302f 💄 https://github.com/siyuan-note/siyuan/issues/17358 2026-04-13 18:37:54 +08:00
Vanessa
ed3c62ecb8 Merge remote-tracking branch 'origin/dev' into dev 2026-04-13 11:51:19 +08:00
Vanessa
df92f92179 🐛 https://github.com/siyuan-note/siyuan/issues/17467 2026-04-13 11:51:06 +08:00
Daniel
87ee243971
📝 Update changelogs
Signed-off-by: Daniel <845765@qq.com>
2026-04-13 11:48:21 +08:00
Daniel
da072ce12c
🎨 https://github.com/siyuan-note/siyuan/issues/17476
Signed-off-by: Daniel <845765@qq.com>
2026-04-13 11:26:42 +08:00
Vanessa
888699151a Merge remote-tracking branch 'origin/dev' into dev 2026-04-13 11:10:09 +08:00
Vanessa
db18b460a2 🎨 https://github.com/siyuan-note/siyuan/issues/17458 2026-04-13 11:09:56 +08:00
Daniel
9b29e5aa49
🎨 https://github.com/siyuan-note/siyuan/issues/17476
Signed-off-by: Daniel <845765@qq.com>
2026-04-13 11:04:24 +08:00
Jeffrey Chen
712ad7b74a
♻️ Encapsulate sorting file read/write functions and add complete file paths to error logs (#17480) 2026-04-13 10:36:05 +08:00
Vanessa
e77d2cd300 Merge remote-tracking branch 'origin/dev' into dev 2026-04-13 10:01:32 +08:00
Vanessa
a49a45ebf9 🎨 https://github.com/siyuan-note/siyuan/issues/17358 2026-04-13 10:01:20 +08:00
Jeffrey Chen
25319d7762
🐛 LoadTreeByData failed https://ld246.com/article/1776010143944 (#17479) 2026-04-13 09:43:37 +08:00
Vanessa
44fbe3cbac 🎨 https://github.com/siyuan-note/siyuan/issues/17352 2026-04-12 23:02:29 +08:00
Jeffrey Chen
c9208f8af0
🎨 Downloaded marketplace packages will no longer revert to fetching the online README (#17464) 2026-04-11 23:49:42 +08:00
Daniel
6808c3bd2d
📝 Update Security report
Signed-off-by: Daniel <845765@qq.com>
2026-04-11 22:55:13 +08:00
Vanessa
051b06997a Merge remote-tracking branch 'origin/dev' into dev 2026-04-11 22:46:44 +08:00
Vanessa
548c9fc9af 🎨 https://github.com/siyuan-note/siyuan/issues/17358 2026-04-11 22:46:27 +08:00
Daniel
996a238d59
🎨 https://github.com/siyuan-note/siyuan/issues/17462
Signed-off-by: Daniel <845765@qq.com>
2026-04-11 22:45:16 +08:00
Vanessa
192f26f735 Merge remote-tracking branch 'origin/dev' into dev 2026-04-11 22:39:46 +08:00
Vanessa
a47491b9fa 🎨 https://github.com/siyuan-note/siyuan/issues/17437 2026-04-11 22:39:24 +08:00
Daniel
1c92d4d10e
⬆️ Upgrade kernel deps
Signed-off-by: Daniel <845765@qq.com>
2026-04-11 22:19:23 +08:00
Daniel
31ca1d779f
⬆️ Upgrade kernel deps
Signed-off-by: Daniel <845765@qq.com>
2026-04-11 22:14:33 +08:00
Vanessa
55f5353350 💄 https://github.com/siyuan-note/siyuan/issues/17358 2026-04-11 21:49:58 +08:00
Vanessa
72cc7c46a7 🐛 https://github.com/siyuan-note/siyuan/issues/17437 2026-04-11 21:39:18 +08:00
Vanessa
c9f745269f Merge remote-tracking branch 'origin/dev' into dev 2026-04-11 20:57:31 +08:00
Vanessa
9388a5170b 🎨 https://github.com/siyuan-note/siyuan/issues/17435 2026-04-11 20:57:15 +08:00
Jeffrey Chen
cce07ff01f
🎨 Improve some file operation APIs https://github.com/siyuan-note/siyuan/issues/17409 (#17460) 2026-04-11 20:22:19 +08:00
Jeffrey Chen
ca38872f11
🧑‍💻 Add kernel API /api/block/batchUpdateTaskListItemMarker https://github.com/siyuan-note/siyuan/issues/17451 (#17461) 2026-04-11 20:06:01 +08:00
Jeffrey Chen
9ba3a9a65d
🎨 Escape marketplace package author name (#17457) 2026-04-11 18:20:49 +08:00
Daniel
31eb761ef3
⬆️ Upgrade kernel deps
Signed-off-by: Daniel <845765@qq.com>
2026-04-11 16:08:37 +08:00
Daniel
bb326aa992
🔒 https://github.com/siyuan-note/siyuan/security/advisories/GHSA-x63q-3rcj-hhp5
Signed-off-by: Daniel <845765@qq.com>
2026-04-11 11:54:32 +08:00
Daniel
068fd226fa
⬆️ Upgrade DOMPurify
Signed-off-by: Daniel <845765@qq.com>
2026-04-11 11:53:14 +08:00
Daniel
b44e9fae91
🎨 https://github.com/siyuan-note/siyuan/issues/17343#issuecomment-4224740397
Signed-off-by: Daniel <845765@qq.com>
2026-04-11 11:04:32 +08:00
Daniel
9fa3c8a2db
🐛 https://github.com/siyuan-note/siyuan/issues/17343#issuecomment-4223974591 https://github.com/siyuan-note/siyuan/issues/4658
Signed-off-by: Daniel <845765@qq.com>
2026-04-10 21:25:42 +08:00
Daniel
0ede0c7ce7
🧑‍💻 Add kernel API /api/block/updateTaskListItemMarker https://github.com/siyuan-note/siyuan/issues/17451
Signed-off-by: Daniel <845765@qq.com>
2026-04-10 21:15:04 +08:00
Daniel
46ce401552
🔒 https://github.com/siyuan-note/siyuan/security/advisories/GHSA-vw86-c94w-v3x4
Signed-off-by: Daniel <845765@qq.com>
2026-04-10 19:58:49 +08:00
Vanessa
0478d00911 Merge remote-tracking branch 'origin/dev' into dev 2026-04-10 19:50:19 +08:00
Vanessa
f5e740adee 🎨 https://github.com/siyuan-note/siyuan/issues/17343 2026-04-10 19:49:45 +08:00
Daniel
3162850e92
⬆️ Upgrade lute
Signed-off-by: Daniel <845765@qq.com>
2026-04-10 17:52:20 +08:00
Daniel
939665d1c1
⬆️ Upgrade lute
Signed-off-by: Daniel <845765@qq.com>
2026-04-10 17:35:48 +08:00
Daniel
06d5ac7bd3
🔒 https://github.com/siyuan-note/siyuan/security/advisories/GHSA-7m5h-w69j-qggg
Signed-off-by: Daniel <845765@qq.com>
2026-04-10 17:35:24 +08:00
Jeffrey Chen
dc4945426c
🎨 Improve the layout of the empty market list https://github.com/siyuan-note/siyuan/issues/17358#issuecomment-4192796313 (#17448) 2026-04-10 17:09:09 +08:00
Jeffrey Chen
2e4c49151f
🎨 Update system version retrieval in error.html to use process.getSystemVersion for better accuracy (#17449) 2026-04-10 17:08:03 +08:00
Vanessa
3247c43564 🎨 https://github.com/siyuan-note/siyuan/issues/17343 2026-04-10 16:57:40 +08:00
Vanessa
83236e86ed 🎨 https://github.com/siyuan-note/siyuan/issues/17358 2026-04-10 16:32:41 +08:00
Vanessa
18a29092d7 ♻️ https://github.com/siyuan-note/siyuan/pull/17434 2026-04-10 12:31:47 +08:00
Vanessa
b45cff419c ♻️ https://github.com/siyuan-note/siyuan/pull/17434 2026-04-10 12:05:07 +08:00
Jeffrey Chen
a93d7ad65a
🎨 The loading icon no longer covers the entire cloud configuration page (#17434) 2026-04-10 11:50:06 +08:00
Vanessa
9bdd7f39d5 🎨 https://github.com/siyuan-note/siyuan/issues/17343 2026-04-10 11:29:47 +08:00
Vanessa
b4e4a6774b Merge remote-tracking branch 'origin/dev' into dev 2026-04-10 11:15:08 +08:00
Vanessa
9ca18df367 🎨 https://github.com/siyuan-note/siyuan/issues/17422 2026-04-10 11:14:55 +08:00
Daniel
c1539878c8
♻️ Move IsSubPath to gulu
Signed-off-by: Daniel <845765@qq.com>
2026-04-10 00:38:50 +08:00
Daniel
be0a86b45f
🔒 https://github.com/siyuan-note/siyuan/security/advisories/GHSA-w95v-4h65-j455
Signed-off-by: Daniel <845765@qq.com>
2026-04-10 00:08:27 +08:00
Vanessa
39c87227ac 🎨 https://github.com/siyuan-note/siyuan/issues/17422 2026-04-09 17:15:34 +08:00
Vanessa
811cc6eefc 🎨 https://github.com/siyuan-note/siyuan/issues/17406 2026-04-09 16:55:46 +08:00
Vanessa
962180d495 🎨 https://github.com/siyuan-note/siyuan/issues/17343 2026-04-09 16:33:56 +08:00
Vanessa
f2ba1f6383 Merge remote-tracking branch 'origin/dev' into dev 2026-04-09 16:27:45 +08:00
Vanessa
bdf9104d7d 🎨 https://github.com/siyuan-note/siyuan/issues/17432 2026-04-09 16:27:30 +08:00
Daniel
df897f5390
🎨 https://github.com/siyuan-note/siyuan/issues/17440
Signed-off-by: Daniel <845765@qq.com>
2026-04-09 13:28:41 +08:00
Daniel
efed9d1604
🎨 https://github.com/siyuan-note/siyuan/issues/17409
Signed-off-by: Daniel <845765@qq.com>
2026-04-09 12:45:32 +08:00
Vanessa
23eddb6703 Merge remote-tracking branch 'origin/dev' into dev 2026-04-09 11:56:20 +08:00
Vanessa
c09fa815f4 🎨 https://github.com/siyuan-note/siyuan/issues/17432 2026-04-09 11:56:08 +08:00
Daniel
a5df75dcba
🎨 Add a "Copy" option to the document block menu https://github.com/siyuan-note/siyuan/issues/17352
Signed-off-by: Daniel <845765@qq.com>
2026-04-09 11:54:08 +08:00
Vanessa
705313f90b Merge remote-tracking branch 'origin/dev' into dev 2026-04-09 11:50:02 +08:00
Vanessa
c01c464c9c 🎨 https://github.com/siyuan-note/siyuan/issues/17387 2026-04-09 11:49:50 +08:00
Daniel
3d7034a892
🎨 Add a "Copy" option to the document block menu https://github.com/siyuan-note/siyuan/issues/17352
Signed-off-by: Daniel <845765@qq.com>
2026-04-09 11:46:51 +08:00
Vanessa
2a31796533 Merge remote-tracking branch 'origin/dev' into dev 2026-04-09 10:30:24 +08:00
Vanessa
13b257ce87 🎨 https://github.com/siyuan-note/siyuan/issues/17352 2026-04-09 10:30:11 +08:00
Jeffrey Chen
68dde82a64
🐛 Only validate the name when the S3 bucket name changes https://ld246.com/article/1775665943744 (#17433) 2026-04-09 09:05:24 +08:00
Vanessa
de94db9449 🎨 https://github.com/siyuan-note/siyuan/issues/17389 2026-04-08 23:46:32 +08:00
Vanessa
20d3903e02 Merge remote-tracking branch 'origin/dev' into dev 2026-04-08 23:22:34 +08:00
Vanessa
f07df861ca 🎨 https://github.com/siyuan-note/siyuan/issues/17343 2026-04-08 23:22:12 +08:00
Daniel
5462b72847
🎨 https://github.com/siyuan-note/siyuan/issues/17430
Signed-off-by: Daniel <845765@qq.com>
2026-04-08 22:34:42 +08:00
Vanessa
049be21c08 🎨 https://github.com/siyuan-note/siyuan/issues/17343 2026-04-08 22:24:53 +08:00
Vanessa
3e451fa461 Merge remote-tracking branch 'origin/dev' into dev 2026-04-08 22:20:04 +08:00
Vanessa
c94e610b25 🎨 https://github.com/siyuan-note/siyuan/issues/17343 2026-04-08 22:17:54 +08:00
Daniel
aaa1b02ad9
⬆️ Upgrade lute
Signed-off-by: Daniel <845765@qq.com>
2026-04-08 20:07:44 +08:00
Daniel
88575a266a
⬆️ Upgrade lute
Signed-off-by: Daniel <845765@qq.com>
2026-04-08 19:43:51 +08:00
Daniel
e65c2a3ac1
🐛 Default workspace data will be lost on macOS https://github.com/siyuan-note/siyuan/issues/17430
Signed-off-by: Daniel <845765@qq.com>
2026-04-08 19:43:50 +08:00
Jeffrey Chen
b35308005b
🎨 Avoid creating empty SiYuan directories using getPath("userData") (#17431) 2026-04-08 19:40:29 +08:00
Vanessa
9bb9ead21e 🎨 https://github.com/siyuan-note/siyuan/issues/17358 2026-04-08 19:30:24 +08:00
Vanessa
0e33f3900d Merge remote-tracking branch 'origin/dev' into dev 2026-04-08 17:44:45 +08:00
Vanessa
a1d9c1239a 🎨 https://github.com/siyuan-note/siyuan/issues/17424 2026-04-08 17:44:31 +08:00
Daniel
07705b5397
🎨 Change the initial workspace path to ~/Library/Application Support/SiYuan on macOS https://github.com/siyuan-note/siyuan/issues/17095
🐛 Default workspace data will be lost on macOS https://github.com/siyuan-note/siyuan/issues/17430

Signed-off-by: Daniel <845765@qq.com>
2026-04-08 17:33:04 +08:00
Daniel
f0a6fb0711
🐛 Default workspace data will be lost on macOS https://github.com/siyuan-note/siyuan/issues/17430
Signed-off-by: Daniel <845765@qq.com>
2026-04-08 17:20:31 +08:00
Daniel
98cc6ed89e
⬆️ Upgrade kernel deps
Signed-off-by: Daniel <845765@qq.com>
2026-04-08 16:42:27 +08:00
Vanessa
c13e85e7f2 🎨 https://github.com/siyuan-note/siyuan/issues/17388 2026-04-08 16:03:57 +08:00
Daniel
661234c289
⬆️ Upgrade lute
Signed-off-by: Daniel <845765@qq.com>
2026-04-07 17:24:30 +08:00
Daniel
7edce5649f
🎨 Clean code
Signed-off-by: Daniel <845765@qq.com>
2026-04-07 17:18:53 +08:00
Daniel
79228dde16
🎨 The list in the backlink panel no longer collapses automatically https://github.com/siyuan-note/siyuan/issues/17362
Signed-off-by: Daniel <845765@qq.com>
2026-04-07 16:51:07 +08:00
Vanessa
847e8a303a Merge remote-tracking branch 'origin/dev' into dev 2026-04-07 16:40:44 +08:00
Vanessa
d3fa65d72c 🎨 https://github.com/siyuan-note/siyuan/issues/17387 2026-04-07 16:40:31 +08:00
Daniel
2f416e5253
⬆️ Upgrade lute
Signed-off-by: Daniel <845765@qq.com>
2026-04-07 11:56:53 +08:00
Daniel
03a0e822a3
🎨 https://github.com/siyuan-note/siyuan/pull/17398
Signed-off-by: Daniel <845765@qq.com>
2026-04-07 10:19:17 +08:00
Jeffrey Chen
a94204487e
🎨 When exporting PDF, clicking on footnote links no longer opens the main window (#17398) 2026-04-07 10:17:25 +08:00
Jeffrey Chen
e009b26d97
🧑‍💻 Add kernel API /api/file/workspaceCopyFiles (#17421) 2026-04-07 09:55:36 +08:00
Vanessa
a1ade9981c 🎨 https://github.com/siyuan-note/siyuan/issues/17354 2026-04-06 22:16:15 +08:00
Jeffrey Chen
be941fdddb
🎨 Improve getAllTabs https://github.com/siyuan-note/siyuan/issues/17354 (#17418) 2026-04-06 22:10:25 +08:00
Vanessa
28d47adc5b 🎨 https://github.com/siyuan-note/siyuan/pull/17420 2026-04-06 21:47:14 +08:00
Jeffrey Chen
08b4437c32
🎨 Marketplace package card displays author's name (#17420) 2026-04-06 21:44:24 +08:00
Vanessa
5b90ba7990 🎨 https://github.com/siyuan-note/siyuan/issues/17358 2026-04-06 21:43:21 +08:00
Vanessa
e4db991e1b ♻️ https://github.com/siyuan-note/siyuan/pull/17378 2026-04-06 21:27:41 +08:00
Jiacheng
029eb0a4a9
Improve pasting link (#17378)
* fix(protyle): use true for genLinkText to show link text

* fix(paste): adjust link paste logic

* refactor(paste): improve URL auto-conversion logic and link handling

- Extract URL to link conversion into separate function for better maintainability
- Simplify pasteAsLink by removing multi-line handling and using single logic
- Move URL auto-conversion check before pasteAsLink for proper processing order

* refactor(paste): simplify URL to link conversion logic

Remove convertUrlsToLinks function and improve pasteAsLink to handle text segments more efficiently. The new implementation processes text and links separately while maintaining whitespace and only converts valid URLs to links.

* feat(paste): add auto URL conversion when pasting text

Add new method Md2BlockDOMWithAutoLink to Lute interface and implement auto URL conversion based on editor configuration. This addresses the feature request for automatically converting pasted URLs to links.

* refactor(paste): remove pasteAsLink function and use lute's auto link conversion

Simplify link handling during paste by leveraging lute's built-in auto link conversion functionality instead of maintaining a separate implementation. This change improves maintainability and reduces code duplication.

* fix(paste): move link conversion after HTML unescape

Ensure link conversion is applied to the correct processed content by moving it after HTML unescaping

* fix: remove auto-link conversion for block paste

The conditional logic for auto-link conversion during paste was incorrectly applied. The code previously skipped auto-link conversion for block types, but the condition was reversed. Since block types should not have auto-link conversion, the condition has been removed entirely to align with the intended behavior.
2026-04-06 21:24:25 +08:00
Vanessa
eeed27a324 Merge remote-tracking branch 'origin/dev' into dev 2026-04-06 21:19:44 +08:00
Vanessa
647d05ff98 ♻️ 2026-04-06 21:19:10 +08:00
Daniel
235dfb9ae3
⬆️ Upgrade lute
Signed-off-by: Daniel <845765@qq.com>
2026-04-06 21:12:34 +08:00
Jeffrey Chen
f9c5c482b8
🎨 Parameterized label query statements and escaping LIKE wildcards (#17416) 2026-04-06 09:30:04 +08:00
Daniel
b62273eb00
⬆️ Upgrade lute
Signed-off-by: Daniel <845765@qq.com>
2026-04-06 09:21:43 +08:00
Jeffrey Chen
698ee3d357
♻️ Improve validation of some JSON parameters (#17412)
* 🎨 Improve validation of some JSON parameters

* 🎨 Improve validation of some JSON parameters

* 🎨 Improve validation of some JSON parameters

* 🎨 Improve validation of some JSON parameters

* 🎨 Improve validation of some JSON parameters

* 🎨 Improve validation of some JSON parameters

* 🎨 Improve validation of some JSON parameters

* 🎨 Improve validation of some JSON parameters

* 🎨 Improve validation of some JSON parameters

* 🎨 Improve validation of some JSON parameters

* 🎨 Improve validation of some JSON parameters

* 🎨 Improve validation of some JSON parameters

* 🎨 Improve validation of some JSON parameters

* 🎨 Improve validation of some JSON parameters

* 🎨 Improve validation of some JSON parameters

* 🎨 Improve validation of some JSON parameters

* 🎨 Improve validation of some JSON parameters

* 🎨 Improve validation of some JSON parameters

* 🎨 Improve validation of some JSON parameters

* 🎨 Improve validation of some JSON parameters

* 🎨 Improve validation of some JSON parameters

* 🎨 Improve validation of some JSON parameters

* 🎨 Improve validation of some JSON parameters

* 🎨 Improve validation of some JSON parameters
2026-04-05 17:03:13 +08:00
Jeffrey Chen
bb9cb86bd7
🎨 Empty tags are once again displayed in the tag panel (#17408) 2026-04-05 16:59:02 +08:00
Jeffrey Chen
29092a385f
🎨 JsonArg uses ShouldBindJSON and returns more diagnosable errors (#17413) 2026-04-05 16:51:27 +08:00
Jeffrey Chen
4065982c9a
♻️ Replace errors.New(fmt.Sprintf) with fmt.Errorf (#17414) 2026-04-05 16:50:20 +08:00
Jeffrey Chen
5c674d7249
♻️ Replace interface{} with any (#17415) 2026-04-05 16:48:32 +08:00
Vanessa
074daacbc4 🎨 https://github.com/siyuan-note/siyuan/pull/17390 2026-04-05 15:32:32 +08:00
Jeffrey Chen
b12f0fdc86
Improve the layout style of the market list cards (#17390)
* 🎨 Improve the layout style of the market list cards https://github.com/siyuan-note/siyuan/issues/17358

* 🎨 Improve the layout style of the market list cards https://github.com/siyuan-note/siyuan/issues/17358
2026-04-04 17:29:48 +08:00
Vanessa
6b2b87895c Merge remote-tracking branch 'origin/dev' into dev 2026-04-04 15:04:07 +08:00
Vanessa
a0add9a0a4 🎨 https://github.com/siyuan-note/siyuan/issues/17354 2026-04-04 15:03:51 +08:00
Jeffrey Chen
209c29cdb0
♻️ Migrate some JSON parameter extraction to util.ParseJsonArgs (#17400) 2026-04-04 08:53:54 +08:00
Jeffrey Chen
9256842fca
♻️ ParseJsonArg adds null value check (#17399) 2026-04-04 08:53:09 +08:00
Jeffrey Chen
064754128b
♻️ Replace time.Now().Sub(start) with time.Since(start) (#17401) 2026-04-04 08:48:32 +08:00
dependabot[bot]
9b4b1d2bf0
⬆️ Bump lodash from 4.17.21 to 4.18.1 in /app (#17392)
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.21 to 4.18.1.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.18.1)

---
updated-dependencies:
- dependency-name: lodash
  dependency-version: 4.18.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-03 21:23:45 +08:00
Jeffrey Chen
20c1b9b387
🎨 Record the number of CSS and JS code snippets in the log (#17395) 2026-04-03 21:19:05 +08:00
Daniel
7771b1ca3b
🎨 mprove pasting of inline code containing backticks https://github.com/siyuan-note/siyuan/issues/17388
Signed-off-by: Daniel <845765@qq.com>
2026-04-03 21:12:04 +08:00
Daniel
8c52a91b42
🎨 Improve pasting inline code
Signed-off-by: Daniel <845765@qq.com>
2026-04-03 21:12:03 +08:00
Vanessa
db39ae5e4b 🎨 https://github.com/siyuan-note/siyuan/issues/17389 2026-04-03 19:19:36 +08:00
Vanessa
751b2515db Merge remote-tracking branch 'origin/dev' into dev 2026-04-03 19:07:57 +08:00
Vanessa
8be7301a71 🎨 https://github.com/siyuan-note/siyuan/issues/17389 2026-04-03 19:07:35 +08:00
Daniel
7278f4dddb
🎨 https://github.com/siyuan-note/siyuan/issues/17393
Signed-off-by: Daniel <845765@qq.com>
2026-04-03 19:04:03 +08:00
243 changed files with 3623 additions and 2472 deletions

View file

@ -1,4 +1,5 @@
[中文](https://github.com/siyuan-note/siyuan/blob/master/.github/CONTRIBUTING_zh_CN.md)
**English**
| [中文](CONTRIBUTING_zh_CN.md)
## Get the source code
@ -14,10 +15,10 @@ Install pnpm: `npm install -g pnpm@10.33.0`
Set the Electron mirror environment variable and install Electron:
* macOS/Linux: `ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/ pnpm install electron@40.8.5 -D`
* macOS/Linux: `ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/ pnpm install electron@40.9.1 -D`
* Windows:
* `SET ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/`
* `pnpm install electron@40.8.5 -D`
* `pnpm install electron@40.9.1 -D`
NPM mirror:
@ -27,7 +28,7 @@ NPM mirror:
Enter the app folder and execute:
* `pnpm install electron@40.8.5 -D`
* `pnpm install electron@40.9.1 -D`
* `pnpm run dev`
* `pnpm run start`

View file

@ -1,4 +1,5 @@
[English](https://github.com/siyuan-note/siyuan/blob/master/.github/CONTRIBUTING.md)
[English](CONTRIBUTING.md)
| **中文**
## 获取源码
@ -14,10 +15,10 @@
设置 Electron 镜像环境变量并安装 Electron
* macOS/Linux`ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/ pnpm install electron@40.8.5 -D`
* macOS/Linux`ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/ pnpm install electron@40.9.1 -D`
* Windows
* `SET ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/`
* `pnpm install electron@40.8.5 -D`
* `pnpm install electron@40.9.1 -D`
NPM 镜像:
@ -27,7 +28,7 @@ NPM 镜像:
进入 app 文件夹执行:
* `pnpm install electron@40.8.5 -D`
* `pnpm install electron@40.9.1 -D`
* `pnpm run dev`
* `pnpm run start`

1
.github/SECURITY.md vendored
View file

@ -7,6 +7,7 @@ https://github.com/siyuan-note/siyuan/security/advisories/new
Some areas we don't consider security vulnerabilities:
* Arbitrary file write: Writing files outside the workspace path (e.g., exporting files) is a common user need
* Chart/Formula/ABC rendering code injection: This is a common user need, for details please refer to https://github.com/siyuan-note/siyuan/pull/6917
* SQL injection
Thank you very much!

View file

@ -34,7 +34,7 @@ jobs:
- name: Create PKGBUILD
run: |
cat << EOF >> PKGBUILD
# maintainer: zxkmm (IHp4a21tQGhvdG1haWwuY29t)
# maintainer: SiYuan community (https://github.com/siyuan-note/siyuan/issues/new/choose)
# auto running on siyuan official repo
# PKGBUILD is modified from https://aur.archlinux.org/cgit/aur.git/tree/PKGBUILD?h=siyuan-appimage
# which is made by vvxxp8 <concatenate[g] the characters[x] in square[b] brackets[1] in[5] order[3] at gmail dot com>
@ -97,7 +97,7 @@ jobs:
EOF
- name: Publish AUR package
uses: KSXGitHub/github-actions-deploy-aur@v4.1.1
uses: KSXGitHub/github-actions-deploy-aur@v4.1.2
with:
pkgname: siyuan-bin
pkgbuild: ./PKGBUILD

View file

@ -1,4 +1,6 @@
{
"hyperlink": "ارتباط تشعبي",
"copyDoc": "نسخ النص كاملًا",
"position": "الموقع",
"insertColumnLeft1": "إدراج ${x} عمودًا إلى اليسار",
"insertColumnRight1": "إدراج ${x} عمودًا إلى اليمين",

View file

@ -1,4 +1,6 @@
{
"hyperlink": "Hyperlink",
"copyDoc": "Gesamten Text kopieren",
"position": "Position",
"insertColumnLeft1": "Füge ${x} Spalten links ein",
"insertColumnRight1": "Füge ${x} Spalten rechts ein",

View file

@ -1,4 +1,6 @@
{
"hyperlink": "Hyperlink",
"copyDoc": "Copy full document",
"position": "Position",
"insertColumnLeft1": "Insert ${x} column(s) to the left",
"insertColumnRight1": "Insert ${x} column(s) to the right",

View file

@ -1,4 +1,6 @@
{
"hyperlink": "Hipervínculo",
"copyDoc": "Copiar todo el texto",
"position": "Posición",
"insertColumnLeft1": "Insertar ${x} columnas a la izquierda",
"insertColumnRight1": "Insertar ${x} columnas a la derecha",

View file

@ -1,4 +1,6 @@
{
"hyperlink": "Hyperlien",
"copyDoc": "Copier tout le texte",
"position": "Position",
"insertColumnLeft1": "Insérer ${x} colonnes à gauche",
"insertColumnRight1": "Insérer ${x} colonnes à droite",
@ -1758,7 +1760,7 @@
"271": "Optimisation de l'index des données terminée, [%s] d'espace disque libéré",
"272": "Champ sans nom",
"273": "Ne créez pas lespace de travail à la racine de la partition, créez un nouveau dossier comme espace de travail",
"274": "Ce dossier contient dautres fichiers, créez un nouveau dossier comme espace de travail",
"274": "Ce dossier contient dautres fichiers, créez un nouveau dossier comme espace de travail",
"275": "Impossible d'ouvrir le document créé par une version plus récente. Veuillez mettre à jour vers la dernière version et réessayer",
"276": "Nettoyage des fichiers temporaires...",
"277": "Nettoyage des fichiers temporaires terminé, [%d] fichiers supprimés, [%s] d'espace disque libéré",

View file

@ -1,4 +1,6 @@
{
"hyperlink": "היפר־קישור",
"copyDoc": "העתק את כל הטקסט",
"position": "מיקום",
"insertColumnLeft1": "הוסף ${x} עמודות משמאל",
"insertColumnRight1": "הוסף ${x} עמודות מימין",

View file

@ -1,4 +1,6 @@
{
"hyperlink": "Collegamento ipertestuale",
"copyDoc": "Copia tutto il testo",
"position": "Posizione",
"insertColumnLeft1": "Inserisci ${x} colonne a sinistra",
"insertColumnRight1": "Inserisci ${x} colonne a destra",

View file

@ -1,4 +1,6 @@
{
"hyperlink": "ハイパーリンク",
"copyDoc": "全文をコピー",
"position": "位置",
"insertColumnLeft1": "左側に ${x} 列を挿入",
"insertColumnRight1": "右側に ${x} 列を挿入",

View file

@ -1,4 +1,6 @@
{
"hyperlink": "하이퍼링크",
"copyDoc": "전체 복사",
"position": "위치",
"insertColumnLeft1": "왼쪽에 ${x} 열 삽입",
"insertColumnRight1": "오른쪽에 ${x} 열 삽입",

View file

@ -1,4 +1,6 @@
{
"hyperlink": "Hiperłącze",
"copyDoc": "Kopiuj cały tekst",
"position": "Pozycja",
"insertColumnLeft1": "Wstaw ${x} kolumn po lewej",
"insertColumnRight1": "Wstaw ${x} kolumn po prawej",

View file

@ -1,4 +1,6 @@
{
"hyperlink": "Hiperlink",
"copyDoc": "Copiar todo o texto",
"position": "Posição",
"insertColumnLeft1": "Inserir ${x} colunas à esquerda",
"insertColumnRight1": "Inserir ${x} colunas à direita",

View file

@ -1,4 +1,6 @@
{
"hyperlink": "Гиперссылка",
"copyDoc": "Копировать весь текст",
"position": "Позиция",
"insertColumnLeft1": "Вставить слева ${x} столбцов",
"insertColumnRight1": "Вставить справа ${x} столбцов",

View file

@ -1,4 +1,6 @@
{
"hyperlink": "Hypertextový odkaz",
"copyDoc": "Kopírovať celý dokument",
"position": "Pozícia",
"insertColumnLeft1": "Vložiť ${x} stĺpec/stĺpce doľava",
"insertColumnRight1": "Vložiť ${x} stĺpec/stĺpce doprava",

View file

@ -1,4 +1,6 @@
{
"hyperlink": "Köprü",
"copyDoc": "Tüm metni kopyala",
"position": "Pozisyon",
"insertColumnLeft1": "Sol tarafa ${x} sütun ekle",
"insertColumnRight1": "Sağ tarafa ${x} sütun ekle",

View file

@ -1,4 +1,6 @@
{
"hyperlink": "超鏈接",
"copyDoc": "複製全文",
"position": "位置",
"insertColumnLeft1": "在左側插入 ${x} 欄",
"insertColumnRight1": "在右側插入 ${x} 欄",

View file

@ -1,4 +1,6 @@
{
"hyperlink": "超链接",
"copyDoc": "复制全文",
"position": "位置",
"insertColumnLeft1": "在左侧插入 ${x} 列",
"insertColumnRight1": "在右侧插入 ${x} 列",

View file

@ -29,7 +29,7 @@
--b3-font-family-graph: arial;
--b3-font-family-emoji: "Emojis Additional", emojis;
--b3-font-family-math: KaTeX_Math;
--b3-font-family-kbd: SFMono-Regular, Consolas, "Liberation Mono";
--b3-font-family-kbd: var(--b3-font-family-protyle);
--b3-font-size: 14px;
/* 顶部工具栏 */
@ -131,7 +131,8 @@
/* 阴影 */
--b3-point-shadow: 0 0 1px 0 rgba(0, 0, 0, .1), 0 0 2px 0 rgba(0, 0, 0, .2);
--b3-dialog-shadow: 0 8px 24px rgba(0, 0, 0, .2);
--b3-button-shadow: 0 5px 5px -3px rgb(0 0 0 / .2), 0 8px 10px 1px rgb(0 0 0 / .14), 0 3px 14px 2px rgb(0 0 0 / .12);
--b3-button-shadow: 0 1px 2px 0 rgb(0 0 0 / .3), 0 1px 3px 1px rgb(0 0 0 /.15);
--b3-button-active-shadow: 0 2px 3px 1px rgb(0 0 0 / .3), 0 2px 4px 2px rgb(0 0 0 /.15);
/* 图表颜色 */
--b3-graph-p-point: #076f7e;

View file

@ -2,7 +2,7 @@
"name": "daylight",
"author": "Vanessa",
"url": "https://github.com/Vanessa219",
"version": "1.1.0",
"version": "1.1.1",
"modes": [
"light"
]

View file

@ -28,7 +28,7 @@
--b3-font-family-graph: arial;
--b3-font-family-emoji: "Emojis Additional", emojis;
--b3-font-family-math: KaTeX_Math;
--b3-font-family-kbd: SFMono-Regular, Consolas, "Liberation Mono";
--b3-font-family-kbd: var(--b3-font-family-protyle);
--b3-font-size: 14px;
/* 顶部工具栏 */
@ -130,7 +130,8 @@
/* 阴影 */
--b3-point-shadow: inset 0 .5px .5px .5px rgba(255, 255, 255, .09), 0 3px 6px rgba(0, 0, 0, .04), 0 0 0 0 transparent;
--b3-dialog-shadow: 0 8px 24px #010409;
--b3-button-shadow: 0 5px 5px -3px rgb(0 0 0 / .2), 0 8px 10px 1px rgb(0 0 0 / .14), 0 3px 14px 2px rgb(0 0 0 / .12);
--b3-button-shadow: 0 1px 2px 0 rgb(0 0 0 / .3), 0 1px 3px 1px rgb(255 255 255 /.15);
--b3-button-active-shadow: 0 2px 3px 1px rgb(0 0 0 / .3), 0 2px 4px 2px rgb(255 255 255 /.15);
/* 图表颜色 */
--b3-graph-p-point: #076f7e;

View file

@ -2,7 +2,7 @@
"name": "midnight",
"author": "Vanessa",
"url": "https://github.com/Vanessa219",
"version": "1.1.0",
"version": "1.1.1",
"modes": [
"dark"
]

View file

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

View file

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

View file

@ -0,0 +1,46 @@
## Overview
This version improves some details.
## Changelogs
Below are the detailed changes in this version.
### Enhancement
* [Add a `Copy full document` option to the document block menu](https://github.com/siyuan-note/siyuan/issues/17352)
* [The list in the backlink panel no longer collapses automatically after pasting](https://github.com/siyuan-note/siyuan/issues/17362)
* [Improve pasting link](https://github.com/siyuan-note/siyuan/pull/17378)
* [Improve block icon render when list items contain blockquotes or callouts](https://github.com/siyuan-note/siyuan/issues/17387)
* [Improve pasting of inline code containing backticks and ampersands](https://github.com/siyuan-note/siyuan/issues/17388)
* [Improve button box-shadow](https://github.com/siyuan-note/siyuan/issues/17389)
* [Improve marketplace list cards](https://github.com/siyuan-note/siyuan/pull/17390)
* [Improve block ref exporting](https://github.com/siyuan-note/siyuan/issues/17397)
* [`Optimize typography` ignores full-width characters](https://github.com/siyuan-note/siyuan/issues/17417)
* [Move pagination and navigation buttons to the top-left of the Flashcard Management window](https://github.com/siyuan-note/siyuan/issues/17422)
* [Support displaying full Dock panel titles and action buttons](https://github.com/siyuan-note/siyuan/issues/17424)
* [Improve the display position of block gutter](https://github.com/siyuan-note/siyuan/issues/17432)
* [The loading icon no longer covers the entire cloud configuration page](https://github.com/siyuan-note/siyuan/pull/17434)
* [Improve split-screen layout](https://github.com/siyuan-note/siyuan/issues/17435)
* [Downloaded marketplace packages no longer fall back to fetching the online README](https://github.com/siyuan-note/siyuan/pull/17464)
### Bugfix
* [Default workspace data will be lost on macOS](https://github.com/siyuan-note/siyuan/issues/17430)
* [Dragging a block to the Backlinks panel causes an error](https://github.com/siyuan-note/siyuan/issues/17437)
* [Fix some security vulnerabilities](https://github.com/siyuan-note/siyuan/issues/17443)
* [Markdown.zip import error on Android](https://github.com/siyuan-note/siyuan/issues/17453)
* [The entire block disappears after dragging a block within the callout block](https://github.com/siyuan-note/siyuan/issues/17467)
### Development
* [Task lists support the `data-task` status attribute](https://github.com/siyuan-note/siyuan/issues/17343)
* [Add a `type` parameter to the plugin API `getAllTabs`](https://github.com/siyuan-note/siyuan/issues/17354)
* [Add kernel API `/api/file/workspaceCopyFiles`](https://github.com/siyuan-note/siyuan/pull/17421)
* [Add kernel API `/api/block/updateTaskListItemMarker`](https://github.com/siyuan-note/siyuan/issues/17451)
* [Add kernel API `/api/block/batchUpdateTaskListItemMarker`](https://github.com/siyuan-note/siyuan/pull/17461)
## Download
* [B3log](https://b3log.org/siyuan/en/download.html)
* [GitHub](https://github.com/siyuan-note/siyuan/releases)

View file

@ -0,0 +1,46 @@
## 概述
此版本改進了一些細節。
## 變更記錄
以下是此版本中的詳細變更。
### 改進功能
* [在文件區塊選單中新增 `複製全文` 選項](https://github.com/siyuan-note/siyuan/issues/17352)
* [反向連結面板中的清單在貼上後不再自動折疊](https://github.com/siyuan-note/siyuan/issues/17362)
* [改進貼上連結](https://github.com/siyuan-note/siyuan/pull/17378)
* [改進當清單項目包含區塊引用或提示區塊時的區塊標渲染](https://github.com/siyuan-note/siyuan/issues/17387)
* [改進包含反引號和與號的行級程式碼的貼上](https://github.com/siyuan-note/siyuan/issues/17388)
* [改進按鈕陰影效果](https://github.com/siyuan-note/siyuan/issues/17389)
* [改進市集清單卡](https://github.com/siyuan-note/siyuan/pull/17390)
* [改進區塊引用導出](https://github.com/siyuan-note/siyuan/issues/17397)
* [`優化排版` 忽略全角字元](https://github.com/siyuan-note/siyuan/issues/17417)
* [將閃卡管理視窗中的分頁和導覽按鈕移到左上角](https://github.com/siyuan-note/siyuan/issues/17422)
* [支援顯示完整的停靠列面板標題和操作按鈕](https://github.com/siyuan-note/siyuan/issues/17424)
* [改進塊標的顯示位置](https://github.com/siyuan-note/siyuan/issues/17432)
* [載入圖示不再覆蓋整個雲端設定介面](https://github.com/siyuan-note/siyuan/pull/17434)
* [改進分割畫面佈局](https://github.com/siyuan-note/siyuan/issues/17435)
* [已下載的市集包不再回退取得線上 README](https://github.com/siyuan-note/siyuan/pull/17464)
### 修復缺陷
* [macOS 上預設工作空間資料會遺失](https://github.com/siyuan-note/siyuan/issues/17430)
* [將區塊拖曳到反向連結面板時會導致報錯](https://github.com/siyuan-note/siyuan/issues/17437)
* [修復一些安全漏洞](https://github.com/siyuan-note/siyuan/issues/17443)
* [Android 上導入 Markdown.zip 出錯](https://github.com/siyuan-note/siyuan/issues/17453)
* [在提示區塊內部拖曳區塊後整個區塊會消失](https://github.com/siyuan-note/siyuan/issues/17467)
### 開發者
* [任務清單支援 `data-task` 狀態屬性](https://github.com/siyuan-note/siyuan/issues/17343)
* [為插件 API `getAllTabs` 新增 `type` 參數](https://github.com/siyuan-note/siyuan/issues/17354)
* [新增核心 API `/api/file/workspaceCopyFiles`](https://github.com/siyuan-note/siyuan/pull/17421)
* [新增內核 API `/api/block/updateTaskListItemMarker`](https://github.com/siyuan-note/siyuan/issues/17451)
* [新增核心 API `/api/block/batchUpdateTaskListItemMarker`](https://github.com/siyuan-note/siyuan/pull/17461)
## 下載
* [B3log](https://b3log.org/siyuan/download.html)
* [GitHub](https://github.com/siyuan-note/siyuan/releases)

View file

@ -0,0 +1,46 @@
## 概述
此版本改进了一些细节。
## 变更记录
以下是此版本中的详细变更。
### 改进功能
* [在文档块菜单中添加 `复制全文` 选项](https://github.com/siyuan-note/siyuan/issues/17352)
* [反向链接面板中的列表在粘贴后不再自动折叠](https://github.com/siyuan-note/siyuan/issues/17362)
* [改进粘贴链接](https://github.com/siyuan-note/siyuan/pull/17378)
* [改进当列表项包含块引用或提示块时的块标渲染](https://github.com/siyuan-note/siyuan/issues/17387)
* [改进包含反引号和与号的行级代码的粘贴](https://github.com/siyuan-note/siyuan/issues/17388)
* [改进按钮阴影效果](https://github.com/siyuan-note/siyuan/issues/17389)
* [改进集市列表卡片](https://github.com/siyuan-note/siyuan/pull/17390)
* [改进块引用导出](https://github.com/siyuan-note/siyuan/issues/17397)
* [`优化排版` 忽略全角字符](https://github.com/siyuan-note/siyuan/issues/17417)
* [将闪卡管理窗口中的分页和导航按钮移动到左上角](https://github.com/siyuan-note/siyuan/issues/17422)
* [支持显示完整的停靠栏面板标题和操作按钮](https://github.com/siyuan-note/siyuan/issues/17424)
* [改进块标的显示位置](https://github.com/siyuan-note/siyuan/issues/17432)
* [加载图标不再覆盖整个云端配置界面](https://github.com/siyuan-note/siyuan/pull/17434)
* [改进分屏布局](https://github.com/siyuan-note/siyuan/issues/17435)
* [已下载的集市包不再回退获取在线 README](https://github.com/siyuan-note/siyuan/pull/17464)
### 修复缺陷
* [macOS 上默认工作空间数据会丢失](https://github.com/siyuan-note/siyuan/issues/17430)
* [将块拖动到反向链接面板时会导致报错](https://github.com/siyuan-note/siyuan/issues/17437)
* [修复一些安全漏洞](https://github.com/siyuan-note/siyuan/issues/17443)
* [Android 上导入 Markdown.zip 出错](https://github.com/siyuan-note/siyuan/issues/17453)
* [在提示块内部拖动块后整个块会消失](https://github.com/siyuan-note/siyuan/issues/17467)
### 开发者
* [任务列表支持 `data-task` 状态属性](https://github.com/siyuan-note/siyuan/issues/17343)
* [为插件 API `getAllTabs` 添加 `type` 参数](https://github.com/siyuan-note/siyuan/issues/17354)
* [新增内核 API `/api/file/workspaceCopyFiles`](https://github.com/siyuan-note/siyuan/pull/17421)
* [新增内核 API `/api/block/updateTaskListItemMarker`](https://github.com/siyuan-note/siyuan/issues/17451)
* [新增内核 API `/api/block/batchUpdateTaskListItemMarker`](https://github.com/siyuan-note/siyuan/pull/17461)
## 下载
* [B3log](https://b3log.org/siyuan/download.html)
* [GitHub](https://github.com/siyuan-note/siyuan/releases)

View file

@ -0,0 +1,52 @@
## Overview
This version improves some details.
## Changelogs
Below are the detailed changes in this version.
### Enhancement
* [Treat the renaming of tags, bookmarks and assets as a data history `Replace` operation](https://github.com/siyuan-note/siyuan/issues/17407)
* [Improve appearance settings for inline text on mobile](https://github.com/siyuan-note/siyuan/issues/17477)
* [Editor toolbar does not hide when clicking outside it on mobile](https://github.com/siyuan-note/siyuan/issues/17478)
* [Improve task list item markdown indexing for `data-task` marker](https://github.com/siyuan-note/siyuan/issues/17502)
* [Easy way to switch between tags](https://github.com/siyuan-note/siyuan/issues/17505)
* [Improve decoding of anchor text when pasting hyperlinks](https://github.com/siyuan-note/siyuan/issues/17513)
* [Improve `kbd` font `--b3-font-family-kbd`](https://github.com/siyuan-note/siyuan/issues/17517)
* [Change default Redo shortcut to `⇧⌘Z` on macOS](https://github.com/siyuan-note/siyuan/issues/17518)
* [Improve cursor positioning after Undo in tables](https://github.com/siyuan-note/siyuan/issues/17532)
* [Optimize code block line number rendering for better performance](https://github.com/siyuan-note/siyuan/issues/17542)
* [Improve data indexing](https://github.com/siyuan-note/siyuan/issues/17543)
* [Improve input method compatibility](https://github.com/siyuan-note/siyuan/issues/17546)
* [Improve the clipping extension to resolve issues where images were too large to be clipped](https://github.com/siyuan-note/siyuan/issues/17547)
### Bugfix
* [Click the editor may cause it to jump to the top on iOS](https://github.com/siyuan-note/siyuan/issues/17454)
* [The IFrame block cannot be edited](https://github.com/siyuan-note/siyuan/issues/17486)
* [Pasting links into database assets fields creates duplicate entries](https://github.com/siyuan-note/siyuan/issues/17492)
* [The outline does not refresh automatically](https://github.com/siyuan-note/siyuan/issues/17493)
* [Events are missing in the cloud configuration interface](https://github.com/siyuan-note/siyuan/issues/17495)
* [A blank area appears after splitting the tabs](https://github.com/siyuan-note/siyuan/issues/17499)
* [Fix some security vulnerabilities](https://github.com/siyuan-note/siyuan/issues/17503)
* [Missing `window.siyuan.config` at startup causes an error](https://github.com/siyuan-note/siyuan/issues/17508)
* [The `Ref` option in the slash menu is not searchable](https://github.com/siyuan-note/siyuan/issues/17510)
* [Authentication failed due to an excessively long cookie](https://github.com/siyuan-note/siyuan/issues/17512)
* [Fix outline issues in editor Preview Mode](https://github.com/siyuan-note/siyuan/issues/17551)
### Refactor
* [Upgrade to Electron v40.9.1](https://github.com/siyuan-note/siyuan/issues/17501)
### Development
* [Error occurs in standalone windows after `uninstall` plugins](https://github.com/siyuan-note/siyuan/issues/17509)
* [Add the document opening mode parameter `doc.mode` to `openTab`](https://github.com/siyuan-note/siyuan/issues/17523)
* [Add `switchMode` method to Protyle instance](https://github.com/siyuan-note/siyuan/issues/17552)
## Download
* [B3log](https://b3log.org/siyuan/en/download.html)
* [GitHub](https://github.com/siyuan-note/siyuan/releases)

View file

@ -0,0 +1,52 @@
## 概述
此版本改進了一些細節。
## 變更記錄
以下是此版本中的詳細變更。
### 改進功能
* [將標籤、書籤和資源的重新命名視為資料歷史中的 `Replace` 操作](https://github.com/siyuan-note/siyuan/issues/17407)
* [改進行動端行級文字的外觀設定](https://github.com/siyuan-note/siyuan/issues/17477)
* [行動端點選編輯器外部時工具列不會隱藏](https://github.com/siyuan-note/siyuan/issues/17478)
* [改進任務清單項目中 `data-task` 標記的 Markdown 索引](https://github.com/siyuan-note/siyuan/issues/17502)
* [改進標籤切換](https://github.com/siyuan-note/siyuan/issues/17505)
* [改進貼上超連結時對錨文本的解碼](https://github.com/siyuan-note/siyuan/issues/17513)
* [改良 `kbd` 字體 `--b3-font-family-kbd`](https://github.com/siyuan-note/siyuan/issues/17517)
* [將 macOS 上預設的重做快捷鍵改為 `⇧⌘Z`](https://github.com/siyuan-note/siyuan/issues/17518)
* [改進表格中撤銷後的遊標定位](https://github.com/siyuan-note/siyuan/issues/17532)
* [最佳化程式碼區塊行號渲染以提升效能](https://github.com/siyuan-note/siyuan/issues/17542)
* [改進資料索引](https://github.com/siyuan-note/siyuan/issues/17543)
* [改進輸入法相容性](https://github.com/siyuan-note/siyuan/issues/17546)
* [改進剪藏擴充解決圖片過大無法剪藏](https://github.com/siyuan-note/siyuan/issues/17547)
### 修復缺陷
* [在 iOS 上點擊編輯器可能會導致頁面跳到頂部](https://github.com/siyuan-note/siyuan/issues/17454)
* [IFrame 區塊無法編輯](https://github.com/siyuan-note/siyuan/issues/17486)
* [將連結貼到資料庫資源欄位時會建立重複條目](https://github.com/siyuan-note/siyuan/issues/17492)
* [大綱不會自動刷新](https://github.com/siyuan-note/siyuan/issues/17493)
* [雲端設定介面中事件缺失](https://github.com/siyuan-note/siyuan/issues/17495)
* [分割標籤頁後出現空白區域](https://github.com/siyuan-note/siyuan/issues/17499)
* [修復一些安全漏洞](https://github.com/siyuan-note/siyuan/issues/17503)
* [啟動時缺少 `window.siyuan.config` 會導致報錯](https://github.com/siyuan-note/siyuan/issues/17508)
* [斜線選單中的 `引用` 選項無法搜尋](https://github.com/siyuan-note/siyuan/issues/17510)
* [由於 Cookie 過長導致授權頁驗證失敗](https://github.com/siyuan-note/siyuan/issues/17512)
* [修復預覽模式下大綱的問題](https://github.com/siyuan-note/siyuan/issues/17551)
### 開發重構
* [升級至 Electron v40.9.1](https://github.com/siyuan-note/siyuan/issues/17501)
### 開發者
* [獨立視窗中卸載插件報錯](https://github.com/siyuan-note/siyuan/issues/17509)
* [為 `openTab` 新增文件開啟模式參數 `doc.mode`](https://github.com/siyuan-note/siyuan/issues/17523)
* [為 Protyle 實例新增 `switchMode` 方法](https://github.com/siyuan-note/siyuan/issues/17552)
## 下載
* [B3log](https://b3log.org/siyuan/download.html)
* [GitHub](https://github.com/siyuan-note/siyuan/releases)

View file

@ -0,0 +1,52 @@
## 概述
此版本改进了一些细节。
## 变更记录
以下是此版本中的详细变更。
### 改进功能
* [将标签、书签和资源的重命名视为数据历史中的 `Replace` 操作](https://github.com/siyuan-note/siyuan/issues/17407)
* [改进移动端行级文本的外观设置](https://github.com/siyuan-note/siyuan/issues/17477)
* [移动端点击编辑器外部时工具栏不会隐藏](https://github.com/siyuan-note/siyuan/issues/17478)
* [改进任务列表项中 `data-task` 标记的 Markdown 索引](https://github.com/siyuan-note/siyuan/issues/17502)
* [改进标签切换](https://github.com/siyuan-note/siyuan/issues/17505)
* [改进粘贴超链接时对锚文本的解码](https://github.com/siyuan-note/siyuan/issues/17513)
* [改进 `kbd` 字体 `--b3-font-family-kbd`](https://github.com/siyuan-note/siyuan/issues/17517)
* [将 macOS 上默认的重做快捷键改为 `⇧⌘Z`](https://github.com/siyuan-note/siyuan/issues/17518)
* [改进表格中撤销后的光标定位](https://github.com/siyuan-note/siyuan/issues/17532)
* [优化代码块行号渲染以提升性能](https://github.com/siyuan-note/siyuan/issues/17542)
* [改进数据索引](https://github.com/siyuan-note/siyuan/issues/17543)
* [改进输入法兼容性](https://github.com/siyuan-note/siyuan/issues/17546)
* [改进剪藏扩展解决图片过大无法剪藏](https://github.com/siyuan-note/siyuan/issues/17547)
### 修复缺陷
* [在 iOS 上点击编辑器可能导致页面跳到顶部](https://github.com/siyuan-note/siyuan/issues/17454)
* [IFrame 块无法编辑](https://github.com/siyuan-note/siyuan/issues/17486)
* [将链接粘贴到数据库资源字段时会创建重复条目](https://github.com/siyuan-note/siyuan/issues/17492)
* [大纲不会自动刷新](https://github.com/siyuan-note/siyuan/issues/17493)
* [云端配置界面中事件缺失](https://github.com/siyuan-note/siyuan/issues/17495)
* [拆分标签页后出现空白区域](https://github.com/siyuan-note/siyuan/issues/17499)
* [修复一些安全漏洞](https://github.com/siyuan-note/siyuan/issues/17503)
* [启动时缺少 `window.siyuan.config` 会导致报错](https://github.com/siyuan-note/siyuan/issues/17508)
* [斜杠菜单中的 `引用` 选项无法搜索](https://github.com/siyuan-note/siyuan/issues/17510)
* [由于 Cookie 过长导致授权页验证失败](https://github.com/siyuan-note/siyuan/issues/17512)
* [修复预览模式下大纲的问题](https://github.com/siyuan-note/siyuan/issues/17551)
### 开发重构
* [升级到 Electron v40.9.1](https://github.com/siyuan-note/siyuan/issues/17501)
### 开发者
* [独立窗口中卸载插件报错](https://github.com/siyuan-note/siyuan/issues/17509)
* [为 `openTab` 添加文档打开模式参数 `doc.mode`](https://github.com/siyuan-note/siyuan/issues/17523)
* [为 Protyle 实例添加 `switchMode` 方法](https://github.com/siyuan-note/siyuan/issues/17552)
## 下载
* [B3log](https://b3log.org/siyuan/download.html)
* [GitHub](https://github.com/siyuan-note/siyuan/releases)

View file

@ -240,9 +240,10 @@
'win32': 'Windows',
'linux': 'Linux'
}[process.platform] || process.platform;
const release = typeof process.getSystemVersion === 'function'
? process.getSystemVersion() // Electron 提供,系统版本
: os.release(); // Node.js 提供,内核版本
// Windows 系统版本判断
const release = os.release();
if (process.platform === 'win32') {
const versionParts = release.split('.'); // 10.0.22000
if (versionParts.length >= 3) {

View file

@ -59,6 +59,7 @@
}
.b3-button {
cursor: pointer;
color: #fff;
border-radius: 6px;
line-height: 20px;
@ -68,21 +69,20 @@
display: inline-flex;
align-items: center;
justify-content: center;
transition: box-shadow 280ms cubic-bezier(0.4, 0, 0.2, 1);
transition: box-shadow 280ms ease;
border: 0;
box-sizing: border-box;
text-align: center;
width: 96px;
cursor: pointer;
}
.b3-button:hover, .b3-button:focus {
text-decoration: none;
box-shadow: 0 5px 5px -3px rgb(0 0 0 / .2), 0 8px 10px 1px rgb(0 0 0 / .14), 0 3px 14px 2px rgb(0 0 0 / .12);
box-shadow: 0 1px 2px 0 rgb(0 0 0 / .3), 0 1px 3px 1px rgb(0 0 0 /.15);
}
.b3-button:active {
box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2), 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12);
box-shadow: 0 2px 3px 1px rgb(0 0 0 / .3), 0 2px 4px 2px rgb(0 0 0 /.15);
}
.b3-label {
@ -217,6 +217,14 @@
background-color: #3573f0;
}
.b3-button:hover, .b3-button:focus {
box-shadow: 0 1px 2px 0 rgb(0 0 0 / .3), 0 1px 3px 1px rgb(255 255 255 /.15);
}
.b3-button:active {
box-shadow: 0 2px 3px 1px rgb(0 0 0 / .3), 0 2px 4px 2px rgb(255 255 255 /.15);
}
.b3-label {
box-shadow: 0 15px 0 0 #1e1e1e, 0 16px 0 0 #363636;
}

View file

@ -55,8 +55,9 @@ const isOpenAsHidden = function () {
remote.initialize();
app.setPath("userData", app.getPath("userData") + "-Electron"); // `~/.config` 下 Electron 相关文件夹名称改为 `SiYuan-Electron` https://github.com/siyuan-note/siyuan/issues/3349
fs.rmSync(app.getPath("appData") + "/" + app.name, {recursive: true}); // 删除自动创建的应用目录 https://github.com/siyuan-note/siyuan/issues/13150
// Electron 相关文件夹名称改为 `SiYuan-Electron` https://github.com/siyuan-note/siyuan/issues/3349
// getPath("userData") 会创建空的 SiYuan 目录,改为 app.getPath("appData")
app.setPath("userData", path.join(app.getPath("appData"), app.getName() + "-Electron"));
if (process.platform === "win32") {
// Windows 需要设置 AppUserModelId 才能正确显示应用名称和应用图标 https://github.com/siyuan-note/siyuan/issues/17022
@ -115,17 +116,9 @@ const windowNavigate = (currentWindow, windowType) => {
if (url.startsWith(localServer)) {
try {
const pathname = new URL(url).pathname;
// 所有窗口都允许认证页面
if (pathname === "/check-auth" || pathname === "/") {
return;
}
if (pathname === "/stage/build/app/" && windowType === "app") {
return;
}
if (pathname === "/stage/build/app/window.html" && windowType === "window") {
return;
}
if (pathname.startsWith("/export/temp/") && windowType === "export") {
if (windowType === "app" && ["/", "/stage/build/app/", "/check-auth"].includes(pathname) ||
(windowType === "window" && ["/stage/build/app/window.html", "/check-auth"].includes(pathname)) ||
(windowType === "export" && pathname.startsWith("/export/temp/"))) {
return;
}
} catch (e) {

View file

@ -1,6 +1,6 @@
{
"name": "SiYuan",
"version": "3.6.3",
"version": "3.6.5",
"description": "Refactor your thinking",
"homepage": "https://b3log.org/siyuan",
"main": "./electron/main.js",
@ -57,7 +57,7 @@
"clean-webpack-plugin": "^4.0.0",
"css-loader": "^7.1.2",
"dayjs": "^1.11.5",
"electron": "40.8.5",
"electron": "40.9.1",
"electron-builder": "26.0.12",
"encoding": "^0.1.13",
"esbuild-loader": "^3.0.1",

View file

@ -10,7 +10,7 @@ importers:
dependencies:
'@electron/remote':
specifier: ^2.1.3
version: 2.1.3(electron@40.8.5)
version: 2.1.3(electron@40.9.1)
devDependencies:
'@eslint/eslintrc':
specifier: ^3.3.1
@ -40,8 +40,8 @@ importers:
specifier: ^1.11.5
version: 1.11.19
electron:
specifier: 40.8.5
version: 40.8.5
specifier: 40.9.1
version: 40.9.1
electron-builder:
specifier: 26.0.12
version: 26.0.12(electron-builder-squirrel-windows@26.0.12)
@ -1186,8 +1186,8 @@ packages:
resolution: {integrity: sha512-bO3y10YikuUwUuDUQRM4KfwNkKhnpVO7IPdbsrejwN9/AABJzzTQ4GeHwyzNSrVO+tEH3/Np255a3sVZpZDjvg==}
engines: {node: '>=8.0.0'}
electron@40.8.5:
resolution: {integrity: sha512-pgTY/VPQKaiU4sTjfU96iyxCXrFm4htVPCMRT4b7q9ijNTRgtLmLvcmzp2G4e7xDrq9p7OLHSmu1rBKFf6Y1/A==}
electron@40.9.1:
resolution: {integrity: sha512-dgUqGjpTJeLZQEbvZQlnjMtPCUfOGRBNJIYjw8yC2ZN9O1QS172r09trhLke+rC8JCLBGbf2DeU63AArd0tbhQ==}
engines: {node: '>= 12.20.55'}
hasBin: true
@ -1476,7 +1476,7 @@ packages:
glob@8.1.0:
resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==}
engines: {node: '>=12'}
deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
deprecated: Glob versions prior to v9 are no longer supported
global-agent@3.0.0:
resolution: {integrity: sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==}
@ -1815,12 +1815,12 @@ packages:
lodash.merge@4.6.2:
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
lodash@4.17.21:
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
lodash@4.17.23:
resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==}
lodash@4.18.1:
resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==}
log-symbols@4.1.0:
resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==}
engines: {node: '>=10'}
@ -2835,9 +2835,9 @@ snapshots:
- bluebird
- supports-color
'@electron/remote@2.1.3(electron@40.8.5)':
'@electron/remote@2.1.3(electron@40.9.1)':
dependencies:
electron: 40.8.5
electron: 40.9.1
'@electron/universal@2.0.1':
dependencies:
@ -3957,14 +3957,14 @@ snapshots:
'@electron/asar': 3.4.1
debug: 4.4.3
fs-extra: 7.0.1
lodash: 4.17.21
lodash: 4.18.1
temp: 0.9.4
optionalDependencies:
'@electron/windows-sign': 1.2.2
transitivePeerDependencies:
- supports-color
electron@40.8.5:
electron@40.9.1:
dependencies:
'@electron/get': 2.0.3
'@types/node': 24.12.0
@ -4657,10 +4657,10 @@ snapshots:
lodash.merge@4.6.2: {}
lodash@4.17.21: {}
lodash@4.17.23: {}
lodash@4.18.1: {}
log-symbols@4.1.0:
dependencies:
chalk: 4.1.2

View file

@ -85,7 +85,7 @@
transition: var(--b3-transition), opacity .3s cubic-bezier(0, 0, .2, 1) 0ms;
line-height: 14px;
&:hover:not([disabled]):not(.ft__primary):not(.block__icon--warning),
&:hover:not([disabled]):not(.block__icon--text):not(.block__icon--warning),
&--active {
color: var(--b3-theme-on-background);
background-color: var(--b3-list-icon-hover);

View file

@ -260,7 +260,7 @@
}
&__content {
margin-top: -15px;
margin: 1px 16px;
}
&__readme {

View file

@ -9,7 +9,7 @@
display: inline-flex;
align-items: center;
justify-content: center;
transition: box-shadow 280ms cubic-bezier(.4, 0, .2, 1);
transition: box-shadow 280ms ease;
border: 0;
box-sizing: border-box;
text-align: center;
@ -29,7 +29,7 @@
}
&:active {
box-shadow: 0 5px 5px -3px rgba(0, 0, 0, .2), 0 8px 10px 1px rgba(0, 0, 0, .14), 0 3px 14px 2px rgba(0, 0, 0, .12);
box-shadow: var(--b3-button-active-shadow)
}
&--progress {

View file

@ -4,31 +4,28 @@
box-shadow: var(--b3-point-shadow);
background-color: var(--b3-theme-surface);
border-radius: var(--b3-border-radius);
margin: 16px;
overflow: hidden;
position: relative;
transition: var(--b3-transition);
cursor: pointer;
display: flex;
&--wrap {
flex: 1;
margin: 16px 0 0 16px;
min-width: 342px;
}
&:hover {
background-color: var(--b3-list-hover);
}
&s {
display: flex;
flex-wrap: wrap;
margin: 0 16px 16px 0;
display: grid;
gap: 16px;
grid-template-columns: repeat(auto-fill, minmax(min(100%, 342px), 1fr));
&--nowrap {
grid-template-columns:1fr;
}
}
&--current {
background-color: var(--b3-theme-primary-lightest)
background-color: var(--b3-theme-primary-lightest);
}
&--disabled {
@ -48,7 +45,7 @@
}
&__info {
padding: 16px 16px 4px;
padding: 16px 16px 0;
line-height: 18px;
&--left {
@ -60,17 +57,23 @@
&__desc {
color: var(--b3-theme-on-surface);
font-size: 12px;
margin-top: 4px;
text-autospace: normal;
margin-top: 8px;
max-height: 54px;
@include mixin.text-clamp(3);
}
&__actions {
padding: 0 16px 14px 16px;
display: flex;
box-sizing: border-box;
font-size: 12px;
line-height: 14px;
padding: 3px 11px 11px;
&:not(.b3-card__actions--right) .block__icon svg {
height: 12px;
width: 12px;
}
&--right {
padding-left: 0;

View file

@ -248,13 +248,34 @@ html[data-frontend="browser-desktop"] {
}
.file-tree {
.block__icons .block__icon,
&:not(.fullscreen) .block__icons .fn__space {
display: none;
transition: opacity .3s cubic-bezier(0, 0, .2, 1) 0ms, display .3s cubic-bezier(0, 0, .2, 1) 0ms allow-discrete;
}
.block__logo::-webkit-scrollbar {
display: none;
}
&:hover .block__icons .fn__space {
display: block;
}
&:hover .block__icons .block__icon:not([disabled]),
&:not(.fullscreen):hover .block__icons .fn__space,
&.fullscreen .block__icons .block__icon:not([disabled]) {
opacity: 1;
display: block;
@starting-style {
opacity: 0;
}
}
&:hover .block__icons .block__icon[disabled] {
opacity: .38;
display: block;
cursor: not-allowed;
}
&__close {

View file

@ -96,6 +96,14 @@ const hasKeymap = (keymap: Record<string, IKeymapItem>, key1: "general" | "edito
};
export const correctHotkey = (app: App) => {
if (!["darwin", "ios"].includes(window.siyuan.config.system.os)) {
["fileTree", "outline", "bookmark", "tag", "dailyNote", "inbox", "backlinks",
"graphView", "globalGraph", "riffCard"].forEach(key => {
Constants.SIYUAN_KEYMAP.general[key].custom = Constants.SIYUAN_KEYMAP.general[key].default =
Constants.SIYUAN_KEYMAP.general[key].default.replace("⌃", "⌥");
});
Constants.SIYUAN_KEYMAP.editor.general.redo.custom = Constants.SIYUAN_KEYMAP.editor.general.redo.default = "⌘Y";
}
const matchKeymap1 = matchKeymap(Constants.SIYUAN_KEYMAP.general, "general");
const matchKeymap2 = matchKeymap(Constants.SIYUAN_KEYMAP.editor.general, "editor", "general");
const matchKeymap3 = matchKeymap(Constants.SIYUAN_KEYMAP.editor.insert, "editor", "insert");

View file

@ -30,7 +30,7 @@ import {goBack, goForward} from "../../util/backForward";
import {getDisplayName, getNotebookName} from "../../util/pathName";
import {openFileById} from "../../editor/util";
import {getAllDocks, getAllModels, getAllTabs} from "../../layout/getAll";
import {focusBlock, focusByOffset, focusByRange, getSelectionOffset} from "../../protyle/util/selection";
import {focusBlock, focusByRange} from "../../protyle/util/selection";
import {initFileMenu, initNavigationMenu} from "../../menus/navigation";
import {bindMenuKeydown} from "../../menus/Menu";
import {Dialog} from "../../dialog";
@ -440,15 +440,12 @@ const editKeydown = (app: App, event: KeyboardEvent) => {
}
if (matchHotKey(window.siyuan.config.keymap.editor.general.outline.custom, event)) {
event.preventDefault();
const offset = getSelectionOffset(target);
openOutline({
app,
rootId: protyle.block.rootID,
title: protyle.options.render.title ? (protyle.title.editElement.textContent || window.siyuan.languages.untitled) : "",
isPreview: !protyle.preview.element.classList.contains("fn__none")
});
// switchWnd 后range会被清空需要重新设置
focusByOffset(target, offset.start, offset.end);
return true;
}
if (matchHotKey(window.siyuan.config.keymap.editor.general.copyPlainText.custom, event)) {

View file

@ -4,15 +4,36 @@ import {hasClosestBlock, hasClosestByClassName, hasClosestByTag} from "../../pro
import {getColIndex} from "../../protyle/util/table";
const getRightBlock = (element: HTMLElement, x: number, y: number) => {
let index = 1;
let left = x + 34;
let nodeElement = element;
if (nodeElement && nodeElement.classList.contains("protyle-action")) {
return nodeElement;
}
while (nodeElement && (nodeElement.classList.contains("list") || nodeElement.classList.contains("li"))) {
nodeElement = document.elementFromPoint(x + 73 * index, y) as HTMLElement;
let lastNodeElement;
while (nodeElement && (
nodeElement.classList.contains("list") || nodeElement.classList.contains("li") ||
nodeElement.classList.contains("bq") || nodeElement.classList.contains("callout")
)) {
nodeElement = document.elementFromPoint(left, y) as HTMLElement;
const calloutInfoElement = hasClosestByClassName(nodeElement, "callout-info");
if (calloutInfoElement) {
nodeElement = calloutInfoElement;
break;
}
nodeElement = hasClosestBlock(nodeElement) as HTMLElement;
index++;
if (lastNodeElement && lastNodeElement === nodeElement) {
break;
}
lastNodeElement = nodeElement;
if (nodeElement) {
if (nodeElement.classList.contains("bq") || nodeElement.classList.contains("callout")) {
left += 10;
} else {
left += 34;
}
} else {
left += 34;
}
}
return nodeElement;
};

View file

@ -98,6 +98,9 @@ export const onGetConfig = (isStart: boolean, app: App) => {
}
});
}
window.siyuan.dialogs.forEach(item => {
item.resize();
});
}, Constants.TIMEOUT_RESIZE);
});
};

View file

@ -23,14 +23,14 @@ export const viewCards = (app: App, deckID: string, title: string, deckType: "Tr
const dialog = new Dialog({
positionId: Constants.DIALOG_VIEWCARDS,
content: `<div class="fn__flex-column" style="height: 100%">
<div class="block__icons">
<span class="fn__flex-1 fn__flex-center resize__move">${escapeHtml(title)}</span>
<div class="block__icons" style="border-bottom: 1px solid var(--b3-border-color)">
<span class="fn__flex-center resize__move">${escapeHtml(title)}</span>
<span class="fn__space${(deckType === "" && deckID === "") ? " fn__none" : ""}"></span>
<span data-type="resetAll" data-position="north" class="block__icon block__icon--show ariaLabel${(deckType === "" && deckID === "") ? " fn__none" : ""}" aria-label="${window.siyuan.languages.reset}"><svg><use xlink:href='#iconUndo'></use></svg></span>
<span class="fn__space"></span>
<span data-type="resetAll" class="block__icon block__icon--show b3-tooltips b3-tooltips__w${(deckType === "" && deckID === "") ? " fn__none" : ""}" aria-label="${window.siyuan.languages.reset}"><svg><use xlink:href='#iconUndo'></use></svg></span>
<span data-type="previous" data-position="north" class="block__icon block__icon--show ariaLabel" disabled="disabled" aria-label="${window.siyuan.languages.previousLabel}"><svg><use xlink:href='#iconLeft'></use></svg></span>
<span class="fn__space"></span>
<span data-type="previous" class="block__icon block__icon--show b3-tooltips b3-tooltips__w" disabled="disabled" aria-label="${window.siyuan.languages.previousLabel}"><svg><use xlink:href='#iconLeft'></use></svg></span>
<span class="fn__space"></span>
<span data-type="next" class="block__icon block__icon--show b3-tooltips b3-tooltips__w" disabled="disabled" aria-label="${window.siyuan.languages.nextLabel}"><svg><use xlink:href='#iconRight'></use></svg></span>
<span data-type="next" data-position="north" class="block__icon block__icon--show ariaLabel" disabled="disabled" aria-label="${window.siyuan.languages.nextLabel}"><svg><use xlink:href='#iconRight'></use></svg></span>
<span class="fn__space"></span>
<span class="fn__flex-center ft__on-surface">${pageIndex}/${response.data.pageCount || 1}</span>
<span class="fn__space"></span>
@ -41,7 +41,7 @@ export const viewCards = (app: App, deckID: string, title: string, deckType: "Tr
</div>` : ""}
</div>
<div class="${isMobile() ? "fn__flex-column" : "fn__flex"} fn__flex-1" style="min-height: auto">
<ul class="fn__flex-1 b3-list b3-list--background" style="user-select: none">
<ul class="fn__flex-1 b3-list b3-list--background" style="user-select: none;padding: 8px 0">
${renderViewItem(response.data.blocks, title, deckType)}
</ul>
<div id="cardPreview" style="border-bottom-right-radius:var(--b3-border-radius-b);" class="fn__flex-1 fn__none"></div>

View file

@ -57,7 +57,7 @@ export const about = {
<div class="fn__space"></div>
<input class="b3-switch fn__flex-center" id="downloadInstallPkg" type="checkbox"${window.siyuan.config.system.downloadInstallPkg ? " checked" : ""}>
</label>
<div class="b3-label${isBrowser() ? " fn__none" : ""}">
<div class="b3-label${(isBrowser() && !isInMobileApp() && !isIPad()) ? " fn__none" : ""}">
<label class="fn__flex config__item">
<div class="fn__flex-1">
${window.siyuan.languages.about11}

View file

@ -101,7 +101,7 @@ export const bazaar = {
<input ${window.siyuan.config.bazaar.petalDisabled ? "" : " checked"} data-type="plugins-enable" type="checkbox" class="b3-switch fn__flex-center" style="margin-right: 8px">
<div class="counter counter--bg fn__none fn__flex-center ariaLabel" data-position="north" aria-label="${window.siyuan.languages.total}"></div>
</div>
<div id="configBazaarDownloaded" class="config-bazaar__content">
<div id="configBazaarDownloaded" class="config-bazaar__content b3-cards b3-cards--nowrap">
${loadingHTML}
</div>
</div>
@ -236,9 +236,9 @@ export const bazaar = {
}
try {
new URL(funding);
return `<a target="_blank" href="${escapeAttr(funding)}" class="block__icon block__icon--show ariaLabel" data-position="north" aria-label="${window.siyuan.languages.sponsor} ${escapeAttr(funding)}"><svg class="ft__pink"><use xlink:href="#iconHeart"></use></svg></a>`;
return `<span class="fn__space--small"></span><a target="_blank" href="${escapeAttr(funding)}" class="block__icon block__icon--show ariaLabel" data-position="north" aria-label="${window.siyuan.languages.sponsor} ${escapeAttr(funding)}"><svg class="ft__pink"><use xlink:href="#iconHeart"></use></svg></a>`;
} catch (e) {
return `<span data-type="copy-funding" data-funding="${escapeAttr(funding)}" class="block__icon block__icon--show ariaLabel" data-position="north" aria-label="${window.siyuan.languages.sponsor} ${escapeAttr(funding)}"><svg class="ft__pink"><use xlink:href="#iconHeart"></use></svg></span>`;
return `<span class="fn__space--small"></span><span data-type="copy-funding" data-funding="${escapeAttr(funding)}" class="block__icon block__icon--show ariaLabel" data-position="north" aria-label="${window.siyuan.languages.sponsor} ${escapeAttr(funding)}"><svg class="ft__pink"><use xlink:href="#iconHeart"></use></svg></span>`;
}
},
_genCardHTML(item: IBazaarItem, bazaarType: TBazaarType) {
@ -266,35 +266,37 @@ export const bazaar = {
downloads: item.downloads,
downloaded: false,
};
return `<div data-obj='${JSON.stringify(dataObj)}' class="b3-card b3-card--wrap${hide ? " fn__none" : ""}${item.current ? " b3-card--current" : ""}">
return `<div data-obj='${JSON.stringify(dataObj)}' class="b3-card${hide ? " fn__none" : ""}${item.current ? " b3-card--current" : ""}">
<div class="b3-card__img">
<img src="${item.iconURL}" loading="lazy" onerror="this.src='/stage/images/icon.png'"/>
</div>
<div class="fn__flex-1 fn__flex-column">
<div class="b3-card__info fn__flex-1">
${item.preferredName}${item.preferredName !== item.name ? ` <span class="ft__on-surface ft__smaller">${item.name}</span>` : ""}
${item.preferredName}
<div class="b3-card__desc" title="${escapeAttr(item.preferredDesc) || ""}">
${item.preferredDesc || ""}
</div>
</div>
<div class="b3-card__actions">
<span class="block__icon block__icon--show ft__primary">
<span class="block__icon block__icon--show block__icon--text">
<svg><use xlink:href="#iconDownload"></use></svg>
<span class="fn__space"></span>
<span class="fn__space--small"></span>
${item.downloads}
</span>
<span class="fn__space"></span>
${bazaar._genFundingHTML(item.preferredFunding)}
<span class="fn__space"></span>
<div class="fn__flex-1"></div>
<span data-position="north" class="ariaLabel block__icon block__icon--show${item.installed ? "" : " fn__none"}" data-type="uninstall" aria-label="${window.siyuan.languages.uninstall}">
<svg><use xlink:href="#iconTrashcan"></use></svg>
<span class="fn__space--small"></span>
<span class="block__icon block__icon--show block__icon--text">
<svg><use xlink:href="#iconAccount"></use></svg>
<span class="fn__space--small"></span>
${item.author}
</span>
<div class="fn__space${!item.current && item.installed && showSwitch ? "" : " fn__none"}"></div>
${bazaar._genFundingHTML(item.preferredFunding)}
<span class="fn__space--small"></span>
<div class="fn__flex-1"></div>
<div class="fn__space--small${!item.current && item.installed && showSwitch ? "" : " fn__none"}"></div>
<span data-position="north" class="ariaLabel block__icon block__icon--show${!item.current && item.installed && showSwitch ? "" : " fn__none"}" data-type="switch" aria-label="${window.siyuan.languages.use}">
<svg><use xlink:href="#iconSelect"></use></svg>
</span>
<div class="fn__space${item.outdated ? "" : " fn__none"}"></div>
<div class="fn__space--small${item.outdated ? "" : " fn__none"}"></div>
<span data-type="install-t" ${item.disallowUpdate ? "disabled" : ""} aria-label="${item.disallowUpdate ? window.siyuan.languages.bazaarNeedVersion.replace("${x}", item.updateRequiredMinAppVer) : window.siyuan.languages.update}" data-position="north" class="ariaLabel block__icon block__icon--show${item.outdated ? "" : " fn__none"}">
<svg class="ft__primary"><use xlink:href="#iconRefresh"></use></svg>
</span>
@ -316,7 +318,7 @@ export const bazaar = {
<div class="b3-card__img"><img src="${item.iconURL}" loading="lazy" onerror="this.src='/stage/images/icon.png'"/></div>
<div class="fn__flex-1 fn__flex-column">
<div class="b3-card__info b3-card__info--left fn__flex-1">
${item.preferredName}${item.preferredName !== item.name ? ` <span class="ft__on-surface ft__smaller">${item.name}</span>` : ""}
${item.preferredName}
<div class="b3-card__desc" title="${escapeAttr(item.preferredDesc) || ""}">${item.preferredDesc || ""}</div>
</div>
</div>
@ -362,7 +364,7 @@ export const bazaar = {
<span class="fn__space"></span>
<div class="counter counter--bg fn__flex-center ariaLabel" data-position="north" aria-label="${window.siyuan.languages.total}">${allCount}</div>
</div>
<div class="config-bazaar__content">${html}</div>`;
<div class="config-bazaar__content b3-cards b3-cards--nowrap">${html}</div>`;
});
},
_genMyHTML(bazaarType: TBazaarType, app: App, updateUpdate = true) {
@ -425,7 +427,7 @@ export const bazaar = {
<div class="b3-card__img"><img src="${item.iconURL}" loading="lazy" onerror="this.src='/stage/images/icon.png'"/></div>
<div class="fn__flex-1 fn__flex-column">
<div class="b3-card__info b3-card__info--left fn__flex-1">
${item.preferredName}${item.preferredName !== item.name ? ` <span class="ft__on-surface ft__smaller">${item.name}</span>` : ""}
${item.preferredName}
<div class="b3-card__desc" title="${escapeAttr(item.preferredDesc) || ""}">${item.preferredDesc || ""}</div>
</div>
</div>
@ -467,7 +469,7 @@ type="checkbox">
} else {
checkElement.classList.add("fn__none");
}
contentElement.innerHTML = html ? html : `<div class="fn__hr"></div><ul class="b3-list b3-list--background"><li class="b3-list--empty">${window.siyuan.languages.emptyContent}</li></ul>`;
contentElement.innerHTML = html ? html : `<ul class="b3-list b3-list--background"><li class="b3-list--empty">${window.siyuan.languages.emptyContent}</li></ul>`;
});
},
_data: {
@ -527,7 +529,7 @@ type="checkbox">
<span class="fn__flex-1"></span>
${data.preferredFunding ?
bazaar._genFundingHTML(data.preferredFunding) :
`<span data-position="north" class="ariaLabel block__icon block__icon--show ft__primary" aria-label="${window.siyuan.languages.author}" style="cursor: default"><svg><use xlink:href="#iconAccount"></use></svg></span>`
'<span class="block__icon block__icon--show block__icon--text" style="cursor: default"><svg><use xlink:href="#iconAccount"></use></svg></span>'
}
<span class="fn__space"></span>
<a href="${urls.join("/")}" target="_blank" title="Creator">${data.author}</a>
@ -593,9 +595,9 @@ type="checkbox">
<img data-type="img-loading" style="height: 64px;width: 100%;padding: 16px 0;" src="/stage/loading-pure.svg">
</div>
</div>`;
if (downloaded && data.preferredReadme) {
if (downloaded) {
const mdElement = readmeElement.querySelector(".item__readme");
mdElement.innerHTML = data.preferredReadme;
mdElement.innerHTML = data.preferredReadme || "";
highlightRender(mdElement);
} else {
fetchPost("/api/bazaar/getBazaarPackageREADME", {
@ -711,7 +713,6 @@ type="checkbox">
fetchPost("/api/petal/setPetalEnabled", {
packageName: dataObj.name,
enabled: true,
frontend: getFrontend(),
app: Constants.SIYUAN_APPID,
}, (response) => {
loadPlugin(app, response.data);
@ -727,7 +728,7 @@ type="checkbox">
break;
} else if (type === "install-all") {
confirmDialog("⬆️ " + window.siyuan.languages.updateAll, window.siyuan.languages.confirmUpdateAll, () => {
fetchPost("/api/bazaar/batchUpdatePackage", {frontend: getFrontend()});
fetchPost("/api/bazaar/batchUpdatePackage");
});
event.preventDefault();
event.stopPropagation();
@ -878,7 +879,6 @@ type="checkbox">
fetchPost("/api/petal/setPetalEnabled", {
packageName: dataObj.name,
enabled,
frontend: getFrontend(),
app: Constants.SIYUAN_APPID,
}, (response) => {
target.removeAttribute("disabled");
@ -1076,9 +1076,6 @@ type="checkbox">
}
localSort[selectElement.parentElement.parentElement.getAttribute("data-type")] = selectElement.value;
setStorageVal(Constants.LOCAL_BAZAAR, window.siyuan.storage[Constants.LOCAL_BAZAAR]);
if (cardElements.length > 1) {
html += '<div class="fn__flex-1" style="margin-left: 15px;min-width: 342px;"></div><div class="fn__flex-1" style="margin-left: 15px;min-width: 342px;"></div>';
}
panelElement.querySelector(".b3-cards").innerHTML = html;
}
});
@ -1140,9 +1137,6 @@ type="checkbox">
html += item.outerHTML;
});
}
if (response.data.packages.length > 1) {
html += '<div class="fn__flex-1" style="margin-left: 15px;min-width: 342px;"></div><div class="fn__flex-1" style="margin-left: 15px;min-width: 342px;"></div>';
}
element.innerHTML = `<div class="b3-cards">${html}</div>`;
element.innerHTML = `<div class="b3-cards${html ? "" : " b3-cards--nowrap"}">${html || `<ul class="b3-list b3-list--background"><li class="b3-list--empty">${window.siyuan.languages.emptyContent}</li></ul>`}</div>`;
}
};

View file

@ -245,6 +245,18 @@ const fillSyncProviderPanelValues = (panel: Element) => {
}
};
const getReposDataLoadingHTML = () => `<div class="fn__flex">
<div class="fn__flex-1">
${window.siyuan.languages.cloudStorage}
</div>
<div class="fn__flex-1">
${window.siyuan.languages.trafficStat}
</div>
</div>
<div style="min-height: 183px; display: flex; justify-content: center;" id="reposLoading">
<img src="/stage/loading-pure.svg">
</div>`;
const bindProviderEvent = () => {
const importElement = repos.element.querySelector("#importData") as HTMLInputElement;
if (importElement) {
@ -267,10 +279,8 @@ const bindProviderEvent = () => {
}
const reposDataElement = repos.element.querySelector("#reposData");
const loadingElement = repos.element.querySelector("#reposLoading");
if (window.siyuan.config.sync.provider === 0) {
if (needSubscribe("")) {
loadingElement.classList.add("fn__none");
let nextElement = reposDataElement;
while (nextElement) {
nextElement.classList.add("fn__none");
@ -278,13 +288,13 @@ const bindProviderEvent = () => {
}
return;
}
reposDataElement.innerHTML = getReposDataLoadingHTML();
fetchPost("/api/cloud/getCloudSpace", {}, (response) => {
loadingElement.classList.add("fn__none");
if (response.code === 1) {
reposDataElement.innerHTML = response.msg;
return;
} else {
reposDataElement.innerHTML = `<div class="fn__flex">
}
reposDataElement.innerHTML = `<div class="fn__flex">
<div class="fn__flex-1">
${window.siyuan.languages.cloudStorage}
<div class="fn__hr"></div>
@ -308,13 +318,11 @@ const bindProviderEvent = () => {
</ul>
</div>
</div>`;
}
});
reposDataElement.classList.remove("fn__none");
return;
}
loadingElement.classList.add("fn__none");
let nextElement = reposDataElement.nextElementSibling;
while (nextElement) {
if (isPaidUser()) {
@ -447,11 +455,7 @@ const bindProviderEvent = () => {
export const repos = {
element: undefined as Element,
genHTML: () => {
return `<div>
<div style="position: fixed;width: 800px;height: 434px;box-sizing: border-box;text-align: center;display: flex;align-items: center;justify-content: center;z-index: 1;" id="reposLoading">
<img src="/stage/loading-pure.svg">
</div>
<div class="fn__flex b3-label config__item">
return `<div><div class="fn__flex b3-label config__item">
<div class="fn__flex-1">
${window.siyuan.languages.syncProvider}
<div class="b3-label__text">${window.siyuan.languages.syncProviderTip}</div>
@ -468,14 +472,7 @@ export const repos = {
${renderProvider(window.siyuan.config.sync.provider)}
</div>
<div id="reposData" class="b3-label">
<div class="fn__flex">
<div class="fn__flex-1">
${window.siyuan.languages.cloudStorage}
</div>
<div class="fn__flex-1">
${window.siyuan.languages.trafficStat}
</div>
</div>
${getReposDataLoadingHTML()}
</div>
<label class="fn__flex b3-label">
<div class="fn__flex-1">
@ -541,8 +538,7 @@ export const repos = {
<div class="b3-label fn__flex">
<div class="fn__flex-center">${window.siyuan.languages.cloudBackup}</div>
<div class="b3-list-item__meta fn__flex-center">${window.siyuan.languages.cloudBackupTip}</div>
</div>
</div>`;
</div></div>`;
},
bindEvent: () => {
bindProviderEvent();
@ -629,9 +625,6 @@ export const repos = {
}
});
});
const loadingElement = repos.element.querySelector("#reposLoading") as HTMLElement;
loadingElement.style.width = repos.element.clientWidth + "px";
loadingElement.style.height = repos.element.clientHeight + "px";
bindSyncCloudListEvent(syncConfigElement);
repos.element.firstElementChild.addEventListener("click", (event) => {
let target = event.target as HTMLElement;

View file

@ -6,8 +6,6 @@ declare const NODE_ENV: string;
const _SIYUAN_VERSION = SIYUAN_VERSION;
const _NODE_ENV = NODE_ENV;
const altNumber = navigator.platform.toUpperCase().indexOf("MAC") > -1 ? "⌃" : "⌥";
const getFunctionKey = () => {
const fData: { [key: number]: string } = {};
for (let i = 1; i <= 32; i++) {
@ -440,16 +438,16 @@ export abstract class Constants {
stickSearch: {default: "⇧⌘F", custom: "⇧⌘F"},
replace: {default: "⌘R", custom: "⌘R"},
closeTab: {default: "⌘W", custom: "⌘W"},
fileTree: {default: altNumber + "1", custom: altNumber + "1"},
outline: {default: altNumber + "2", custom: altNumber + "2"},
bookmark: {default: altNumber + "3", custom: altNumber + "3"},
tag: {default: altNumber + "4", custom: altNumber + "4"},
dailyNote: {default: altNumber + "5", custom: altNumber + "5"},
inbox: {default: altNumber + "6", custom: altNumber + "6"},
backlinks: {default: altNumber + "7", custom: altNumber + "7"},
graphView: {default: altNumber + "8", custom: altNumber + "8"},
globalGraph: {default: altNumber + "9", custom: altNumber + "9"},
riffCard: {default: altNumber + "0", custom: altNumber + "0"},
fileTree: {default: "1", custom: "1"},
outline: {default: "2", custom: "2"},
bookmark: {default: "3", custom: "3"},
tag: {default: "4", custom: "4"},
dailyNote: {default: "5", custom: "5"},
inbox: {default: "6", custom: "6"},
backlinks: {default: "7", custom: "7"},
graphView: {default: "8", custom: "8"},
globalGraph: {default: "9", custom: "9"},
riffCard: {default: "0", custom: "0"},
config: {default: "⌥P", custom: "⌥P"},
dataHistory: {default: "⌥H", custom: "⌥H"},
toggleWin: {default: "⌥M", custom: "⌥M"},
@ -505,7 +503,7 @@ export abstract class Constants {
copyBlockEmbed: {default: "⇧⌘E", custom: "⇧⌘E"},
copyHPath: {default: "⇧⌘P", custom: "⇧⌘P"},
undo: {default: "⌘Z", custom: "⌘Z"},
redo: {default: "⌘Y", custom: "⌘Y"},
redo: {default: "⇧⌘Z", custom: "⇧⌘Z"},
rename: {default: "F2", custom: "F2"},
newNameFile: {default: "F3", custom: "F3"},
newContentFile: {default: "F4", custom: "F4"},

View file

@ -14,6 +14,7 @@ export class Dialog {
private disableClose: boolean;
public editors: { [key: string]: Protyle };
public data: any;
private resizeCallback: (type: string) => void;
constructor(options: {
positionId?: string,
@ -29,6 +30,7 @@ export class Dialog {
resizeCallback?: (type: string) => void,
containerClassName?: string
}) {
this.resizeCallback = options.resizeCallback;
this.disableClose = options.disableClose;
this.id = genUUID();
window.siyuan.dialogs.push(this);
@ -85,6 +87,15 @@ left:${left || "auto"};top:${top || "auto"}">
/// #endif
}
public resize() {
if (this.resizeCallback) {
const containerElement = this.element.querySelector(".b3-dialog__container") as HTMLElement;
if (containerElement && containerElement.style.maxWidth !== "none") {
this.resizeCallback("l");
}
}
}
public destroy(options?: IObject) {
this.element.classList.remove("b3-dialog--open");
setTimeout(() => {

View file

@ -50,14 +50,15 @@ export const reloadSync = (
hideMessage();
}
/// #if MOBILE
if (window.siyuan.mobile.popEditor) {
if (window.siyuan.mobile.popEditor && window.siyuan.mobile.popEditor.protyle) {
if (data.removeRootIDs.includes(window.siyuan.mobile.popEditor.protyle.block.rootID)) {
hideElements(["dialog"]);
} else {
reloadProtyle(window.siyuan.mobile.popEditor.protyle, false, updateReadonly);
}
}
if (window.siyuan.mobile.editor) {
if (document.getElementById("empty").classList.contains("fn__none") &&
window.siyuan.mobile.editor && window.siyuan.mobile.editor.protyle) {
if (data.removeRootIDs.includes(window.siyuan.mobile.editor.protyle.block.rootID)) {
setEmpty(app);
} else {
@ -190,7 +191,7 @@ export const setDefRefCount = (data: {
// 不能对比 rootId否则嵌入块中的锚文本无法更新
editor.protyle.wysiwyg.element.querySelectorAll(`[data-node-id="${data.blockID}"]`).forEach(item => {
// 不能直接查询,否则列表中会获取到第一个列表项的 attr https://github.com/siyuan-note/siyuan/issues/12738
const countElement = item.lastElementChild.querySelector(".protyle-attr--refcount");
const countElement = item.lastElementChild?.querySelector(".protyle-attr--refcount");
if (countElement) {
if (data.refCount === 0) {
countElement.remove();
@ -378,14 +379,17 @@ export const exitSiYuan = async (setCurrentWorkspace = true) => {
});
};
export const transactionError = () => {
export const transactionError = (msg?: string) => {
if (document.getElementById("transactionError")) {
return;
}
const dialog = new Dialog({
disableClose: true,
title: `${window.siyuan.languages.stateExcepted} v${Constants.SIYUAN_VERSION}`,
content: `<div class="b3-dialog__content" id="transactionError">${window.siyuan.languages.rebuildIndexTip}</div>
content: `<div class="b3-dialog__content" style="max-height: calc(100vh - 182px)" id="transactionError">
${window.siyuan.languages.rebuildIndexTip}
${msg ? `<div class="fn__hr"></div>${escapeHtml(msg.trim())}` : ""}
</div>
<div class="b3-dialog__action">
<button class="b3-button b3-button--text">${window.siyuan.languages._kernel[97]}</button>
<div class="fn__space"></div>

View file

@ -5,9 +5,8 @@ import {getInstanceById, getWndByLayout, pdfIsLoading, setPanelFocus} from "../l
import {getDockByType} from "../layout/tabUtil";
import {getAllModels, getAllTabs} from "../layout/getAll";
import {highlightById, scrollCenter} from "../util/highlightById";
import {getDisplayName, useShell, pathPosix} from "../util/pathName";
import {getDisplayName, pathPosix, useShell} from "../util/pathName";
import {Constants} from "../constants";
import {setEditMode} from "../protyle/util/setEditMode";
import {Files} from "../layout/dock/Files";
import {fetchPost, fetchSyncPost} from "../util/fetch";
import {focusBlock, focusByOffset, focusByRange} from "../protyle/util/selection";
@ -361,7 +360,6 @@ const switchEditor = (editor: Editor, options: IOpenFileOptions, allModels: IMod
editor.parent.parent.switchTab(editor.parent.headElement);
editor.parent.parent.showHeading();
if (options.mode !== "preview" && !editor.editor.protyle.preview.element.classList.contains("fn__none")) {
// TODO https://github.com/siyuan-note/siyuan/issues/3059
return true;
}
if (options.zoomIn) {
@ -442,9 +440,6 @@ const switchEditor = (editor: Editor, options: IOpenFileOptions, allModels: IMod
if (options.action?.includes(Constants.CB_GET_OUTLINE)) {
hideElements(["select"], editor.editor.protyle);
}
if (options.mode) {
setEditMode(editor.editor.protyle, options.mode);
}
};
const newTab = (options: IOpenFileOptions) => {
@ -633,6 +628,9 @@ export const updateOutline = (models: IModels, protyle: IProtyle, reload = false
let blockId = "";
if (protyle && protyle.block) {
blockId = protyle.block.rootID;
if (!blockId && reload && item.type === "local") {
blockId = item.blockId;
}
}
if (blockId === item.blockId && !reload && item.isPreview !== protyle.preview.element.classList.contains("fn__none")) {
return;

View file

@ -40,7 +40,6 @@ import {ipcRenderer} from "electron";
/// #endif
import {getDockByType} from "./layout/tabUtil";
import {Tag} from "./layout/dock/Tag";
import {updateControlAlt} from "./protyle/util/hotKey";
import {updateAppearance} from "./config/util/updateAppearance";
import {renderSnippet} from "./config/util/snippets";
@ -121,7 +120,6 @@ export class App {
break;
case "setConf":
window.siyuan.config = data.data;
updateControlAlt();
break;
case "setPublish":
window.siyuan.config.publish = data.data;
@ -188,7 +186,7 @@ export class App {
downloadProgress(data.data);
break;
case "txerr":
transactionError();
transactionError(data.msg);
break;
case "syncing":
processSync(data, this.plugins);
@ -220,7 +218,6 @@ export class App {
addScriptSync(`${Constants.PROTYLE_CDN}/js/lute/lute.min.js?v=${Constants.SIYUAN_VERSION}`, "protyleLuteScript");
addScript(`${Constants.PROTYLE_CDN}/js/protyle-html.js?v=${Constants.SIYUAN_VERSION}`, "protyleWcHtmlScript");
window.siyuan.config = response.data.conf;
updateControlAlt();
window.siyuan.isPublish = response.data.isPublish;
await loadPlugins(this);
getLocalStorage(() => {

View file

@ -55,7 +55,9 @@ export class Model {
}
};
ws.onmessage = (event) => {
if (options.msgCallback) {
if (options.msgCallback &&
// 等待 config 加载完成才接受推送 https://github.com/siyuan-note/siyuan/issues/17508
window.siyuan.config) {
const data = processMessage(JSON.parse(event.data));
options.msgCallback.call(this, data);
}

View file

@ -99,7 +99,9 @@ export class Tab {
tabElement.style.opacity = "0.38";
window.siyuan.dragElement = this.headElement;
}
/// #if !BROWSER
ipcRenderer.send(Constants.SIYUAN_SEND_WINDOWS, {cmd: "resetTabsStyle", data: "removeRegionStyle"});
/// #endif
});
this.headElement.addEventListener("dragend", (event: DragEvent & { target: HTMLElement }) => {
const tabElement = hasClosestByTag(event.target, "LI");

View file

@ -9,7 +9,6 @@ import {
pdfIsLoading,
saveLayout,
setPanelFocus,
switchWnd
} from "./util";
import {Tab} from "./Tab";
import {Model} from "./Model";
@ -382,26 +381,16 @@ export class Wnd {
// split
if (dragElement.style.height === "50%") {
// split to bottom
const newWnd = targetWnd.split("tb");
const newWnd = targetWnd.split("tb", dragElement.style.bottom !== "50%");
newWnd.headersElement.append(oldTab.headElement);
newWnd.headersElement.parentElement.classList.remove("fn__none");
newWnd.moveTab(oldTab);
if (dragElement.style.bottom === "50%" && newWnd.element.previousElementSibling && targetWnd.element.parentElement) {
// 交换位置
switchWnd(newWnd, targetWnd);
}
} else if (dragElement.style.width === "50%") {
// split to right
const newWnd = targetWnd.split("lr");
const newWnd = targetWnd.split("lr", dragElement.style.right !== "50%");
newWnd.headersElement.append(oldTab.headElement);
newWnd.headersElement.parentElement.classList.remove("fn__none");
newWnd.moveTab(oldTab);
if (dragElement.style.right === "50%" && newWnd.element.previousElementSibling && targetWnd.element.parentElement) {
// 交换位置
switchWnd(newWnd, targetWnd);
}
}
resizeTabs();
/// #if !BROWSER
@ -990,7 +979,7 @@ export class Wnd {
/// #endif
}
public split(direction: Config.TUILayoutDirection) {
public split(direction: Config.TUILayoutDirection, after = true) {
if (this.children.length === 1 && !this.children[0].headElement) {
// 场景:没有打开的文档,点击标签面板打开
return this;
@ -998,18 +987,19 @@ export class Wnd {
recordBeforeResizeTop();
const wnd = new Wnd(this.app, direction);
if (direction === this.parent.direction) {
this.parent.addWnd(wnd, this.id);
this.parent.addWnd(wnd, this.id, after);
} else if (this.parent.children.length === 1) {
// layout 仅含一个时,只需更新 direction
this.parent.direction = direction;
if (direction === "tb") {
this.parent.element.classList.add("fn__flex-column");
this.parent.element.style.minHeight = "8px";
this.parent.element.classList.remove("fn__flex");
} else {
this.parent.element.classList.remove("fn__flex-column");
this.parent.element.classList.add("fn__flex");
}
this.parent.addWnd(wnd, this.id);
this.parent.addWnd(wnd, this.id, after);
} else {
this.parent.children.find((item, index) => {
if (item.id === this.id) {
@ -1017,14 +1007,23 @@ export class Wnd {
resize: item.resize,
direction,
});
this.parent.addLayout(layout, item.id);
const movedWnd = this.parent.children.splice(index, 1)[0];
this.parent.addLayout(layout, item.id, after);
const movedWnd = this.parent.children.splice(after ? index : index + 1, 1)[0];
if (movedWnd.resize) {
movedWnd.element.previousElementSibling.remove();
if (movedWnd.element.previousElementSibling && movedWnd.element.previousElementSibling.classList.contains("layout__resize")) {
movedWnd.element.previousElementSibling.remove();
} else if (movedWnd.element.nextElementSibling && movedWnd.element.nextElementSibling.classList.contains("layout__resize")) {
movedWnd.element.nextElementSibling.remove();
}
movedWnd.resize = undefined;
}
layout.addWnd.call(layout, movedWnd);
layout.addWnd.call(layout, wnd);
if (after) {
layout.addWnd.call(layout, movedWnd);
layout.addWnd.call(layout, wnd);
} else {
layout.addWnd.call(layout, wnd);
layout.addWnd.call(layout, movedWnd);
}
if (direction === "tb" && movedWnd.element.style.width) {
layout.element.style.width = movedWnd.element.style.width;

View file

@ -44,6 +44,7 @@ export class Backlink extends Model {
super({
app: options.app,
id: options.tab.id,
type: "backlink",
callback() {
if (this.type === "local") {
fetchPost("/api/block/checkBlockExist", {id: this.blockId}, existResponse => {
@ -84,11 +85,10 @@ export class Backlink extends Model {
const backlinkSort = window.siyuan.config.editor.backlinkSort;
const backmentionSort = window.siyuan.config.editor.backmentionSort;
this.element.innerHTML = `<div class="block__icons">
<div class="block__logo">
<div class="block__logo fn__flex-1">
<svg class="block__logoicon"><use xlink:href="#iconLink"></use></svg>${window.siyuan.languages.backlinks}
</div>
<span class="counter listCount" style="margin-left: 0"></span>
<span class="fn__flex-1"></span>
<span class="fn__space"></span>
<input class="b3-text-field search__label fn__none fn__size200" placeholder="${window.siyuan.languages.filterKeywordEnter}" />
<span data-type="search" class="block__icon ariaLabel" data-position="north" aria-label="${window.siyuan.languages.filter}"><svg><use xlink:href='#iconFilter'></use></svg></span>
@ -109,11 +109,10 @@ export class Backlink extends Model {
</div>
<div class="backlinkList fn__flex-1"></div>
<div class="block__icons">
<div class="block__logo fn__pointer" data-type="mention">
<div class="block__logo fn__flex-1 fn__pointer" data-type="mention">
<svg class="block__logoicon"><use xlink:href="#iconLink"></use></svg>${window.siyuan.languages.mentions}
</div>
<span class="counter listMCount" style="margin-left: 0;"></span>
<span class="fn__flex-1"></span>
<span class="fn__space"></span>
<input class="b3-text-field search__label fn__none fn__size200" placeholder="${window.siyuan.languages.filterKeywordEnter}" />
<span data-type="search" class="block__icon b3-tooltips b3-tooltips__nw" aria-label="${window.siyuan.languages.filter}"><svg><use xlink:href='#iconFilter'></use></svg></span>

View file

@ -21,6 +21,7 @@ export class Bookmark extends Model {
super({
app,
id: tab.id,
type: "bookmark",
msgCallback(data) {
if (data) {
switch (data.cmd) {
@ -52,11 +53,9 @@ export class Bookmark extends Model {
this.element = tab.panelElement;
this.element.classList.add("fn__flex-column", "file-tree", "sy__bookmark", "dockPanel");
this.element.innerHTML = `<div class="block__icons">
<div class="block__logo">
<div class="block__logo fn__flex-1">
<svg class="block__logoicon"><use xlink:href="#iconBookmark"></use></svg>${window.siyuan.languages.bookmark}
</div>
<span class="fn__flex-1"></span>
<span class="fn__space"></span>
<span data-type="refresh" class="block__icon ariaLabel" data-position="north" aria-label="${window.siyuan.languages.refresh}"><svg><use xlink:href='#iconRefresh'></use></svg></span>
<span class="fn__space"></span>
<span data-type="expand" class="block__icon ariaLabel" data-position="north" aria-label="${window.siyuan.languages.expand}${updateHotkeyAfterTip(window.siyuan.config.keymap.editor.general.expand.custom)}">

View file

@ -118,10 +118,9 @@ export class Files extends Model {
});
options.tab.panelElement.classList.add("fn__flex-column", "file-tree", "sy__file", "dockPanel");
options.tab.panelElement.innerHTML = `<div class="block__icons">
<div class="block__logo">
<div class="block__logo fn__flex-1">
<svg class="block__logoicon"><use xlink:href="#iconFiles"></use></svg>${window.siyuan.languages.fileTree}
</div>
<span class="fn__flex-1 fn__space"></span>
<span data-type="focus" class="block__icon ariaLabel" data-position="north" aria-label="${window.siyuan.languages.selectOpen1}${updateHotkeyAfterTip(window.siyuan.config.keymap.general.selectOpen1.custom)}"><svg><use xlink:href='#iconFocus'></use></svg></span>
<span class="fn__space"></span>
<span data-type="collapse" class="block__icon ariaLabel" data-position="north" aria-label="${window.siyuan.languages.collapse}${updateHotkeyAfterTip(window.siyuan.config.keymap.editor.general.collapse.custom)}">
@ -1063,7 +1062,7 @@ data-type="navigation-root" data-path="/">
if (!fileItemElement) {
return;
}
fileItemElement.setAttribute("data-name", Lute.EscapeHTMLStr(data.title));
fileItemElement.setAttribute("data-name", data.title);
fileItemElement.querySelector(".b3-list-item__text").innerHTML = escapeHtml(data.title);
}
@ -1358,7 +1357,7 @@ class="b3-list-item b3-list-item--hide-action" data-path="${item.path}">
<span class="b3-list-item__icon b3-tooltips b3-tooltips__n popover__block${editingPublishAccess ? " fn__none" : ""}" data-id="${item.id}" aria-label="${window.siyuan.languages.changeIcon}">${unicode2Emoji(item.icon || (item.subFileCount === 0 ? window.siyuan.storage[Constants.LOCAL_IMAGES].file : window.siyuan.storage[Constants.LOCAL_IMAGES].folder))}</span>
<span class="b3-list-item__switch b3-tooltips b3-tooltips__n${editingPublishAccess ? "" : " fn__none"}" aria-label="${window.siyuan.languages.publishAccess}">${getPublishAccessOptionByLevel("public").iconHTML}</span>
<span class="b3-list-item__text ariaLabel" data-position="parentE"
aria-label="${ariaLabel}">${getDisplayName(item.name, true, true)}</span>
aria-label="${ariaLabel}">${getDisplayName(Lute.EscapeHTMLStr(item.name), true, true)}</span>
<span data-type="more-file" class="b3-list-item__action b3-tooltips b3-tooltips__nw" aria-label="${window.siyuan.languages.more}">
<svg><use xlink:href="#iconMore"></use></svg>
</span>

View file

@ -41,6 +41,7 @@ export class Graph extends Model {
super({
app: options.app,
id: options.tab.id,
type: "graph",
callback() {
if (this.type === "local") {
fetchPost("/api/block/checkBlockExist", {id: this.blockId}, existResponse => {
@ -265,11 +266,9 @@ export class Graph extends Model {
<button class="b3-button b3-button--small fn__block">${window.siyuan.languages.reset}</button>`;
}
this.element.innerHTML = `<div class="block__icons">
<div class="block__logo">
<div class="block__logo fn__flex-1">
<svg class="block__logoicon"><use xlink:href="#icon${this.type === "global" ? "GlobalGraph" : "Graph"}"></use></svg>${this.type === "global" ? window.siyuan.languages.globalGraph : window.siyuan.languages.graphView}
</div>
<span class="fn__flex-1"></span>
<span class="fn__space"></span>
<input class="b3-text-field search__label fn__size200 fn__none" placeholder="${window.siyuan.languages.search}" />
<span data-type="search" class="block__icon ariaLabel" data-position="north" aria-label="${window.siyuan.languages.search}"><svg><use xlink:href='#iconFilter'></use></svg></span>
<span class="fn__space"></span>
@ -316,11 +315,11 @@ export class Graph extends Model {
if (dataType === "min") {
getDockByType(this.type === "global" ? "globalGraph" : "graph").toggleModel(this.type === "global" ? "globalGraph" : "graph", false, true);
} else if (dataType === "menu") {
if (target.classList.contains("ft__primary")) {
target.classList.remove("ft__primary");
if (target.classList.contains("block__icon--active")) {
target.classList.remove("block__icon--active");
this.panelElement.style.right = "";
} else {
target.classList.add("ft__primary");
target.classList.add("block__icon--active");
this.panelElement.style.right = "0";
}
} else if (dataType === "search") {
@ -341,8 +340,8 @@ export class Graph extends Model {
}
break;
} else if (target.classList.contains("graph__svg")) {
this.element.querySelectorAll(".block__icon.ft__primary").forEach(item => {
item.classList.remove("ft__primary");
this.element.querySelectorAll(".block__icon.block__icon--active").forEach(item => {
item.classList.remove("block__icon--active");
});
this.panelElement.style.right = "";
break;

View file

@ -54,12 +54,10 @@ export class Inbox extends Model {
/// #else
this.element.classList.add("fn__flex-column", "file-tree", "sy__inbox", "dockPanel");
this.element.innerHTML = `<div class="block__icons">
<div class="block__logo">
<div class="block__logo fn__flex-1">
<svg class="block__logoicon"><use xlink:href="#iconInbox"></use></svg>${window.siyuan.languages.inbox}&nbsp;
<span class="inboxSelectCount"></span>
</div>
<span class="fn__flex-1"></span>
<span class="fn__space"></span>
<span data-type="selectall" class="block__icon"><svg><use xlink:href="#iconUncheck"></use></svg></span>
<span class="fn__space"></span>
<span data-type="previous" class="block__icon ariaLabel" disabled="disabled" data-position="north" aria-label="${window.siyuan.languages.previousLabel}"><svg><use xlink:href="#iconLeft"></use></svg></span>

View file

@ -48,6 +48,7 @@ export class Outline extends Model {
super({
app: options.app,
id: options.tab.id,
type: "outline",
callback() {
if (this.type === "local") {
fetchPost("/api/block/checkBlockExist", {id: this.blockId}, existResponse => {
@ -97,10 +98,9 @@ export class Outline extends Model {
this.type = options.type;
options.tab.panelElement.classList.add("fn__flex-column", "file-tree", "sy__outline", "dockPanel");
options.tab.panelElement.innerHTML = `<div class="block__icons fn__hidescrollbar">
<div class="block__logo">
<div class="block__logo fn__flex-1">
<svg class="block__logoicon"><use xlink:href="#iconAlignCenter"></use></svg>${window.siyuan.languages.outline}
</div>
<span class="fn__flex-1 fn__space"></span>
<input class="b3-text-field search__label fn__none fn__size200" placeholder="${window.siyuan.languages.filterKeywordEnter}" />
<span data-type="search" class="block__icon ariaLabel" data-position="north" aria-label="${window.siyuan.languages.filter}">
<svg><use xlink:href='#iconFilter'></use></svg>

View file

@ -21,6 +21,7 @@ export class Tag extends Model {
super({
app,
id: tab.id,
type: "tag",
msgCallback(data) {
if (data) {
switch (data.cmd) {
@ -54,11 +55,9 @@ export class Tag extends Model {
this.element.classList.add("fn__flex-column", "file-tree", "sy__tag", "dockPanel");
this.element.innerHTML = `<div class="block__icons">
<div class="block__logo">
<div class="block__logo fn__flex-1">
<svg class="block__logoicon"><use xlink:href="#iconTags"></use></svg>${window.siyuan.languages.tag}
</div>
<span class="fn__flex-1"></span>
<span class="fn__space"></span>
<span data-type="refresh" class="block__icon ariaLabel" data-position="north" aria-label="${window.siyuan.languages.refresh}"><svg><use xlink:href='#iconRefresh'></use></svg></span>
<span class="fn__space"></span>
<span data-type="sort" class="block__icon ariaLabel${window.siyuan.config.readonly ? " fn__none" : ""}" data-position="north" aria-label="${window.siyuan.languages.sort}">

View file

@ -2,7 +2,7 @@ import {getAllModels} from "../getAll";
import {Tab} from "../Tab";
import {Graph} from "./Graph";
import {Outline} from "./Outline";
import {fixWndFlex1, getInstanceById, getWndByLayout, saveLayout, switchWnd} from "../util";
import {fixWndFlex1, getInstanceById, getWndByLayout, saveLayout} from "../util";
import {getDockByType, resizeTabs} from "../tabUtil";
import {Backlink} from "./Backlink";
import {App} from "../../index";
@ -145,7 +145,7 @@ export const openOutline = async (options: {
if (!wnd) {
wnd = getWndByLayout(window.siyuan.layout.centerLayout);
}
const newWnd = wnd.split("lr");
const newWnd = wnd.split("lr", false);
if (!options.title) {
const response = await fetchSyncPost("api/block/getDocInfo", {id: options.rootId});
@ -166,7 +166,6 @@ export const openOutline = async (options: {
}), false, false);
newWnd.element.style.width = "200px";
newWnd.element.classList.remove("fn__flex-1");
switchWnd(newWnd, wnd);
fixWndFlex1(newWnd.parent);
saveLayout();
};

View file

@ -123,15 +123,52 @@ export const getAllWnds = (layout: Layout, wnds: Wnd[]) => {
}
};
export const getAllTabs = () => {
export const getAllTabs = (type?: TTab | string) => {
const tabs: Tab[] = [];
const getTabs = (layout: Layout) => {
for (let i = 0; i < layout.children.length; i++) {
const item = layout.children[i];
if (item instanceof Tab) {
tabs.push(item);
} else {
if (!(item instanceof Tab)) {
getTabs(item as Layout);
continue;
}
if (!type) {
tabs.push(item);
continue;
}
const model = item.model;
if (model) {
if (model instanceof Search && type === "Search") {
tabs.push(item);
} else if (model instanceof Asset && type === "Asset") {
tabs.push(item);
} else if (model instanceof Editor && type === "Editor") {
tabs.push(item);
} else if (model instanceof Graph && type === "Graph") {
tabs.push(item);
} else if (model instanceof Backlink && type === "Backlink") {
tabs.push(item);
} else if (model instanceof Outline && type === "Outline") {
tabs.push(item);
} else if (model instanceof Custom && model.type === type) {
tabs.push(item);
}
continue;
}
const initData = item.headElement?.getAttribute("data-initdata");
if (!initData) {
continue;
}
try {
const initObj = JSON.parse(initData) as ILayoutJSON;
if (
(initObj.instance === "Custom" && initObj.customModelType === type) ||
initObj.instance === type
) {
tabs.push(item);
}
} catch (e) {
console.log(`getAllTabs(${type}) error:`, e);
}
}
};

View file

@ -42,7 +42,7 @@ export class Layout {
}
}
addLayout(child: Layout, id?: string) {
addLayout(child: Layout, id?: string, after = true) {
if (!id) {
this.children.splice(this.children.length, 0, child);
if (this) {
@ -51,8 +51,12 @@ export class Layout {
} else {
this.children.find((item, index) => {
if (item.id === id) {
this.children.splice(index + 1, 0, child);
item.element.after(child.element);
this.children.splice(after ? index + 1 : index, 0, child);
if (after) {
item.element.after(child.element);
} else {
item.element.before(child.element);
}
return true;
}
});
@ -62,18 +66,22 @@ export class Layout {
} else {
child.element.style[(this && this.direction === "lr") ? "width" : "height"] = child.size;
}
addResize(child);
addResize(child, after);
child.parent = this;
}
addWnd(child: Wnd, id?: string) {
addWnd(child: Wnd, id?: string, after = true) {
if (!id) {
this.children.splice(this.children.length, 0, child);
this.element.append(child.element);
} else {
this.children.find((item, index) => {
if (item.id === id) {
this.children.splice(index + 1, 0, child);
if (after) {
this.children.splice(index + 1, 0, child);
} else {
this.children.splice(index, 0, child);
}
if (this.direction === "lr") {
// 向右分屏,左侧文档抖动,移除动画和边距
item.element.querySelectorAll(".protyle-content").forEach((element: HTMLElement) => {
@ -84,7 +92,11 @@ export class Layout {
}
});
}
item.element.after(child.element);
if (after) {
item.element.after(child.element);
} else {
item.element.before(child.element);
}
return true;
}
});
@ -92,7 +104,7 @@ export class Layout {
if (id) {
fixWndFlex1(this);
}
addResize(child);
addResize(child, after);
resizeTabs(false);
child.parent = this;
}

View file

@ -12,18 +12,15 @@ import {getAllModels, getAllTabs, getAllWnds} from "./getAll";
import {Asset} from "../asset";
import {Search} from "../search";
import {Dock} from "./dock";
import {focusByOffset, focusByRange, getSelectionOffset} from "../protyle/util/selection";
import {focusByRange} from "../protyle/util/selection";
import {hideElements} from "../protyle/ui/hideElements";
import {fetchPost} from "../util/fetch";
import {hasClosestBlock, hasClosestByClassName} from "../protyle/util/hasClosest";
import {hasClosestByClassName} from "../protyle/util/hasClosest";
import {Constants} from "../constants";
import {saveScroll} from "../protyle/scroll/saveScroll";
import {Backlink} from "./dock/Backlink";
import {openFileById} from "../editor/util";
import {isWindow} from "../util/functions";
/// #if !BROWSER
import {setTabPosition} from "../window/setHeader";
/// #endif
import {showMessage} from "../dialog/message";
import {getIdZoomInByPath} from "../util/pathName";
import {Custom} from "./dock/Custom";
@ -68,57 +65,6 @@ export const setPanelFocus = (element: Element, isSaveLayout = true) => {
}
};
export const switchWnd = (newWnd: Wnd, targetWnd: Wnd) => {
// DOM 移动后 range 会变化
const rangeDatas: {
id: string,
start: number,
end: number
}[] = [];
targetWnd.children.forEach((item) => {
if (item.model instanceof Editor && item.model.editor.protyle.toolbar.range) {
const blockElement = hasClosestBlock(item.model.editor.protyle.toolbar.range.startContainer);
if (blockElement) {
const startEnd = getSelectionOffset(blockElement, undefined, item.model.editor.protyle.toolbar.range);
rangeDatas.push({
id: blockElement.getAttribute("data-node-id"),
start: startEnd.start,
end: startEnd.end
});
}
}
});
newWnd.element.after(targetWnd.element);
targetWnd.children.forEach((item) => {
if (item.model instanceof Editor) {
const rangeData = rangeDatas.splice(0, 1)[0];
if (!rangeData) {
return;
}
const range = focusByOffset(item.model.editor.protyle.wysiwyg.element.querySelector(`[data-node-id="${rangeData.id}"]`), rangeData.start, rangeData.end);
if (range) {
item.model.editor.protyle.toolbar.range = range;
}
}
});
// 分隔线
newWnd.element.after(newWnd.element.previousElementSibling);
newWnd.parent.children.find((item, index) => {
if (item.id === newWnd.id) {
const tempResize = newWnd.parent.children[index].resize;
newWnd.parent.children[index].resize = newWnd.parent.children[index - 1].resize;
newWnd.parent.children[index - 1].resize = tempResize;
const temp = item;
newWnd.parent.children[index] = newWnd.parent.children[index - 1];
newWnd.parent.children[index - 1] = temp;
return true;
}
});
/// #if !BROWSER
setTabPosition();
/// #endif
};
export const getWndByLayout: (layout: Layout) => Wnd = (layout: Layout) => {
const wndsTemp: Wnd[] = [];
getAllWnds(layout, wndsTemp);
@ -757,7 +703,8 @@ export const newModelByInitData = (app: App, tab: Tab, json: any) => {
blockId: json.blockId,
mode: json.mode,
scrollPosition: json.scrollPosition,
action: typeof json.action === "string" ? (json.action ? [json.action, Constants.CB_GET_FOCUS] : [Constants.CB_GET_FOCUS]) : json.action.concat(Constants.CB_GET_FOCUS),
action: Array.isArray(json.action) ? json.action.concat(Constants.CB_GET_FOCUS) :
(json.action ? [json.action, Constants.CB_GET_FOCUS] : [Constants.CB_GET_FOCUS]),
});
}
return model;
@ -790,7 +737,7 @@ export const getInstanceById = (id: string, layout = window.siyuan.layout.center
return _getInstanceById(layout, id);
};
export const addResize = (obj: Layout | Wnd) => {
export const addResize = (obj: Layout | Wnd, after = true) => {
if (!obj.resize) {
return;
}
@ -917,7 +864,12 @@ export const addResize = (obj: Layout | Wnd) => {
resizeElement.classList.add("layout__resize--lr");
}
resizeElement.classList.add("layout__resize");
obj.element.insertAdjacentElement("beforebegin", resizeElement);
if (after) {
obj.element.insertAdjacentElement((obj.element.previousElementSibling && !obj.element.previousElementSibling.classList.contains("layout__resize")) ?
"beforebegin" : "afterend", resizeElement);
} else {
obj.element.insertAdjacentElement("afterend", resizeElement);
}
resizeWnd(resizeElement, obj.resize);
resizeElement.addEventListener("dblclick", () => {
@ -985,6 +937,13 @@ export const adjustLayout = (layout: Layout = window.siyuan.layout.centerLayout.
} else {
item.element.style.minWidth = "";
}
if (!item.element.style.height && !item.element.classList.contains("layout__center") &&
item.element.classList.contains("fn__flex-column")) {
item.element.style.minHeight = "8px";
} else {
item.element.style.minHeight = "";
}
});
if (layout.direction === "lr" && layout.element.scrollWidth > layout.element.clientWidth + 2) {
let index = Math.ceil(screen.width / 8);

View file

@ -415,7 +415,7 @@ export const openAttr = (nodeElement: Element, focusName = "bookmark", protyle:
});
};
export const copySubMenu = (ids: string[], accelerator = true, focusElement?: Element, stdMarkdownId?: string) => {
export const copySubMenu = (ids: string[], accelerator = true, focusElement?: Element, stdMarkdownId?: string): IMenu[] => {
const menuItems = [{
id: "copyBlockRef",
iconHTML: "",

View file

@ -48,7 +48,7 @@ import {pushBack} from "../mobile/util/MobileBackFoward";
import {copyPNGByLink, exportAsset, writeAssetToClipboard} from "./util";
import {removeInlineType} from "../protyle/toolbar/util";
import {alignImgCenter, alignImgLeft} from "../protyle/wysiwyg/commonHotkey";
import {checkFold, renameTag} from "../util/noRelyPCFunction";
import {checkFold, genTagList, renameTag} from "../util/noRelyPCFunction";
import {hideElements} from "../protyle/ui/hideElements";
import {emitOpenMenu} from "../plugin/EventBus";
import {openMobileFileById} from "../mobile/editor";
@ -65,6 +65,7 @@ import {hideTooltip} from "../dialog/tooltip";
import {clearSelect} from "../protyle/util/clear";
import {scrollCenter} from "../util/highlightById";
import {base64ToURL} from "../util/image";
import {setPosition} from "../util/setPosition";
const renderAssetList = (element: Element, k: string, position: IPosition, exts: string[] = []) => {
fetchPost("/api/search/searchAsset", {
@ -572,7 +573,7 @@ export const refMenu = (protyle: IProtyle, element: HTMLElement) => {
}
}, {
id: "link",
label: window.siyuan.languages.link,
label: window.siyuan.languages.hyperlink,
iconHTML: "",
click() {
element.outerHTML = `<span data-type="a" data-href="siyuan://blocks/${element.getAttribute("data-id")}">${element.innerHTML}</span><wbr>`;
@ -1764,55 +1765,84 @@ style="margin:4px 0;width: ${isMobile() ? "100%" : "360px"}" class="b3-text-fiel
export const tagMenu = (protyle: IProtyle, tagElement: HTMLElement) => {
window.siyuan.menus.menu.remove();
window.siyuan.menus.menu.element.setAttribute("data-name", Constants.MENU_INLINE_TAG);
const nodeElement = hasClosestBlock(tagElement);
if (!nodeElement) {
return;
}
hideElements(["util", "toolbar", "hint"], protyle);
const id = nodeElement.getAttribute("data-node-id");
let html = nodeElement.outerHTML;
let inputElement: HTMLInputElement;
const oldHTML = nodeElement.outerHTML;
window.siyuan.menus.menu.removeCB = () => {
tagElement.innerHTML = Constants.ZWSP + Lute.EscapeHTMLStr(inputElement.value || "");
if (!inputElement.value) {
tagElement.insertAdjacentHTML("afterend", "<wbr>");
tagElement.remove();
focusByWbr(nodeElement, protyle.toolbar.range);
} else {
protyle.toolbar.range.selectNodeContents(tagElement);
protyle.toolbar.range.collapse(false);
focusByRange(protyle.toolbar.range);
}
if (nodeElement.outerHTML !== oldHTML) {
nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss"));
updateTransaction(protyle, id, nodeElement.outerHTML, oldHTML);
}
};
window.siyuan.menus.menu.element.setAttribute("data-name", Constants.MENU_INLINE_TAG);
window.siyuan.menus.menu.append(new MenuItem({
id: "tag",
iconHTML: "",
type: "readonly",
label: `<input class="b3-text-field fn__block" style="margin: 4px 0" placeholder="${window.siyuan.languages.tag}">`,
label: `<input class="b3-text-field fn__block" style="margin: 4px 0" placeholder="${window.siyuan.languages.tag}">
<div class="fn__none b3-list fn__flex-1 b3-list--background protyle-hint" style="position: fixed"></div>`,
bind(element) {
const inputElement = element.querySelector("input");
const listElement = element.querySelector(".b3-list") as HTMLElement;
inputElement = element.querySelector("input");
inputElement.value = tagElement.textContent.replace(Constants.ZWSP, "");
inputElement.addEventListener("change", () => {
updateTransaction(protyle, id, nodeElement.outerHTML, html);
html = nodeElement.outerHTML;
});
inputElement.addEventListener("compositionend", () => {
tagElement.innerHTML = Constants.ZWSP + Lute.EscapeHTMLStr(inputElement.value || "");
genTagList(listElement, inputElement.value.trim());
setPosition(listElement, inputElementRect.right + 8, inputElementRect[isMobile() ? "bottom" : "top"], inputElementRect.height);
});
inputElement.addEventListener("input", (event: KeyboardEvent) => {
if (!event.isComposing) {
// https://github.com/siyuan-note/siyuan/issues/4511
tagElement.innerHTML = Constants.ZWSP + Lute.EscapeHTMLStr(inputElement.value || "");
listElement.classList.remove("fn__none");
genTagList(listElement, inputElement.value.trim());
setPosition(listElement, inputElementRect.right + 8, inputElementRect[isMobile() ? "bottom" : "top"], inputElementRect.height);
}
});
inputElement.addEventListener("keydown", (event) => {
if ((event.key === "Enter" || event.key === "Escape") && !event.isComposing) {
event.preventDefault();
event.stopPropagation();
if (!inputElement.value) {
const oldHTML = nodeElement.outerHTML;
tagElement.insertAdjacentHTML("afterend", "<wbr>");
tagElement.remove();
nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss"));
updateTransaction(protyle, id, nodeElement.outerHTML, oldHTML);
focusByWbr(nodeElement, protyle.toolbar.range);
} else {
protyle.toolbar.range.selectNodeContents(tagElement);
protyle.toolbar.range.collapse(false);
focusByRange(protyle.toolbar.range);
}
window.siyuan.menus.menu.remove();
} else if (electronUndo(event)) {
event.stopPropagation();
if (event.isComposing) {
return;
}
if (event.key === "Enter" || event.key === "Escape") {
if (!listElement.classList.contains("fn__none")) {
listElement.classList.add("fn__none");
if (event.key === "Enter") {
const currentElement = listElement.querySelector(".b3-list-item--focus") as HTMLElement;
inputElement.value = currentElement.dataset.type === "new" ? currentElement.querySelector("mark").textContent.trim() : currentElement.textContent.trim();
}
return;
}
if (event.key === "Escape") {
window.siyuan.menus.menu.removeCB = null;
}
window.siyuan.menus.menu.remove();
event.preventDefault();
} else {
electronUndo(event);
upDownHint(listElement, event);
}
});
listElement.addEventListener("click", (event) => {
const target = event.target as HTMLElement;
const listItemElement = hasClosestByClassName(target, "b3-list-item");
if (!listItemElement) {
return;
}
inputElement.value = listItemElement.dataset.type === "new" ? listItemElement.querySelector("mark").textContent.trim() : listItemElement.textContent.trim();
listElement.classList.add("fn__none");
});
}
}).element);
@ -1885,7 +1915,6 @@ export const tagMenu = (protyle: IProtyle, tagElement: HTMLElement) => {
icon: "iconTrashcan",
label: window.siyuan.languages.remove,
click() {
const oldHTML = nodeElement.outerHTML;
tagElement.insertAdjacentHTML("afterend", "<wbr>");
tagElement.remove();
nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss"));
@ -1918,7 +1947,8 @@ export const tagMenu = (protyle: IProtyle, tagElement: HTMLElement) => {
/// #endif
const popoverElement = hasTopClosestByClassName(protyle.element, "block__popover", true);
window.siyuan.menus.menu.element.setAttribute("data-from", popoverElement ? popoverElement.dataset.level + "popover" : "app");
window.siyuan.menus.menu.element.querySelector("input").select();
inputElement.select();
const inputElementRect = inputElement.getBoundingClientRect();
};
export const inlineMathMenu = (protyle: IProtyle, element: Element) => {

View file

@ -12,6 +12,8 @@ import {App} from "../index";
import {exportByMobile, isInAndroid, updateHotkeyTip} from "../protyle/util/compatibility";
import {checkFold} from "../util/noRelyPCFunction";
import {showMessage} from "../dialog/message";
import {Editor} from "../editor";
import {setEditMode} from "../protyle/util/setEditMode";
export const exportAsset = (src: string) => {
return {
@ -164,7 +166,11 @@ export const openEditorTab = (app: App, ids: string[], notebookId?: string, path
label: window.siyuan.languages.preview,
click: () => {
ids.forEach((id) => {
openFileById({app, id, mode: "preview"});
openFileById({
app, id, mode: "preview", afterOpen(editor: Editor) {
setEditMode(editor.editor.protyle, "preview");
}
});
});
}
});

View file

@ -527,7 +527,7 @@ export class MobileFiles extends Model {
if (!fileItemElement) {
return;
}
fileItemElement.setAttribute("data-name", Lute.EscapeHTMLStr(data.title));
fileItemElement.setAttribute("data-name", data.title);
fileItemElement.querySelector(".b3-list-item__text").innerHTML = escapeHtml(data.title);
}
@ -802,7 +802,7 @@ class="b3-list-item" data-path="${item.path}">
</span>
<span class="b3-list-item__icon"${editingPublishAccess ? " fn__none" : ""}>${unicode2Emoji(item.icon || (item.subFileCount === 0 ? window.siyuan.storage[Constants.LOCAL_IMAGES].file : window.siyuan.storage[Constants.LOCAL_IMAGES].folder))}</span>
<span class="b3-list-item__switch${editingPublishAccess ? "" : " fn__none"}">${getPublishAccessOptionByLevel("public").iconHTML}</span>
<span class="b3-list-item__text">${getDisplayName(item.name, true, true)}</span>
<span class="b3-list-item__text">${getDisplayName(Lute.EscapeHTMLStr(item.name), true, true)}</span>
<span data-type="more-file" class="b3-list-item__action b3-tooltips b3-tooltips__nw" aria-label="${window.siyuan.languages.more}">
<svg><use xlink:href="#iconMore"></use></svg>
</span>

View file

@ -1,12 +1,7 @@
import {Tree} from "../../util/Tree";
import {fetchPost} from "../../util/fetch";
import {hasClosestBlock, hasClosestByClassName} from "../../protyle/util/hasClosest";
import {
isInAndroid,
isInHarmony,
setStorageVal,
writeText
} from "../../protyle/util/compatibility";
import {isInAndroid, isInHarmony, setStorageVal, writeText} from "../../protyle/util/compatibility";
import {Constants} from "../../constants";
import {MenuItem} from "../../menus/Menu";
import {getPreviousBlock} from "../../protyle/wysiwyg/getBlock";
@ -35,6 +30,7 @@ export class MobileOutline extends Model {
super({
app: options.app,
id: genUUID(),
type: "outline",
msgCallback(data) {
if (data) {
switch (data.cmd) {

View file

@ -2,7 +2,12 @@ import {addScript, addScriptSync} from "../protyle/util/addScript";
import {Constants} from "../constants";
import {onMessage} from "./util/onMessage";
import {genUUID} from "../util/genID";
import {hasClosestBlock, hasClosestByAttribute, hasTopClosestByClassName} from "../protyle/util/hasClosest";
import {
hasClosestBlock,
hasClosestByAttribute,
hasClosestByClassName,
hasTopClosestByClassName
} from "../protyle/util/hasClosest";
import {Model} from "../layout/Model";
import "../assets/scss/mobile.scss";
import {Menus} from "../menus";
@ -30,9 +35,9 @@ import {updateCardHV} from "../card/util";
import {mobileKeydown} from "./util/keydown";
import {correctHotkey} from "../boot/globalEvent/commonHotkey";
import {processIOSPurchaseResponse} from "../util/iOSPurchase";
import {updateControlAlt} from "../protyle/util/hotKey";
import {nbsp2space} from "../protyle/util/normalizeText";
import {callMobileAppShowKeyboard, canInput, setWebViewFocusable} from "./util/mobileAppUtil";
import {hideAllElements} from "../protyle/ui/hideElements";
class App {
public plugins: import("../plugin").Plugin[] = [];
@ -101,6 +106,9 @@ class App {
callMobileAppShowKeyboard();
}
}
if (!hasClosestByClassName(event.target as Element, "protyle-util")) {
hideAllElements(["util"]);
}
});
if (window.JSAndroid && window.JSAndroid.showKeyboard || window.JSHarmony && window.JSHarmony.showKeyboard) {
const __siyuan_original_focus = HTMLElement.prototype.focus;
@ -132,7 +140,6 @@ class App {
addScriptSync(`${Constants.PROTYLE_CDN}/js/lute/lute.min.js?v=${Constants.SIYUAN_VERSION}`, "protyleLuteScript");
addScript(`${Constants.PROTYLE_CDN}/js/protyle-html.js?v=${Constants.SIYUAN_VERSION}`, "protyleWcHtmlScript");
window.siyuan.config = confResponse.data.conf;
updateControlAlt();
window.siyuan.isPublish = confResponse.data.isPublish;
correctHotkey(siyuanApp);
await loadPlugins(this);

View file

@ -7,7 +7,7 @@ import {
} from "../../protyle/util/hasClosest";
import {moveToDown, moveToUp} from "../../protyle/wysiwyg/move";
import {Constants} from "../../constants";
import {focusByRange, getSelectionPosition} from "../../protyle/util/selection";
import {focusBlock, focusByRange, getSelectionPosition} from "../../protyle/util/selection";
import {getCurrentEditor} from "../editor";
import {fontEvent, getFontNodeElements} from "../../protyle/toolbar/Font";
import {hideElements} from "../../protyle/ui/hideElements";
@ -15,6 +15,7 @@ import {softEnter} from "../../protyle/wysiwyg/enter";
import {isInAndroid, isInEdge, isInHarmony} from "../../protyle/util/compatibility";
import {tabCodeBlock} from "../../protyle/wysiwyg/codeBlock";
import {callMobileAppShowKeyboard, canInput, keyboardLockUntil} from "./mobileAppUtil";
import {isNotEditBlock} from "../../protyle/wysiwyg/getBlock";
let renderKeyboardToolbarTimeout: number;
let showUtil = false;
@ -440,13 +441,24 @@ export const showKeyboardToolbar = () => {
setTimeout(() => {
const contentElement = hasClosestByClassName(range.startContainer, "protyle-content", true);
if (contentElement) {
const contentTop = contentElement.getBoundingClientRect().top;
const cursorTop = getSelectionPosition(contentElement).top;
if (cursorTop < window.innerHeight - 42 && cursorTop > contentTop) {
let cursorTop = getSelectionPosition(contentElement).top;
if (cursorTop < 0 && window.siyuan.mobile.touchRange) {
const rangeBlockElement = hasClosestBlock(window.siyuan.mobile.touchRange.startContainer);
if (rangeBlockElement) {
if (isNotEditBlock(rangeBlockElement)) {
focusBlock(rangeBlockElement);
} else {
focusByRange(window.siyuan.mobile.touchRange);
}
cursorTop = getSelectionPosition(contentElement, window.siyuan.mobile.touchRange).top;
}
}
if (cursorTop < window.innerHeight - 42 && cursorTop > contentElement.getBoundingClientRect().top) {
return;
}
contentElement.scroll({
top: contentElement.scrollTop + cursorTop - window.innerHeight + 42 + 26,
top: cursorTop < 0 ? contentElement.scrollTop + window.innerHeight - 42 :
contentElement.scrollTop + cursorTop - window.innerHeight + 42 + 26,
left: contentElement.scrollLeft,
behavior: "smooth"
});
@ -731,6 +743,13 @@ export const initKeyboardToolbar = () => {
renderTextMenu(protyle, toolbarElement);
showKeyboardToolbarUtil(oldScrollTop);
window.JSAndroid?.hideKeyboard();
setTimeout(() => {
focusByRange(range);
preventRender = true;
setTimeout(() => {
preventRender = false;
}, 1000);
}, Constants.TIMEOUT_TRANSITION);
}
return;
} else if (type === "moveup") {

View file

@ -11,7 +11,6 @@ import {App} from "../../index";
import {reloadPlugin} from "../../plugin/loader";
import {reloadEmoji} from "../../emoji";
import {setLocalShorthandCount} from "../../util/noRelyPCFunction";
import {updateControlAlt} from "../../protyle/util/hotKey";
import {renderSnippet} from "../../config/util/snippets";
import {redirectToCheckAuth} from "../../util/pathName";
@ -67,7 +66,6 @@ export const onMessage = (app: App, data: IWebSocketData) => {
break;
case "setConf":
window.siyuan.config = data.data;
updateControlAlt();
break;
case "setPublish":
window.siyuan.config.publish = data.data;
@ -92,7 +90,7 @@ export const onMessage = (app: App, data: IWebSocketData) => {
openMobileFileById(app, data.data.id);
break;
case"txerr":
transactionError();
transactionError(data.msg);
break;
case"statusbar":
if (!document.querySelector("#keyboardToolbar").classList.contains("fn__none") ||

View file

@ -10,6 +10,8 @@ import {activeBlur} from "./keyboardToolbar";
import {isIPhone} from "../../protyle/util/compatibility";
import {App} from "../../index";
import {globalTouchEnd, globalTouchStart} from "../../boot/globalEvent/touch";
import {getRangeByPoint} from "../../protyle/util/selection";
import {getCurrentEditor} from "../editor";
let clientX: number;
let clientY: number;
@ -164,6 +166,15 @@ export const handleTouchStart = (event: TouchEvent) => {
if (globalTouchStart(event)) {
return;
}
if (getSelection().rangeCount > 0 && hasClosestBlock(event.target as Element)) {
const editor = getCurrentEditor();
if (editor && !editor.protyle.disabled && event.touches[0].clientY > window.innerHeight / 2 &&
document.querySelector("#keyboardToolbar").classList.contains("fn__none")) {
window.siyuan.mobile.touchRange = getRangeByPoint(event.touches[0].clientX, event.touches[0].clientY);
}
}
firstDirection = null;
xDiff = undefined;
yDiff = undefined;

View file

@ -80,6 +80,7 @@ openTab = (options: {
id: string, // 块 id
action?: TProtyleAction [] // cb-get-all获取所有内容cb-get-focus打开后光标定位在 id 所在的块cb-get-hl: 打开后 id 块高亮
zoomIn?: boolean // 是否缩放
mode?: TEditorMode // 文档打开模式,默认 "wysiwyg"
},
pdf?: {
path: string,
@ -126,7 +127,8 @@ openTab = (options: {
id: options.doc.id,
action: options.doc.action,
zoomIn: options.doc.zoomIn,
scrollPosition: "start"
scrollPosition: "start",
mode: options.doc.mode,
});
}
if (options.asset) {

View file

@ -76,19 +76,19 @@ export const uninstall = (app: App, name: string, isReload: boolean) => {
}
}
if (Object.keys(window.siyuan.layout.leftDock.data).includes(key)) {
if (window.siyuan.layout.leftDock && Object.keys(window.siyuan.layout.leftDock.data).includes(key)) {
window.siyuan.layout.leftDock.remove(key);
if (dockIconElement) {
window.siyuan.storage[Constants.LOCAL_PLUGIN_DOCKS][plugin.name][key].position =
"Left" + (dockIconElement.getAttribute("data-index") === "0" ? "Top" : "Bottom");
}
} else if (Object.keys(window.siyuan.layout.rightDock.data).includes(key)) {
} else if (window.siyuan.layout.rightDock && Object.keys(window.siyuan.layout.rightDock.data).includes(key)) {
window.siyuan.layout.rightDock.remove(key);
if (dockIconElement) {
window.siyuan.storage[Constants.LOCAL_PLUGIN_DOCKS][plugin.name][key].position =
"Right" + (dockIconElement.getAttribute("data-index") === "0" ? "Top" : "Bottom");
}
} else if (Object.keys(window.siyuan.layout.bottomDock.data).includes(key)) {
} else if (window.siyuan.layout.bottomDock && Object.keys(window.siyuan.layout.bottomDock.data).includes(key)) {
window.siyuan.layout.bottomDock.remove(key);
if (dockIconElement) {
window.siyuan.storage[Constants.LOCAL_PLUGIN_DOCKS][plugin.name][key].position =

View file

@ -1,12 +1,11 @@
/// #if !MOBILE
import {getAllEditor, getAllModels, getAllWnds} from "../../layout/getAll";
import {getAllModels, getAllWnds} from "../../layout/getAll";
/// #endif
import {addLoading} from "../ui/initUI";
import {fetchPost} from "../../util/fetch";
import {Constants} from "../../constants";
import {hideAllElements, hideElements} from "../ui/hideElements";
import {hasClosestByClassName} from "../util/hasClosest";
import {reloadProtyle} from "../util/reload";
import {resize} from "../util/resize";
import {disabledProtyle, enableProtyle} from "../util/onGet";
import {isWindow} from "../../util/functions";
@ -20,16 +19,6 @@ export const net2LocalAssets = (protyle: IProtyle, type: "Assets" | "Img") => {
hideElements(["toolbar"], protyle);
fetchPost(`/api/format/net${type}2LocalAssets`, {
id: protyle.block.rootID
}, () => {
/// #if MOBILE
reloadProtyle(protyle, false);
/// #else
getAllEditor().forEach(item => {
if (item.protyle.block.rootID === protyle.block.rootID) {
reloadProtyle(item.protyle, item.protyle.element === protyle.element);
}
});
/// #endif
});
};
@ -111,7 +100,7 @@ export const fullscreen = (element: Element, btnElement?: Element) => {
};
export const updateReadonly = (target: Element, protyle: IProtyle) => {
if (!window.siyuan.config.readonly) {
if (!window.siyuan.config.readonly && protyle.element.getAttribute("disabled-forever") !== "true") {
const isReadonly = target.querySelector("use").getAttribute("xlink:href") !== "#iconUnlock";
if (window.siyuan.config.editor.readOnly) {
if (isReadonly) {

View file

@ -573,6 +573,9 @@ ${padHTML}
}
public render(protyle: IProtyle, update = false, nodeElement?: Element | false) {
if (protyle.element.getAttribute("disabled-forever") === "true") {
return;
}
/// #if !MOBILE
let range: Range;
let blockElement: Element;

View file

@ -8,7 +8,7 @@ import {Dialog} from "../../dialog";
import {addScript} from "../util/addScript";
import {isMobile} from "../../util/functions";
import {Constants} from "../../constants";
import {highlightRender} from "../render/highlightRender";
import {highlightRender, lineNumberRender} from "../render/highlightRender";
import {processRender} from "../util/processCode";
import {isIPhone, isSafari, openByMobile, setStorageVal} from "../util/compatibility";
import {useShell} from "../../util/pathName";
@ -27,6 +27,7 @@ export const afterExport = (exportPath: string, msgId: string) => {
export const exportImage = (id: string) => {
const exportDialog = new Dialog({
disableAnimation: true,
title: window.siyuan.languages.exportAsImage,
content: `<div class="b3-dialog__content" style="${isMobile() ? "padding:8px;" : ""};background-color: var(--b3-theme-background)">
<div style="${isMobile() ? "margin: 8px 0" : "padding: 48px;margin: 8px 0"}" class="export-img">
@ -51,7 +52,14 @@ export const exportImage = (id: string) => {
</div>
<div class="fn__loading"><img height="128px" width="128px" src="stage/loading-pure.svg"></div>`,
width: isMobile() ? "92vw" : "990px",
height: "70vh"
height: "70vh",
resizeCallback() {
previewElement.querySelectorAll(".code-block .protyle-linenumber__rows").forEach((item: HTMLElement) => {
if ((item.nextElementSibling as HTMLElement).style.wordBreak === "break-word") {
lineNumberRender(item.parentElement);
}
});
}
});
exportDialog.element.setAttribute("data-key", Constants.DIALOG_EXPORTIMAGE);
const btnsElement = exportDialog.element.querySelectorAll(".b3-button");

View file

@ -2565,8 +2565,14 @@ export class Gutter {
if (index === 0) {
// 不单独显示要不然在块的间隔中gutter 会跳来跳去的
if (["NodeBlockquote", "NodeList", "NodeCallout", "NodeSuperBlock"].includes(type)) {
if (target && type === "NodeCallout" && hasTopClosestByClassName(target, "callout-info")) {
if (target && type === "NodeCallout") {
// Callout 标题需显示
const calloutInfoElement = hasTopClosestByClassName(target, "callout-info");
if (calloutInfoElement) {
element = calloutInfoElement;
} else {
return;
}
} else {
return;
}
@ -2585,7 +2591,13 @@ export class Gutter {
}
// 标题(除列表下的)、提示下的块必须显示
if (topElement !== nodeElement && type !== "NodeHeading" && !hasClosestByClassName(nodeElement, "callout")) {
nodeElement = topElement;
while (nodeElement !== topElement) {
nodeElement = nodeElement.parentElement;
// > > > > 1 left 位置
if (nodeElement.parentElement.classList.contains("bq")) {
space += 10;
}
}
parentElement = hasClosestBlock(nodeElement.parentElement);
type = nodeElement.getAttribute("data-type");
dataNodeId = nodeElement.getAttribute("data-node-id");
@ -2606,11 +2618,11 @@ export class Gutter {
if (protyle.options.backlinkData) {
popoverHTML = `class="popover__block" data-id="${dataNodeId}"`;
}
const buttonHTML = `<button class="ariaLabel" data-position="parentW" aria-label="${gutterTip}"
const buttonHTML = type ? `<button class="ariaLabel" data-position="parentW" aria-label="${gutterTip}"
data-type="${type}" data-subtype="${nodeElement.getAttribute("data-subtype")}" data-node-id="${dataNodeId}">
<svg><use xlink:href="#${getIconByType(type, nodeElement.getAttribute("data-subtype"))}"></use></svg>
<span ${popoverHTML} ${protyle.disabled ? "" : 'draggable="true"'}></span>
</button>`;
</button>` : "";
if (!hideParent) {
html = buttonHTML + html;
}
@ -2618,7 +2630,7 @@ data-type="${type}" data-subtype="${nodeElement.getAttribute("data-subtype")}" d
if (type === "NodeListItem" && nodeElement.childElementCount > 3 || type === "NodeHeading") {
const fold = nodeElement.getAttribute("fold");
foldHTML = `<button class="ariaLabel" data-position="parentW" aria-label="${window.siyuan.languages.fold}"
data-type="fold" style="cursor:inherit;"><svg style="width: 10px${fold && fold === "1" ? "" : ";transform:rotate(90deg)"}"><use xlink:href="#iconPlay"></use></svg></button>`;
data-type="fold" style="cursor:inherit;"><svg style="width: 10px;${fold && fold === "1" ? "" : "transform:rotate(90deg)"}"><use xlink:href="#iconPlay"></use></svg></button>`;
}
if (type === "NodeListItem" || type === "NodeList") {
listItem = nodeElement;
@ -2630,7 +2642,7 @@ data-type="fold" style="cursor:inherit;"><svg style="width: 10px${fold && fold =
html = html + foldHTML;
}
if (["NodeBlockquote", "NodeCallout"].includes(type)) {
space += 8;
space += 10;
}
if ((nodeElement.previousElementSibling && nodeElement.previousElementSibling.getAttribute("data-node-id")) ||
nodeElement.parentElement.classList.contains("callout-content")) {
@ -2642,7 +2654,7 @@ data-type="fold" style="cursor:inherit;"><svg style="width: 10px${fold && fold =
}
// 列表项中的引述块中的第二个段落块块标和引述块左侧样式重叠
if (parentElement && ["NodeBlockquote", "NodeCallout"].includes(parentElement.getAttribute("data-type"))) {
space += 8;
space += 10;
}
}
}

View file

@ -262,11 +262,11 @@ export class Background {
} else if (type === "show-random" && !protyle.disabled) {
let html = "";
bgs.forEach((item: string, index: number) => {
html += `<div data-index="${index}" style="height: 128px;${item}" class="b3-card b3-card--wrap"></div>`;
html += `<div data-index="${index}" style="height: 128px;${item}" class="b3-card"></div>`;
});
const dialog = new Dialog({
title: window.siyuan.languages.builtIn,
content: `<div class="b3-cards">${html}</div>`,
content: `<div class="b3-cards" style="padding: 16px">${html}</div>`,
width: isMobile() ? "92vw" : "912px",
height: isMobile() ? "80vh" : "70vh",
});

View file

@ -2,7 +2,7 @@ import {fetchPost, fetchSyncPost} from "../../util/fetch";
import {MenuItem} from "../../menus/Menu";
import {copySubMenu, exportMd, movePathToMenu, openFileAttr, openFileWechatNotify,} from "../../menus/commonMenuItem";
import {deleteFile} from "../../editor/deleteFile";
import {updateHotkeyTip} from "../util/compatibility";
import {encodeBase64, updateHotkeyTip} from "../util/compatibility";
/// #if !MOBILE
import {openBacklink, openGraph, openOutline} from "../../layout/dock/util";
import * as path from "path";
@ -25,6 +25,8 @@ import {transferBlockRef} from "../../menus/block";
import {addEditorToDatabase} from "../render/av/addToDatabase";
import {openFileById} from "../../editor/util";
import {hasTopClosestByClassName} from "../util/hasClosest";
import {showMessage} from "../../dialog/message";
import {removeZWJ} from "../util/normalizeText";
export const openTitleMenu = (protyle: IProtyle, position: IPosition, from: string) => {
hideTooltip();
@ -40,12 +42,41 @@ export const openTitleMenu = (protyle: IProtyle, position: IPosition, from: stri
window.siyuan.menus.menu.element.setAttribute("data-name", Constants.MENU_TITLE);
const popoverElement = hasTopClosestByClassName(protyle.element, "block__popover", true);
window.siyuan.menus.menu.element.setAttribute("data-from", popoverElement ? popoverElement.dataset.level + "popover-" + from : "app-" + from);
const submenu = copySubMenu([protyle.block.rootID], true, undefined, protyle.block.showAll ? protyle.block.id : protyle.block.rootID);
submenu.push({
iconHTML: "",
label: window.siyuan.languages.copyDoc,
accelerator: undefined,
click: async () => {
const [responseHTML, responseText] = await Promise.all([
fetchSyncPost("/api/block/getBlockDOM", {id: protyle.block.rootID}),
fetchSyncPost("/api/export/exportMdContent", {
id: protyle.block.rootID,
refMode: 3,
embedMode: 1,
yfm: false,
fillCSSVar: false,
adjustHeadingLevel: false
})
]);
const textHTML = `<!--data-siyuan='${encodeBase64(responseHTML.data.dom)}'-->${removeZWJ(responseHTML.data.dom)}`;
await navigator.clipboard.write([
new ClipboardItem({
"text/plain": new Blob([responseText.data.content], {type: "text/plain"}),
"text/html": new Blob([textHTML], {type: "text/html"}),
})
]);
showMessage(window.siyuan.languages.copied);
}
});
window.siyuan.menus.menu.append(new MenuItem({
id: "copy",
label: window.siyuan.languages.copy,
icon: "iconCopy",
type: "submenu",
submenu: copySubMenu([protyle.block.rootID], true, undefined, protyle.block.showAll ? protyle.block.id : protyle.block.rootID)
submenu,
}).element);
if (!protyle.disabled) {
window.siyuan.menus.menu.append(movePathToMenu([protyle.path]));

View file

@ -647,8 +647,8 @@ ${genHintItemHTML(item)}
blockRender(protyle, protyle.wysiwyg.element);
return;
} else if (this.splitChar === "/" || this.splitChar === "、") {
this.enableExtend = true;
if (value === "((" || value === "{{") {
this.enableExtend = true;
if (value === "((") {
hintRef("", protyle, "hint");
} else {

View file

@ -48,6 +48,7 @@ import {getAllModels} from "../layout/getAll";
import {isSupportCSSHL} from "./render/searchMarkRender";
import {renderAVAttribute} from "./render/av/blockAttr";
import {setFoldById, zoomOut} from "../menus/protyle";
import {setEditMode} from "./util/setEditMode";
export class Protyle {
@ -306,9 +307,15 @@ export class Protyle {
}
let needCreateAction = "";
data.data[0].doOperations.find((item: IOperation) => {
if (this.protyle.options.backlinkData && ["delete", "move"].includes(item.action)) {
if (this.protyle.options.backlinkData && ["delete", "move"].includes(item.action)) {
// 只对特定情况刷新,否则展开、编辑等操作刷新会频繁
/// #if !MOBILE
if (2 == data.data[0].doOperations.length && "insert" === data.data[0].doOperations[0].action && "delete" === data.data[0].doOperations[1].action) {
// 从反链面板复制块到正文粘贴时不再自动刷新反链面板
// The list in the backlink panel no longer collapses automatically https://github.com/siyuan-note/siyuan/issues/17362
return true;
}
getAllModels().backlink.find(backlinkItem => {
if (backlinkItem.element.contains(this.protyle.element)) {
backlinkItem.refresh();
@ -528,4 +535,8 @@ export class Protyle {
public renderAVAttribute(element: HTMLElement, id: string, cb?: (element: HTMLElement) => void) {
renderAVAttribute(element, id, this.protyle, cb);
}
public switchMode(mode: TEditorMode) {
setEditMode(this.protyle, mode);
}
}

View file

@ -786,13 +786,6 @@ export const updateCellsValue = async (protyle: IProtyle, nodeElement: HTMLEleme
name = getAssetName(value) + pathPosix().extname(value);
}
// https://github.com/siyuan-note/siyuan/issues/12308
if (link) {
htmlValue.push({
type: "file",
content: link,
name
});
}
if (html) {
const tempElement = document.createElement("template");
tempElement.innerHTML = html;
@ -811,14 +804,28 @@ export const updateCellsValue = async (protyle: IProtyle, nodeElement: HTMLEleme
});
}
});
if (htmlValue.length === 0 && value) {
}
if (link) {
const hasExited = htmlValue.find(valueItem => {
if (valueItem.content === link) {
return true;
}
});
if (!hasExited) {
htmlValue.push({
type: "file",
content: "",
name: value
content: link,
name
});
}
}
if (htmlValue.length === 0 && value) {
htmlValue.push({
type: "file",
content: "",
name: value
});
}
newValue = oldValue.mAsset.concat(htmlValue);
}
} else if (type === "mSelect" || type === "select") {

View file

@ -2,6 +2,7 @@ import {addScript} from "../util/addScript";
import {Constants} from "../../constants";
import {focusByOffset} from "../util/selection";
import {setCodeTheme} from "./util";
import {escapeHtml} from "../../util/escape";
export const highlightRender = (element: Element, cdn = Constants.PROTYLE_CDN, zoom = 1) => {
let codeElements: NodeListOf<Element>;
@ -116,24 +117,26 @@ export const highlightRender = (element: Element, cdn = Constants.PROTYLE_CDN, z
});
};
export const lineNumberRender = (block: HTMLElement, zoom = 1) => {
const lineNumber = block.parentElement.getAttribute("lineNumber");
export const lineNumberRender = (hljsElement: HTMLElement, zoom = 1) => {
const lineNumber = hljsElement.parentElement.getAttribute("lineNumber");
if (lineNumber === "false") {
return;
}
if (!window.siyuan.config.editor.codeSyntaxHighlightLineNum && lineNumber !== "true") {
return;
}
const codeElement = hljsElement.lastElementChild as HTMLElement;
if (hljsElement.firstElementChild.clientHeight === codeElement.clientHeight && codeElement.style.wordBreak !== "break-word") {
return;
}
// clientHeight 总是取的整数
block.parentElement.style.lineHeight = `${((parseInt(block.parentElement.style.fontSize) || window.siyuan.config.editor.fontSize) * 1.625 * 0.85).toFixed(0)}px`;
const codeElement = block.lastElementChild as HTMLElement;
hljsElement.parentElement.style.lineHeight = `${((parseInt(hljsElement.parentElement.style.fontSize) || window.siyuan.config.editor.fontSize) * 1.625 * 0.85).toFixed(0)}px`;
const lineList = codeElement.textContent.split(/\r\n|\r|\n|\u2028|\u2029/g);
if (lineList[lineList.length - 1] === "" && lineList.length > 1) {
lineList.pop();
}
block.firstElementChild.innerHTML = `<span>${lineList.length}</span>`;
codeElement.style.paddingLeft = `${block.firstElementChild.clientWidth + 16}px`;
hljsElement.firstElementChild.innerHTML = `<span>${lineList.length}</span>`;
codeElement.style.paddingLeft = `${hljsElement.firstElementChild.clientWidth + 16}px`;
let lineNumberHTML = "";
if (codeElement.style.wordBreak === "break-word") {
// 代码块开启了换行
@ -142,7 +145,7 @@ export const lineNumberRender = (block: HTMLElement, zoom = 1) => {
lineNumberTemp.className = "hljs";
// 不能使用 codeElement.clientWidth被忽略小数点导致宽度不一致
// 需要手动复制字体样式 https://ld246.com/article/1762527296449
lineNumberTemp.setAttribute("style", `padding-left:${codeElement.style.paddingLeft};
lineNumberTemp.innerHTML = `<div contenteditable="true" style="padding-left:${codeElement.style.paddingLeft};
width: ${codeElement.getBoundingClientRect().width / zoom}px;
white-space:${codeElementStyle.whiteSpace};
word-break:${codeElementStyle.wordBreak};
@ -151,31 +154,26 @@ font-family:${codeElementStyle.fontFamily};
font-size:${codeElementStyle.fontSize};
line-height:${codeElementStyle.lineHeight};
font-weight:${codeElementStyle.fontWeight};
padding-right:0;max-height: none;box-sizing: border-box;position: absolute;padding-top:0 !important;padding-bottom:0 !important;min-height:auto !important;`);
lineNumberTemp.setAttribute("contenteditable", "true");
block.insertAdjacentElement("afterend", lineNumberTemp);
padding-right:0;max-height: none;box-sizing: border-box;position: absolute;padding-top:0 !important;padding-bottom:0 !important;min-height:auto !important;"></div>`;
lineNumberTemp.firstElementChild.innerHTML = lineList.map(line =>
`<div>${line.trim() ? escapeHtml(line) : "&nbsp;" }</div>`
).join("");
hljsElement.insertAdjacentElement("afterend", lineNumberTemp);
lineList.map((line) => {
// windows 下空格高度为 0 https://github.com/siyuan-note/siyuan/issues/12346
lineNumberTemp.textContent = line.trim() ? line : "<br>";
// 不能使用 lineNumberTemp.getBoundingClientRect().height.toFixed(1) 否则
// windows 需等待字体下载完成再计算,否则导致不换行,高度计算错误
// https://github.com/siyuan-note/siyuan/issues/9029
// https://github.com/siyuan-note/siyuan/issues/9140
lineNumberHTML += `<span style="height:${lineNumberTemp.clientHeight}px"></span>`;
});
const childNodes = lineNumberTemp.firstElementChild.children;
for (let i = 0; i < childNodes.length; i++) {
lineNumberHTML += `<span style="height:${childNodes[i].clientHeight}px"></span>`;
}
lineNumberTemp.remove();
} else {
lineNumberHTML = "<span></span>".repeat(lineList.length);
}
block.firstElementChild.innerHTML = lineNumberHTML;
hljsElement.firstElementChild.innerHTML = lineNumberHTML;
// https://github.com/siyuan-note/siyuan/issues/12726
if (block.scrollHeight > block.clientHeight) {
if (hljsElement.scrollHeight > hljsElement.clientHeight) {
if (getSelection().rangeCount > 0) {
const range = getSelection().getRangeAt(0);
if (block.contains(range.startContainer)) {
if (hljsElement.contains(range.startContainer)) {
const brElement = document.createElement("br");
range.insertNode(brElement);
brElement.scrollIntoView({block: "nearest"});

View file

@ -98,7 +98,15 @@ const initMermaid = (mermaidElements: Element[]) => {
try {
renderElement.innerHTML = `<span style="position: absolute;left:0;top:0;width: 1px;">${Constants.ZWSP}</span><div contenteditable="false"><span id="${id}"></span></div>`;
const mermaidData = await window.mermaid.render(id, Lute.UnEscapeHTMLStr(item.getAttribute("data-content")));
renderElement.lastElementChild.innerHTML = mermaidData.svg;
let svg = mermaidData.svg.replace(/(href|src|xlink:href)\s*=\s*["']\\\\/gi, (match, p1) => `${p1}="about:blank"`);
svg = window.DOMPurify.sanitize(svg, {
USE_PROFILES: { svg: true, svgFilters: true },
ADD_TAGS: ["foreignObject", "use", "style"],
ADD_ATTR: ["dominant-baseline", "xlink:href", "href"], // 保留对齐和链接属性
// 必须添加此项,否则 foreignObject 里的 HTML 内容会被清空
HTML_INTEGRATION_POINTS: { foreignobject: true }
});
renderElement.lastElementChild.innerHTML = svg;
} catch (e) {
const errorElement = document.querySelector("#" + id);
renderElement.lastElementChild.innerHTML = `${errorElement.outerHTML}<div class="fn__hr"></div><div class="ft__error">${e.message.replace(/\n/, "<br>")}</div>`;

View file

@ -47,6 +47,10 @@ export const setLute = (options: ILuteOptions) => {
});
lute.PutEmojis(emojis);
}
lute.SetUnorderedListMarker("-");;
lute.SetUnorderedListMarker("-");
lute.SetDataTask(true);
lute.SetExportNormalizeTaskListMarker(true);
lute.SetArbitraryTaskListItemMarker(true);
return lute;
};

View file

@ -139,8 +139,8 @@ const moveTo = async (protyle: IProtyle, sourceElements: Element[], targetElemen
newSourceElements.push(copyElement);
}
} else {
const topSourceElement = getTopAloneElement(item);
const oldSourceParentElement = item.parentElement;
let topSourceElement = getTopAloneElement(item);
const oldSourceParentElement = getParentBlock(item);
if (item.classList.contains("li") && item.getAttribute("data-subtype") === "o") {
orderListElements[item.parentElement.getAttribute("data-node-id")] = item.parentElement;
}
@ -163,7 +163,10 @@ const moveTo = async (protyle: IProtyle, sourceElements: Element[], targetElemen
}
if (topSourceElement !== item) {
// 删除空元素
if (topSourceElement.contains(item)) {
topSourceElement = getTopAloneElement(oldSourceParentElement);
}
// 拖拽后剩下空元素
doOperations.push({
action: "delete",
id: topSourceElement.getAttribute("data-node-id"),
@ -570,7 +573,11 @@ export const dropEvent = (protyle: IProtyle, editorElement: HTMLElement) => {
target.parentElement.classList.add("protyle-wysiwyg--select");
const ghostElement = document.createElement("div");
ghostElement.className = protyle.wysiwyg.element.className;
ghostElement.append(processClonePHElement(target.parentElement.cloneNode(true) as Element));
const cloneElement = processClonePHElement(target.parentElement.cloneNode(true) as Element);
cloneElement.querySelectorAll(".iframe").forEach(item => {
item.remove();
});
ghostElement.append(cloneElement);
ghostElement.setAttribute("style", `position:fixed;opacity:.1;width:${target.parentElement.clientWidth}px;padding:0;`);
document.body.append(ghostElement);
event.dataTransfer.setDragImage(ghostElement, 0, 0);

View file

@ -216,25 +216,3 @@ export const isIncludesHotKey = (hotKey: string) => {
return isInclude;
};
export const updateControlAlt = () => {
if (!window.siyuan.config.keymap.general) {
return;
}
Object.keys(window.siyuan.config.keymap.general).forEach(key => {
if (["fileTree", "outline", "bookmark", "tag", "dailyNote", "inbox", "backlinks",
"graphView", "globalGraph", "riffCard"].includes(key)) {
if (navigator.platform.toUpperCase().indexOf("MAC") > -1) {
window.siyuan.config.keymap.general[key].default = window.siyuan.config.keymap.general[key].default.replace("⌥", "⌃");
if (window.siyuan.config.keymap.general[key].default === window.siyuan.config.keymap.general[key].custom) {
window.siyuan.config.keymap.general[key].custom = window.siyuan.config.keymap.general[key].default.replace("⌥", "⌃");
}
} else {
window.siyuan.config.keymap.general[key].default = window.siyuan.config.keymap.general[key].default.replace("⌃", "⌥");
if (window.siyuan.config.keymap.general[key].default === window.siyuan.config.keymap.general[key].custom) {
window.siyuan.config.keymap.general[key].custom = window.siyuan.config.keymap.general[key].default.replace("⌃", "⌥");
}
}
}
});
};

View file

@ -251,7 +251,12 @@ const setHTML = (options: {
if (protyle.breadcrumb) {
protyle.breadcrumb.element.nextElementSibling.textContent = "";
}
protyle.element.removeAttribute("disabled-forever");
if (protyle.element.hasAttribute("disabled-forever")) {
if (protyle.wysiwyg.element.getAttribute("custom-sy-readonly") !== "true") {
protyle.disabled = false;
}
protyle.element.removeAttribute("disabled-forever");
}
if (options.action.includes(Constants.CB_GET_OPENNEW) && window.siyuan.config.editor.readOnly && !window.siyuan.config.readonly) {
enableProtyle(protyle);
} else {

View file

@ -17,33 +17,7 @@ import {getCalloutInfo, getContenteditableElement} from "../wysiwyg/getBlock";
import {clearBlockElement} from "./clear";
import {removeZWJ} from "./normalizeText";
import {base64ToURL} from "../../util/image";
import {resolveLinkDest, genLinkText} from "../toolbar/util";
const pasteAsLink = (text: string, protyle: IProtyle): boolean => {
if (!window.siyuan.config.editor.pasteURLAutoConvert) {
return false;
}
const trimmed = text.trim();
if (!trimmed || trimmed.includes("\n") || trimmed.includes(" ")) {
// TODO 暂不支持多行文本
return false;
}
const linkDest = resolveLinkDest(trimmed, protyle.lute);
if (!linkDest) {
return false;
}
const linkText = genLinkText(linkDest, false);
const linkNodes = protyle.toolbar.setInlineMark(protyle, "a", "range", {
type: "a",
color: linkDest + Constants.ZWSP + linkText
});
if (linkNodes && linkNodes.length > 0) {
const lastNode = linkNodes[linkNodes.length - 1];
protyle.toolbar.range.setStartAfter(lastNode);
protyle.toolbar.range.collapse(true);
}
return true;
};
import {resolveLinkDest} from "../toolbar/util";
export const getTextStar = (blockElement: HTMLElement, contentOnly = false) => {
const dataType = blockElement.dataset.type;
@ -388,7 +362,7 @@ export const paste = async (protyle: IProtyle, event: (ClipboardEvent | DragEven
}
return;
}
protyle.hint.enableExtend = Constants.BLOCK_HINT_KEYS.concat("{{", "/", "#", "、", "「「", "「『", "『「", "『『",).includes(protyle.hint.splitChar);
protyle.hint.enableExtend = protyle.hint.enableExtend ? Constants.BLOCK_HINT_KEYS.concat("{{", "/", "#", "、", "「「", "「『", "『「", "『『",).includes(protyle.hint.splitChar) : false;
hideElements(protyle.hint.enableExtend ? ["select"] : ["select", "hint"], protyle);
protyle.wysiwyg.element.querySelectorAll(".protyle-wysiwyg--hl").forEach(item => {
item.classList.remove("protyle-wysiwyg--hl");
@ -459,7 +433,9 @@ export const paste = async (protyle: IProtyle, event: (ClipboardEvent | DragEven
tempElement.querySelectorAll('[contenteditable="false"][spellcheck]').forEach((e) => {
e.setAttribute("contenteditable", "true");
});
let tempInnerHTML = tempElement.innerHTML;
if (!nodeElement.classList.contains("av") && tempInnerHTML.startsWith("[[{") && tempInnerHTML.endsWith("}]]")) {
try {
const json = JSON.parse(tempInnerHTML);
@ -476,6 +452,7 @@ export const paste = async (protyle: IProtyle, event: (ClipboardEvent | DragEven
// 复制 HTML 块粘贴出来的不是 HTML 块 https://github.com/siyuan-note/siyuan/issues/12994
tempInnerHTML = Lute.UnEscapeHTMLStr(tempInnerHTML);
}
insertHTML(tempInnerHTML, protyle, isBlock, false, true);
}
blockRender(protyle, protyle.wysiwyg.element);
@ -621,11 +598,14 @@ export const paste = async (protyle: IProtyle, event: (ClipboardEvent | DragEven
}
}
}
let textPlainDom: string;
// Auto-convert pasted URL to link format https://github.com/siyuan-note/siyuan/issues/17337
if (pasteAsLink(textPlain, protyle)) {
return;
if (window.siyuan.config.editor.pasteURLAutoConvert) {
textPlainDom = protyle.lute.Md2BlockDOMWithAutoLink(textPlain);
} else {
textPlainDom = protyle.lute.Md2BlockDOM(textPlain);
}
let textPlainDom = protyle.lute.Md2BlockDOM(textPlain);
if (textPlainDom && textPlainDom.indexOf("data:image/") > -1) {
const tempElement = document.createElement("template");
tempElement.innerHTML = textPlainDom;

View file

@ -7,6 +7,8 @@ import {mindmapRender} from "../render/mindmapRender";
import {flowchartRender} from "../render/flowchartRender";
import {plantumlRender} from "../render/plantumlRender";
import {htmlRender} from "../render/htmlRender";
import {Constants} from "../../constants";
import {escapeHtml} from "../../util/escape";
export const processPasteCode = (html: string, text: string, originalTextHTML: string, protyle: IProtyle) => {
const tempElement = document.createElement("div");
@ -32,13 +34,12 @@ export const processPasteCode = (html: string, text: string, originalTextHTML: s
}
if (isCode) {
let code = text || html;
const code = text || html;
if (/\n/.test(code)) {
return protyle.lute.Md2BlockDOM(code);
} else {
// Paste code from IDE no longer escape `<` and `>` https://github.com/siyuan-note/siyuan/issues/8340
code = code.replace("<", "&lt;").replace(">", "&gt;");
return "`" + code + "`";
// Paste code <&lt;div class="b3-dialog__action"&gt;> WithAll<XXX>() <div class="b3-dialog__action">
return `<span data-type="code" spellcheck="false">${Constants.ZWSP}${escapeHtml(code)}</span>`;
}
}
return false;

View file

@ -541,13 +541,30 @@ export const setInsertWbrHTML = (nodeElement: HTMLElement, range: Range, protyle
if (!editElement) {
return;
}
const offset = getSelectionOffset(editElement, nodeElement, range);
const cloneNode = nodeElement.cloneNode(true) as HTMLElement;
const cloneRange = focusByOffset(cloneNode, offset.end, offset.end, false);
if (cloneRange) {
cloneRange.insertNode(document.createElement("wbr"));
if (nodeElement.classList.contains("table")) {
const cellElement = hasClosestByTag(range.startContainer, "TH") || hasClosestByTag(range.startContainer, "TD");
if (cellElement) {
const offset = getSelectionOffset(cellElement, nodeElement, range);
cellElement.classList.add("range");
const cloneNode = nodeElement.cloneNode(true) as HTMLElement;
cellElement.removeAttribute("class");
const cloneCellElement = cloneNode.querySelector(".range");
const cloneRange = focusByOffset(cloneCellElement, offset.end, offset.end, false);
if (cloneRange) {
cloneRange.insertNode(document.createElement("wbr"));
}
cloneCellElement.removeAttribute("class");
protyle.wysiwyg.lastHTMLs[nodeElement.getAttribute("data-node-id")] = cloneNode.outerHTML;
}
} else {
const offset = getSelectionOffset(editElement, nodeElement, range);
const cloneNode = nodeElement.cloneNode(true) as HTMLElement;
const cloneRange = focusByOffset(cloneNode, offset.end, offset.end, false);
if (cloneRange) {
cloneRange.insertNode(document.createElement("wbr"));
}
protyle.wysiwyg.lastHTMLs[nodeElement.getAttribute("data-node-id")] = cloneNode.outerHTML;
}
protyle.wysiwyg.lastHTMLs[nodeElement.getAttribute("data-node-id")] = cloneNode.outerHTML;
};
export const focusByWbr = (element: Element, range: Range) => {

View file

@ -1515,6 +1515,7 @@ export class WYSIWYG {
selectCellElements[0].colSpan = colSpan;
selectCellElements[0].rowSpan = rowSpan;
focusByWbr(selectCellElements[0], document.createRange());
document.execCommand("insertHTML", false, "");
updateTransaction(protyle, tableBlockElement.getAttribute("data-node-id"), tableBlockElement.outerHTML, oldHTML);
}
});
@ -2517,7 +2518,10 @@ export class WYSIWYG {
input(protyle, blockElement, range, true, event);
}, Constants.TIMEOUT_INPUT);
} else {
input(protyle, blockElement, range, true, event);
clearTimeout(timeout); // https://github.com/siyuan-note/siyuan/issues/9179
timeout = window.setTimeout(() => {
input(protyle, blockElement, range, true, event);
});
}
}
event.stopPropagation();
@ -3053,9 +3057,11 @@ export class WYSIWYG {
if (actionElement.parentElement.classList.contains("protyle-task--done")) {
actionElement.querySelector("use").setAttribute("xlink:href", "#iconUncheck");
actionElement.parentElement.classList.remove("protyle-task--done");
actionElement.parentElement.setAttribute("data-task", " ");
} else {
actionElement.querySelector("use").setAttribute("xlink:href", "#iconCheck");
actionElement.parentElement.classList.add("protyle-task--done");
actionElement.parentElement.setAttribute("data-task", "X");
}
actionElement.parentElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss"));
updateTransaction(protyle, actionId, actionElement.parentElement.outerHTML, html);

View file

@ -241,6 +241,7 @@ export const input = async (protyle: IProtyle, blockElement: HTMLElement, range:
realElement = protyle.wysiwyg.element.querySelector(`[data-node-id="${tempId}"]`);
}
const realType = realElement.getAttribute("data-type");
let itemHTML = "";
if (realType === "NodeCodeBlock") {
const languageElement = realElement.querySelector(".protyle-action__language");
if (languageElement) {
@ -283,6 +284,7 @@ export const input = async (protyle: IProtyle, blockElement: HTMLElement, range:
currentWbrElement.insertAdjacentText("beforebegin", Constants.ZWSP);
}
}
itemHTML = realElement.outerHTML;
focusByWbr(protyle.wysiwyg.element, range);
protyle.hint.render(protyle);
// 表格出现滚动条,输入数字会向前滚 https://github.com/siyuan-note/siyuan/issues/3650
@ -292,7 +294,7 @@ export const input = async (protyle: IProtyle, blockElement: HTMLElement, range:
}
}
// https://github.com/siyuan-note/siyuan/issues/14766
html += realElement.outerHTML;
html += itemHTML || realElement.outerHTML;
});
} else if (blockElement.getAttribute("data-type") === "NodeCodeBlock") {
editElement.parentElement.removeAttribute("data-render");

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