hexo-theme-stellar 1.29.1 → 1.30.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/_config.yml +29 -7
  2. package/_data/chat_users.yml +0 -0
  3. package/_data/icons.yml +3 -1
  4. package/_data/widgets.yml +7 -0
  5. package/layout/_partial/head.ejs +2 -1
  6. package/layout/_partial/main/navbar/nav_tabs_blog.ejs +10 -10
  7. package/layout/_partial/main/post_list/post_card.ejs +15 -11
  8. package/layout/_partial/scripts/defines.ejs +3 -0
  9. package/layout/_partial/scripts/services.ejs +91 -0
  10. package/layout/_partial/scripts/theme.ejs +5 -0
  11. package/layout/_partial/scripts/utils.ejs +67 -7
  12. package/layout/_partial/scripts.ejs +1 -1
  13. package/layout/_plugins/mermaid.ejs +1 -1
  14. package/layout/_plugins/scrollreveal.ejs +1 -0
  15. package/layout/_plugins/search/algolia_search.ejs +11 -12
  16. package/layout/layout.ejs +1 -1
  17. package/package.json +1 -1
  18. package/scripts/events/lib/config.js +3 -0
  19. package/scripts/events/lib/doc_tree.js +1 -6
  20. package/scripts/filters/index.js +26 -0
  21. package/scripts/generators/notebooks.js +1 -1
  22. package/scripts/generators/search.js +21 -2
  23. package/scripts/helpers/dynamic_color.js +138 -0
  24. package/scripts/tags/index.js +1 -0
  25. package/scripts/tags/lib/box.js +1 -1
  26. package/scripts/tags/lib/chat.js +515 -0
  27. package/scripts/tags/lib/folders.js +1 -1
  28. package/scripts/tags/lib/folding.js +2 -2
  29. package/scripts/tags/lib/friends.js +4 -4
  30. package/scripts/tags/lib/sites.js +1 -1
  31. package/scripts/tags/lib/video.js +7 -2
  32. package/source/css/_components/list.styl +41 -12
  33. package/source/css/_components/partial/article-banner.styl +23 -9
  34. package/source/css/_components/tag-plugins/chat.styl +621 -0
  35. package/source/css/_components/tag-plugins/friends.styl +9 -0
  36. package/source/css/_components/tag-plugins/friends_posts.styl +160 -0
  37. package/source/css/_components/tag-plugins/sites.styl +25 -0
  38. package/source/css/_components/tag-plugins/tabs.styl +5 -2
  39. package/source/css/_custom.styl +1 -0
  40. package/source/css/_defines/func.styl +7 -6
  41. package/source/css/_defines/theme.styl +38 -0
  42. package/source/css/_plugins/katex.styl +0 -1
  43. package/source/js/plugins/download-file.js +198 -0
  44. package/source/js/plugins/video.js +65 -0
  45. package/source/js/plugins/voice.js +438 -0
  46. package/source/js/search/algolia-search.js +63 -61
  47. package/source/js/services/artalk_latest_comment.js +33 -0
  48. package/source/js/services/friends.js +4 -0
  49. package/source/js/services/friends_and_posts.js +57 -0
  50. package/source/js/services/giscus_latest_comment.js +36 -0
  51. package/source/js/services/memos.js +91 -69
  52. package/source/js/services/sites.js +12 -1
  53. package/source/js/services/twikoo_latest_comment.js +47 -0
  54. package/source/js/services/waline_latest_comment.js +32 -0
package/_config.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  ######## Stellar info ########
2
2
  stellar:
3
- version: '1.29.1'
3
+ version: '1.30.1'
4
4
  homepage: 'https://xaoxuu.com/wiki/stellar/'
5
5
  repo: 'https://github.com/xaoxuu/hexo-theme-stellar'
6
6
  main_css: /css/main.css
@@ -145,7 +145,7 @@ notebook:
145
145
  auto_excerpt: 128
146
146
  # 可以为某个 tag 设定图标(显示在标签树中)。
147
147
  tagcons:
148
- '': solar:hashtag-linear
148
+ '': solar:hashtag-square-bold
149
149
  # 每页显示多少篇笔记。0 表示不分页,null 则 fallback 到 hexo 的配置。
150
150
  # 可以在笔记本 yaml 的 per_page 字段中覆盖此参数。
151
151
  per_page: null
@@ -173,7 +173,7 @@ article:
173
173
  # 如果没有指定封面,是否根据 tags 作为关键词搜索封面图片?
174
174
  auto_cover: false # search from https://source.unsplash.com/
175
175
  # 封面图宽高比
176
- cover_ratio: 2.4
176
+ cover_ratio: 2
177
177
  # 如果没有指定横幅,是否根据 tags 作为关键词搜索横幅图片?
178
178
  auto_banner: false # search from https://source.unsplash.com/
179
179
  # 如果没有指定 excerpt 和 description,将自动取多长的内容作为文章摘要?
@@ -197,10 +197,12 @@ search:
197
197
  field: all # post, page, all
198
198
  path: /search.json # 搜索文件存放位置
199
199
  content: true # 是否搜索内容
200
+ skip_search: # 指定 path 中的内容不被搜索。
200
201
  algolia_search: # Docsearch https://docsearch.algolia.com/apply/ 申请
201
202
  appId:
202
203
  apiKey:
203
204
  indexName:
205
+ js: https://gcore.jsdelivr.net/algoliasearch/3/algoliasearch.min.js
204
206
 
205
207
 
206
208
  ######## Comments ########
@@ -354,11 +356,11 @@ tag_plugins:
354
356
  interactive: false # enable interactive for user
355
357
  # {% quot %}
356
358
  quot:
357
- default: # 可以自行配置多种图标方案
358
- prefix: https://bu.dusays.com/2022/10/24/63567d3e092ff.png
359
- suffix: https://bu.dusays.com/2022/10/24/63567d3e0ab55.png
359
+ default: # 可以自行配置多种图标方案,支持icons.yml中配置的图片key,也支持直接设置svg/png等文件链接
360
+ prefix: bxs:quote-left
361
+ suffix: bxs:quote-right
360
362
  hashtag:
361
- prefix: https://bu.dusays.com/2022/10/24/63567d3e07da3.png
363
+ prefix: solar:hashtag-square-bold
362
364
  question:
363
365
  prefix: ph:seal-question-fill
364
366
  # {% emoji %}
@@ -416,6 +418,8 @@ tag_plugins:
416
418
  layout: grid # grid / flow
417
419
  size: mix # s / m / l / xl / mix
418
420
  ratio: square # origin / square
421
+ chat:
422
+ api: https://siteinfo.listentothewind.cn/api/v1
419
423
 
420
424
 
421
425
  # 基础依赖
@@ -442,6 +446,8 @@ data_services:
442
446
  js: /js/services/sites.js
443
447
  friends:
444
448
  js: /js/services/friends.js
449
+ friends_and_posts:
450
+ js: /js/services/friends_and_posts.js
445
451
  # 列表布局类
446
452
  timeline:
447
453
  js: /js/services/timeline.js
@@ -451,6 +457,22 @@ data_services:
451
457
  js: /js/services/weibo.js
452
458
  memos:
453
459
  js: /js/services/memos.js
460
+ # chat
461
+ voice:
462
+ js: /js/plugins/voice.js
463
+ video:
464
+ js: /js/plugins/video.js
465
+ download-file:
466
+ js: /js/plugins/download-file.js
467
+ # 最新评论获取类
468
+ twikoo:
469
+ js: /js/services/twikoo_latest_comment.js
470
+ waline:
471
+ js: /js/services/waline_latest_comment.js
472
+ artalk:
473
+ js: /js/services/artalk_latest_comment.js
474
+ giscus:
475
+ js: /js/services/giscus_latest_comment.js
454
476
 
455
477
 
456
478
  # 扩展插件接入方法:(插件名下面用 #plugin# 代替)
File without changes
package/_data/icons.yml CHANGED
@@ -8,7 +8,7 @@ solar:chat-square-like-bold-duotone: <svg xmlns="http://www.w3.org/2000/svg" wid
8
8
  solar:planet-bold-duotone: <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="M20 12a8 8 0 1 1-16 0a8 8 0 0 1 16 0" opacity=".5"/><path fill="currentColor" d="M17.712 5.453c1.047-.193 2.006-.259 2.797-.152c.77.103 1.536.393 1.956 1.064c.446.714.312 1.542-.012 2.258c-.33.728-.918 1.499-1.672 2.268c-1.516 1.547-3.836 3.226-6.597 4.697c-2.763 1.472-5.495 2.484-7.694 2.92c-1.095.217-2.098.299-2.923.201c-.8-.095-1.6-.383-2.032-1.075c-.47-.752-.296-1.63.07-2.379c.375-.768 1.032-1.586 1.872-2.403L4 12.416c0 .219.083.71.168 1.146c.045.23.09.444.123.596c-.652.666-1.098 1.263-1.339 1.756c-.277.567-.208.825-.145.925c.072.116.305.305.937.38c.609.073 1.44.018 2.455-.183c2.02-.4 4.613-1.351 7.28-2.772c2.667-1.42 4.85-3.015 6.23-4.423c.694-.707 1.15-1.334 1.377-1.836c.233-.515.167-.75.107-.844c-.07-.112-.289-.294-.883-.374c-.542-.072-1.272-.041-2.163.112L16.87 5.656c.338-.101.658-.17.842-.203"/></svg>
9
9
  solar:notebook-bookmark-bold-duotone: <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" d="M14.25 4.48v3.057c0 .111 0 .27.02.406a.936.936 0 0 0 .445.683a.96.96 0 0 0 .783.072c.13-.04.272-.108.378-.159L17 8.005l1.124.534c.106.05.248.119.378.16a.958.958 0 0 0 .783-.073a.936.936 0 0 0 .444-.683c.021-.136.021-.295.021-.406V3.031c.113-.005.224-.01.332-.013C21.154 2.98 22 3.86 22 4.933v11.21c0 1.112-.906 2.01-2.015 2.08c-.97.06-2.108.179-2.985.41c-1.082.286-1.99 1.068-3.373 1.436c-.626.167-1.324.257-1.627.323V5.174c.32-.079 1.382-.203 1.674-.371c.184-.107.377-.216.576-.323m5.478 8.338a.75.75 0 0 1-.546.91l-4 1a.75.75 0 0 1-.364-1.456l4-1a.75.75 0 0 1 .91.546" clip-rule="evenodd"/><path fill="currentColor" d="M18.25 3.151c-.62.073-1.23.18-1.75.336a8.2 8.2 0 0 0-.75.27v3.182l.75-.356l.008-.005a1.13 1.13 0 0 1 .492-.13c.047 0 .094.004.138.01c.175.029.315.1.354.12l.009.005l.749.356V3.647z"/><path fill="currentColor" d="M12 5.214c-.334-.064-1.057-.161-1.718-.339C8.938 4.515 8.05 3.765 7 3.487c-.887-.234-2.041-.352-3.018-.412C2.886 3.007 2 3.9 2 4.998v11.146c0 1.11.906 2.01 2.015 2.079c.97.06 2.108.179 2.985.41c.486.129 1.216.431 1.873.726c1.005.451 2.052.797 3.127 1.034z" opacity=".5"/><path fill="currentColor" d="M4.273 12.818a.75.75 0 0 1 .91-.545l4 1a.75.75 0 1 1-.365 1.455l-4-1a.75.75 0 0 1-.545-.91m.909-4.545a.75.75 0 1 0-.364 1.455l4 1a.75.75 0 0 0 .364-1.455z"/></svg>
10
10
  solar:pin-linear: <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path d="m15.9894 4.9502.5306-.53006zm3.0822 3.08542-.5306.53006zm-10.33323 11.39338-.5306.5301zm-4.11668-4.1209.5306-.53zm12.94521-.3138-.2637-.7021zm-1.9171.7203.2638.7021zm-7.3176-7.33283-.70422-.25802zm.69445-1.89541.70422.25802zm-3.18161 4.18714.19934.723zm1.45663-.5384-.43821-.60864zm.37415-.34472.57083.48642zm6.57518 6.59012.491.567zm-.8704 1.8207-.7232-.199zm.5363-1.4546-.6094-.4372zm-11.19844-3.9914-.74998.0048zm.21199-.8031-.64992-.3743zm8.37475 9.391.0012-.75zm.7881-.2084-.3718-.6514zm-.396-19.09864.1615.73239zm-10.2279 19.43384c-.29274.2931-.2925.768.00054 1.0607s.76792.2925 1.06066-.0005zm5.71443-3.5978c.29274-.293.2925-.7679-.00054-1.0607-.29305-.2927-.76792-.2925-1.06066.0006zm8.27497-12.39184 3.0822 3.08542 1.0612-1.06012-3.0822-3.08542zm-6.18983 13.41864-4.11668-4.1208-1.0612 1.0601 4.11668 4.1209zm8.03423-4.6067-1.9172.7203.5276 1.4042 1.9171-.7203zm-8.26678-5.65241.69445-1.89541-1.40844-.51604-.69445 1.89541zm-2.99204 2.75671c.71145-.1962 1.25281-.334 1.69549-.6527l-.87641-1.21734c-.17293.12451-.39745.19782-1.21776.42398zm1.5836-3.27275c-.29296.79957-.3846 1.01778-.52299 1.18016l1.14166.97289c.35376-.41505.53565-.94343.78977-1.63701zm.11189 2.62005c.18709-.1347.35725-.2915.50678-.467l-1.14166-.97289c-.07129.08366-.15239.15838-.24153.22255zm7.64613 4.2687c-.689.2589-1.2144.4446-1.626.801l.982 1.134c.1608-.1393.3772-.2323 1.1716-.5308zm-1.2823 3.3876c.2253-.8188.2984-1.0432.4226-1.2163l-1.2188-.8744c-.3173.4423-.4546.9825-.6501 1.6928zm-.3437-2.5866c-.1697.147-.3216.3134-.4525.4959l1.2188.8744c.0624-.087.1348-.1663.2157-.2363zm-8.60771-1.0354c-.64614-.6468-1.0843-1.0871-1.36863-1.4443-.28531-.3585-.31477-.5137-.31521-.5833l-1.49997.0095c.00367.5822.29279 1.0697.64154 1.5079.34974.4394.86113.9497 1.48107 1.5703zm.49341-4.82766c-.84522.23306-1.54174.42386-2.06274.63306-.51955.2085-1.0118.4897-1.30243.9943l1.29985.7486c.03462-.0601.13655-.1804.56142-.3509.42343-.17 1.02157-.3361 1.90258-.579zm-2.17725 2.80006c-.00094-.1489.03771-.2952.11193-.4241l-1.29985-.7486c-.20699.3594-.31467.7674-.31205 1.1822zm4.73932 7.2086c.62387.6245 1.13687 1.1396 1.5787 1.4915.44053.3509.93143.6416 1.51763.6425l.0023-1.5c-.0695-.0001-.225-.0287-.5854-.3158-.3592-.2861-.80177-.7274-1.45203-1.3784zm4.44963-1.9569c-.2441.8875-.4112 1.4902-.5823 1.9166-.1718.4279-.293.5299-.3536.5645l.7435 1.3028c.509-.2905.7923-.7857 1.0021-1.3086.2105-.5243.4023-1.2259.6366-2.0774zm-1.3533 4.0909c.4071.0006.8073-.1052 1.1609-.307l-.7435-1.3028c-.1265.0722-.2696.11-.4151.1098zm7.2369-13.52742c1.0635 1.06454 1.7993 1.80382 2.2507 2.41312.4436.5986.4946.9171.4404 1.1676l1.4661.317c.1899-.878-.16-1.6472-.7013-2.3777-.5334-.71978-1.3664-1.55084-2.3947-2.58014zm-.7103 7.13072c1.3614-.5115 2.4633-.9234 3.2464-1.358.7947-.4411 1.4312-.9968 1.6211-1.875l-1.4661-.317c-.0541.2504-.232.5191-.883.8804-.6626.3678-1.6379.7364-3.0459 1.2654zm-1.3107-11.27626c-1.0359-1.03694-1.8719-1.87661-2.5954-2.41376-.7338-.54473-1.5071-.89726-2.3889-.70271l.3231 1.46478c.2498-.0551.5689-.00515 1.1716.4423.6129.45504 1.3572 1.19726 2.4284 2.26951zm-6.78913 2.32424c.52163-1.42363.88523-2.41035 1.25033-3.08123.359-.65977.6278-.83958.8776-.8947l-.3231-1.46478c-.8817.19452-1.4352.83965-1.87208 1.64251-.43084.79175-.83674 1.90536-1.34119 3.28216zm-7.20027 15.78572 4.65323-4.658-1.0612-1.0601-4.65323 4.6579z" fill="currentColor"/></svg>
11
- solar:hashtag-linear: <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><g stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"><path d="m10 3-5 18"/><path d="m19 3-5 18"/><path d="m22 9h-18"/><path d="m20 16h-18"/></g></svg>
11
+ solar:hashtag-square-bold: <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><!-- Icon from Solar by 480 Design - https://creativecommons.org/licenses/by/4.0/ --><path fill="currentColor" d="m14.092 10.75l-.75 2.5H9.908l.75-2.5z"/><path fill="currentColor" fill-rule="evenodd" d="M3.464 3.464C2 4.93 2 7.286 2 12s0 7.071 1.464 8.535C4.93 22 7.286 22 12 22s7.071 0 8.535-1.465C22 19.072 22 16.714 22 12s0-7.071-1.465-8.536C19.072 2 16.714 2 12 2S4.929 2 3.464 3.464m7.752 2.818a.75.75 0 0 1 .502.934l-.61 2.034h3.434l.74-2.465a.75.75 0 0 1 1.436.43l-.61 2.035H18a.75.75 0 0 1 0 1.5h-2.342l-.75 2.5H17a.75.75 0 0 1 0 1.5h-2.542l-.74 2.465a.75.75 0 0 1-1.436-.43l.61-2.035H9.458l-.74 2.465a.75.75 0 1 1-1.436-.43l.61-2.035H6a.75.75 0 0 1 0-1.5h2.342l.75-2.5H7a.75.75 0 0 1 0-1.5h2.542l.74-2.465a.75.75 0 0 1 .934-.503" clip-rule="evenodd"/></svg>
12
12
 
13
13
  default:goback: <svg aria-hidden="true" viewBox="0 0 16 16" fill="currentColor"><path fill-rule="evenodd" d="M7.78 12.53a.75.75 0 01-1.06 0L2.47 8.28a.75.75 0 010-1.06l4.25-4.25a.75.75 0 011.06 1.06L4.81 7h7.44a.75.75 0 010 1.5H4.81l2.97 2.97a.75.75 0 010 1.06z"></path></svg>
14
14
 
@@ -48,3 +48,5 @@ share:link: https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.12/social/8411ed
48
48
 
49
49
  # quot icons
50
50
  ph:seal-question-fill: <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 256 256"><path fill="currentColor" d="M225.86 102.82c-3.77-3.94-7.67-8-9.14-11.57c-1.36-3.27-1.44-8.69-1.52-13.94c-.15-9.76-.31-20.82-8-28.51s-18.75-7.85-28.51-8c-5.25-.08-10.67-.16-13.94-1.52c-3.56-1.47-7.63-5.37-11.57-9.14C146.28 23.51 138.44 16 128 16s-18.27 7.51-25.18 14.14c-3.94 3.77-8 7.67-11.57 9.14c-3.25 1.36-8.69 1.44-13.94 1.52c-9.76.15-20.82.31-28.51 8s-7.8 18.75-8 28.51c-.08 5.25-.16 10.67-1.52 13.94c-1.47 3.56-5.37 7.63-9.14 11.57C23.51 109.72 16 117.56 16 128s7.51 18.27 14.14 25.18c3.77 3.94 7.67 8 9.14 11.57c1.36 3.27 1.44 8.69 1.52 13.94c.15 9.76.31 20.82 8 28.51s18.75 7.85 28.51 8c5.25.08 10.67.16 13.94 1.52c3.56 1.47 7.63 5.37 11.57 9.14c6.9 6.63 14.74 14.14 25.18 14.14s18.27-7.51 25.18-14.14c3.94-3.77 8-7.67 11.57-9.14c3.27-1.36 8.69-1.44 13.94-1.52c9.76-.15 20.82-.31 28.51-8s7.85-18.75 8-28.51c.08-5.25.16-10.67 1.52-13.94c1.47-3.56 5.37-7.63 9.14-11.57c6.63-6.9 14.14-14.74 14.14-25.18s-7.51-18.27-14.14-25.18M128 192a12 12 0 1 1 12-12a12 12 0 0 1-12 12m8-48.72v.72a8 8 0 0 1-16 0v-8a8 8 0 0 1 8-8c13.23 0 24-9 24-20s-10.77-20-24-20s-24 9-24 20v4a8 8 0 0 1-16 0v-4c0-19.85 17.94-36 40-36s40 16.15 40 36c0 17.38-13.76 31.93-32 35.28"/></svg>
51
+ bxs:quote-left: <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><!-- Icon from BoxIcons Solid by Atisa - https://creativecommons.org/licenses/by/4.0/ --><path fill="currentColor" d="M3.691 6.292C5.094 4.771 7.217 4 10 4h1v2.819l-.804.161c-1.37.274-2.323.813-2.833 1.604A2.9 2.9 0 0 0 6.925 10H10a1 1 0 0 1 1 1v7c0 1.103-.897 2-2 2H3a1 1 0 0 1-1-1v-5l.003-2.919c-.009-.111-.199-2.741 1.688-4.789M20 20h-6a1 1 0 0 1-1-1v-5l.003-2.919c-.009-.111-.199-2.741 1.688-4.789C16.094 4.771 18.217 4 21 4h1v2.819l-.804.161c-1.37.274-2.323.813-2.833 1.604A2.9 2.9 0 0 0 17.925 10H21a1 1 0 0 1 1 1v7c0 1.103-.897 2-2 2"/></svg>
52
+ bxs:quote-right: <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><!-- Icon from BoxIcons Solid by Atisa - https://creativecommons.org/licenses/by/4.0/ --><path fill="currentColor" d="M20.309 17.708C22.196 15.66 22.006 13.03 22 13V5a1 1 0 0 0-1-1h-6c-1.103 0-2 .897-2 2v7a1 1 0 0 0 1 1h3.078a2.9 2.9 0 0 1-.429 1.396c-.508.801-1.465 1.348-2.846 1.624l-.803.16V20h1c2.783 0 4.906-.771 6.309-2.292m-11.007 0C11.19 15.66 10.999 13.03 10.993 13V5a1 1 0 0 0-1-1h-6c-1.103 0-2 .897-2 2v7a1 1 0 0 0 1 1h3.078a2.9 2.9 0 0 1-.429 1.396c-.508.801-1.465 1.348-2.846 1.624l-.803.16V20h1c2.783 0 4.906-.771 6.309-2.292"/></svg>
package/_data/widgets.yml CHANGED
@@ -71,6 +71,13 @@ timeline:
71
71
  type: # 默认不用写,如果是友链朋友圈数据请写 fcircle
72
72
  limit: # 默认通过 api 上增加 per_page 来设置,如果是友链朋友圈,可通过这个设置数量
73
73
 
74
+ latest_comment:
75
+ layout: timeline
76
+ title: 最新评论
77
+ api: # 参照文档获取服务对应的api
78
+ type: # 选择评论服务
79
+ limit: 16 # 限制获取数量
80
+
74
81
  tagtree:
75
82
  layout: tagtree
76
83
  expand_all: false # 是否展开所有节点
@@ -119,7 +119,8 @@ function custom_inject() {
119
119
  <%- feed_tag(config.feed.path, {title: config.title}) %>
120
120
  <% } %>
121
121
 
122
- <link rel="stylesheet" href="<%- `${theme.stellar.main_css}?v=${stellar_info('version')}` %>">
122
+ <link rel="stylesheet" href="<%- url_for(`${theme.stellar.main_css}?v=${stellar_info('version')}`) %>">
123
+
123
124
 
124
125
  <% if (config.favicon) { %>
125
126
  <%- favicon_tag(config.favicon) %>
@@ -11,37 +11,37 @@ function layoutDiv() {
11
11
 
12
12
  if (site.categories && site.categories.length > 0) {
13
13
  if (page.category) {
14
- el += '<a class="active" href="' + url_for(config.category_dir) + '">' + __("btn.category") + __("symbol.colon") + page.category + '</a>';
14
+ el += '<a class="active" href="' + url_for(config.category_dir) + '/">' + __("btn.category") + __("symbol.colon") + page.category + '</a>';
15
15
  } else if (page.layout == "categories") {
16
- el += '<a class="active" href="' + url_for(config.category_dir) + '">' + __("btn.categories") + '</a>';
16
+ el += '<a class="active" href="' + url_for(config.category_dir) + '/">' + __("btn.categories") + '</a>';
17
17
  } else {
18
- el += '<a href="' + url_for(config.category_dir) + '">' + __("btn.categories") + '</a>';
18
+ el += '<a href="' + url_for(config.category_dir) + '/">' + __("btn.categories") + '</a>';
19
19
  }
20
20
  }
21
21
 
22
22
  if (site.tags && site.tags.length > 0) {
23
23
  if (page.tag) {
24
- el += '<a class="active" href="' + url_for(config.tag_dir) + '">' + __("btn.tag") + __("symbol.colon") + page.tag + '</a>';
24
+ el += '<a class="active" href="' + url_for(config.tag_dir) + '/">' + __("btn.tag") + __("symbol.colon") + page.tag + '</a>';
25
25
  } else if (page.layout == "tags") {
26
- el += '<a class="active" href="' + url_for(config.tag_dir) + '">' + __("btn.tags") + '</a>';
26
+ el += '<a class="active" href="' + url_for(config.tag_dir) + '/">' + __("btn.tags") + '</a>';
27
27
  } else {
28
- el += '<a href="' + url_for(config.tag_dir) + '">' + __("btn.tags") + '</a>';
28
+ el += '<a href="' + url_for(config.tag_dir) + '/">' + __("btn.tags") + '</a>';
29
29
  }
30
30
  }
31
31
 
32
32
  if (theme.topic?.publish_list?.length > 0) {
33
33
  if (page.layout == 'index_topic') {
34
- el += '<a class="active" href="' + url_for(theme.site_tree.index_topic.base_dir) + '">' + __("btn.topic") + '</a>';
34
+ el += '<a class="active" href="' + url_for(theme.site_tree.index_topic.base_dir) + '/">' + __("btn.topic") + '</a>';
35
35
  } else {
36
- el += '<a href="' + url_for(theme.site_tree.index_topic.base_dir) + '">' + __("btn.topic") + '</a>';
36
+ el += '<a href="' + url_for(theme.site_tree.index_topic.base_dir) + '/">' + __("btn.topic") + '</a>';
37
37
  }
38
38
  }
39
39
 
40
40
  if (site.posts && site.posts.length > 0) {
41
41
  if (is_archive()) {
42
- el += '<a class="active" href="' + url_for(config.archive_dir) + '">' + __("btn.archives") + '</a>';
42
+ el += '<a class="active" href="' + url_for(config.archive_dir) + '/">' + __("btn.archives") + '</a>';
43
43
  } else {
44
- el += '<a href="' + url_for(config.archive_dir) + '">' + __("btn.archives") + '</a>';
44
+ el += '<a href="' + url_for(config.archive_dir) + '/">' + __("btn.archives") + '</a>';
45
45
  }
46
46
  }
47
47
 
@@ -100,26 +100,30 @@ function div_default() {
100
100
  }
101
101
  function div_photo() {
102
102
  var el = '';
103
- el += '<div class="cover">';
104
- el += '<img src="' + obj.image + '"/>';
103
+ var position = '';
105
104
  if (obj.headline || obj.topic || obj.caption) {
106
- el += '<div class="cover-info"';
107
- if (obj.color) {
108
- el += 'style="color:' + obj.color + '"';
109
- }
110
105
  if (obj.topic) {
111
- el += 'position="top">';
106
+ position = 'top';
112
107
  } else {
113
- el += 'position="bottom">';
108
+ position = 'bottom';
109
+ }
110
+ }
111
+ el += '<div class="cover" position="' + position + '">';
112
+ el += '<img src="' + obj.image + '"/>';
113
+ if (position.length > 0) {
114
+ el += '<div class="cover-info" position="' + position + '"';
115
+ if (obj.color) {
116
+ el += 'style="color:' + obj.color + '"';
114
117
  }
118
+ el += '>';
115
119
  if (obj.topic) {
116
- el += '<div class="cap">' + obj.topic + '</div>';
120
+ el += '<div class="text topic">' + obj.topic + '</div>';
117
121
  }
118
122
  if (obj.headline) {
119
- el += '<div class="title">' + obj.headline + '</div>';
123
+ el += '<div class="text headline">' + obj.headline + '</div>';
120
124
  }
121
125
  if (obj.caption) {
122
- el += '<div class="cap">' + obj.caption + '</div>';
126
+ el += '<div class="text caption">' + obj.caption + '</div>';
123
127
  }
124
128
  el += '</div>';
125
129
 
@@ -7,6 +7,9 @@
7
7
  day: `<%- __('meta.date_suffix.day') %>`,
8
8
  },
9
9
  root : `<%- config.root %>`,
10
+ tag_plugins: {
11
+ chat: Object.assign(<%- JSON.stringify(theme.tag_plugins.chat) %>),
12
+ }
10
13
  };
11
14
 
12
15
  // required plugins (only load if needs)
@@ -10,6 +10,27 @@
10
10
  setCardLink(ctx.cardlinks);
11
11
  });
12
12
  }
13
+ } else if (id == 'voice') {
14
+ ctx.voiceAudios = document.querySelectorAll('.voice>audio');
15
+ if (ctx.voiceAudios?.length > 0) {
16
+ utils.js(js, { defer: true }).then(function () {
17
+ createVoiceDom(ctx.voiceAudios);
18
+ });
19
+ }
20
+ } else if (id == 'video') {
21
+ ctx.videos = document.querySelectorAll('.video>video');
22
+ if (ctx.videos?.length > 0) {
23
+ utils.js(js, { defer: true }).then(function () {
24
+ videoEvents(ctx.videos);
25
+ });
26
+ }
27
+ } else if (id == 'download-file') {
28
+ ctx.files = document.querySelectorAll('.file');
29
+ if (ctx.files?.length > 0) {
30
+ utils.js(js, { defer: true }).then(function () {
31
+ downloadFileEvent(ctx.files);
32
+ });
33
+ }
13
34
  } else {
14
35
  const els = document.getElementsByClassName(`ds-${id}`);
15
36
  if (els?.length > 0) {
@@ -25,5 +46,75 @@
25
46
  }
26
47
  }
27
48
  }
49
+
50
+ // chat iphone time
51
+ let phoneTimes = document.querySelectorAll('.chat .status-bar .time');
52
+
53
+ if (phoneTimes.length > 0) {
54
+ NowTime();
55
+ var date = new Date();
56
+ var sec = date.getSeconds();
57
+ var firstAdjustInterval = setInterval(firstAdjustTime, 1000 * (60 - sec));
58
+ }
59
+
60
+ function firstAdjustTime() {
61
+ NowTime();
62
+ clearInterval(firstAdjustInterval);
63
+ setInterval(NowTime, 1000 * 60);
64
+ }
65
+
66
+ function NowTime() {
67
+ for (let i = 0; i < phoneTimes.length; ++i) {
68
+ var timeSpan = phoneTimes[i];
69
+ var date = new Date();
70
+ var hour = date.getHours();
71
+ var min = date.getMinutes();
72
+ timeSpan.innerHTML = check(hour) + ":" + check(min);
73
+ }
74
+ };
75
+
76
+ function check(val) {
77
+ if (val < 10) {
78
+ return ("0" + val);
79
+ }
80
+ return (val);
81
+ }
82
+
83
+ // chat quote
84
+ const chat_quote_obverser = new IntersectionObserver((entries, observer) => {
85
+ entries.filter((entry) => { return entry.isIntersecting }).sort((a, b) => a.intersectionRect.y !== b.intersectionRect.y ? a.intersectionRect.y - b.intersectionRect.y : a.intersectionRect.x - b.intersectionRect.x).forEach((entry, index) => {
86
+ observer.unobserve(entry.target);
87
+ setTimeout(() => {
88
+ entry.target.classList.add('quote-blink');
89
+ setTimeout(() => {
90
+ entry.target.classList.remove('quote-blink');
91
+ }, 1000);
92
+ }, Math.max(100, 16) * (index + 1));
93
+ });
94
+ });
95
+
96
+ var chatQuotes = document.querySelectorAll(".chat .talk .quote");
97
+ chatQuotes.forEach((quote) => {
98
+ quote.addEventListener('click', function () {
99
+ var chatCellDom = document.getElementById("quote-" + quote.getAttribute("quotedCellTag"));
100
+ if (chatCellDom) {
101
+ var chatDiv = chatCellDom.parentElement;
102
+ var mid = chatDiv.clientHeight / 2;
103
+ var offsetTop = chatCellDom.offsetTop;
104
+ if (offsetTop > mid - chatCellDom.clientHeight / 2) {
105
+ chatDiv.scrollTo({
106
+ top: chatCellDom.offsetTop - mid + chatCellDom.clientHeight / 2,
107
+ behavior: "smooth"
108
+ });
109
+ } else {
110
+ chatDiv.scrollTo({
111
+ top: 0,
112
+ behavior: "smooth"
113
+ });
114
+ }
115
+ chat_quote_obverser.observe(chatCellDom);
116
+ }
117
+ });
118
+ });
28
119
  });
29
120
  </script>
@@ -43,6 +43,8 @@
43
43
  }
44
44
  applyTheme(newTheme)
45
45
  window.localStorage.setItem('Stellar.theme', newTheme)
46
+ utils.dark.mode = newTheme === 'auto' ? (window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light") : newTheme;
47
+ utils.dark.method.toggle.start();
46
48
 
47
49
  const messages = {
48
50
  light: `<%- __('message.theme_switched.light') %>`,
@@ -57,6 +59,9 @@
57
59
  const theme = window.localStorage.getItem('Stellar.theme')
58
60
  if (theme !== null) {
59
61
  applyTheme(theme)
62
+ } else {
63
+ utils.dark.mode = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
60
64
  }
65
+ utils.dark.method.toggle.start();
61
66
  })()
62
67
  </script>
@@ -1,4 +1,44 @@
1
1
  <script type="text/javascript">
2
+ function RunItem() {
3
+ this.list = []; // 存放回调函数
4
+ this.start = () => {
5
+ for (var i = 0; i < this.list.length; i++) {
6
+ this.list[i].run();
7
+ }
8
+ };
9
+ this.push = (fn, name, setRequestAnimationFrame = true) => {
10
+ let myfn = fn
11
+ if (setRequestAnimationFrame) {
12
+ myfn = () => {
13
+ utils.requestAnimationFrame(fn)
14
+ }
15
+ }
16
+ var f = new Item(myfn, name);
17
+ this.list.push(f);
18
+ };
19
+ this.remove = (name) => {
20
+ for (let index = 0; index < this.list.length; index++) {
21
+ const e = this.list[index];
22
+ if (e.name == name) {
23
+ this.list.splice(index, 1);
24
+ }
25
+ }
26
+ }
27
+ // 构造一个可以run的对象
28
+ function Item(fn, name) {
29
+ // 函数名称
30
+ this.name = name || fn.name;
31
+ // run方法
32
+ this.run = () => {
33
+ try {
34
+ fn()
35
+ } catch (error) {
36
+ console.log(error);
37
+ }
38
+ };
39
+ }
40
+ }
41
+
2
42
  const utils = {
3
43
  // 懒加载 css https://github.com/filamentgroup/loadCSS
4
44
  css: (href, before, media, attributes) => {
@@ -61,7 +101,7 @@
61
101
 
62
102
  js: (src, opt) => new Promise((resolve, reject) => {
63
103
  var script = document.createElement('script');
64
- if (src.startsWith('/')){
104
+ if (src.startsWith('/')) {
65
105
  src = ctx.root + src.substring(1);
66
106
  }
67
107
  script.src = src;
@@ -74,7 +114,7 @@
74
114
  script.async = true
75
115
  }
76
116
  script.onerror = reject
77
- script.onload = script.onreadystatechange = function() {
117
+ script.onload = script.onreadystatechange = function () {
78
118
  const loadState = this.readyState
79
119
  if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
80
120
  script.onload = script.onreadystatechange = null
@@ -90,7 +130,7 @@
90
130
  fn()
91
131
  }
92
132
  },
93
-
133
+
94
134
  onLoading: (el) => {
95
135
  if (el) {
96
136
  $(el).append('<div class="loading-wrap"><svg xmlns="http://www.w3.org/2000/svg" width="2em" height="2em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-width="2"><path stroke-dasharray="60" stroke-dashoffset="60" stroke-opacity=".3" d="M12 3C16.9706 3 21 7.02944 21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3Z"><animate fill="freeze" attributeName="stroke-dashoffset" dur="1.3s" values="60;0"/></path><path stroke-dasharray="15" stroke-dashoffset="15" d="M12 3C16.9706 3 21 7.02944 21 12"><animate fill="freeze" attributeName="stroke-dashoffset" dur="0.3s" values="15;0"/><animateTransform attributeName="transform" dur="1.5s" repeatCount="indefinite" type="rotate" values="0 12 12;360 12 12"/></path></g></svg></div>');
@@ -124,7 +164,7 @@
124
164
  }
125
165
  }
126
166
  }, 5000);
127
- fetch(url).then(function(response) {
167
+ fetch(url).then(function (response) {
128
168
  if (status !== 2) {
129
169
  clearTimeout(timer);
130
170
  resolve(response);
@@ -135,11 +175,11 @@
135
175
  return response.json();
136
176
  }
137
177
  throw new Error('Network response was not ok.');
138
- }).then(function(data) {
178
+ }).then(function (data) {
139
179
  retryTimes = 0;
140
180
  utils.onLoadSuccess(el);
141
181
  callback(data);
142
- }).catch(function(error) {
182
+ }).catch(function (error) {
143
183
  if (retryTimes > 0) {
144
184
  retryTimes -= 1;
145
185
  setTimeout(() => {
@@ -154,5 +194,25 @@
154
194
  }
155
195
  req();
156
196
  },
197
+ /********************** requestAnimationFrame ********************************/
198
+ // 1、requestAnimationFrame 会把每一帧中的所有 DOM 操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率,一般来说,这个频率为每秒60帧。
199
+ // 2、在隐藏或不可见的元素中,requestAnimationFrame 将不会进行重绘或回流,这当然就意味着更少的的 cpu,gpu 和内存使用量。
200
+ requestAnimationFrame: (fn) => {
201
+ if (!window.requestAnimationFrame) {
202
+ window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame;
203
+ }
204
+ window.requestAnimationFrame(fn)
205
+ },
206
+ dark: {},
207
+ };
208
+
209
+ // utils.dark.mode 当前模式 dark or light
210
+ // utils.dark.toggle() 暗黑模式触发器
211
+ // utils.dark.push(callBack[,"callBackName"]) 传入触发器回调函数
212
+ utils.dark.method = {
213
+ toggle: new RunItem(),
157
214
  };
158
- </script>
215
+ utils.dark = Object.assign(utils.dark, {
216
+ push: utils.dark.method.toggle.push,
217
+ });
218
+ </script>
@@ -21,7 +21,7 @@ function custom_inject() {
21
21
  <%- partial('scripts/tagtree') %>
22
22
 
23
23
  <!-- required -->
24
- <script src="<%- `${theme.stellar.main_js}?v=${stellar_info('version')}` %>" defer></script>
24
+ <script src="<%- url_for(`${theme.stellar.main_js}?v=${stellar_info('version')}`) %>" defer></script>
25
25
 
26
26
  <%- partial('scripts/theme') %>
27
27
 
@@ -4,7 +4,7 @@
4
4
  var mermaid_config = {
5
5
  startOnLoad: true,
6
6
  theme:
7
- "<%- theme.style.darkmode %>" == "auto" &&
7
+ "<%- theme.style.prefers_theme %>" == "auto" &&
8
8
  window.matchMedia("(prefers-color-scheme: dark)").matches
9
9
  ? "dark"
10
10
  : "<%- conf.theme %>",
@@ -11,5 +11,6 @@
11
11
  };
12
12
  ScrollReveal().reveal('.l_left .slide-up', slideUp);
13
13
  ScrollReveal().reveal('.l_main .slide-up', slideUp);
14
+ ScrollReveal().reveal('.l_right .slide-up', slideUp);
14
15
  });
15
16
  </script>
@@ -1,13 +1,12 @@
1
1
  <script>
2
- window.addEventListener('DOMContentLoaded', (event) => {
3
- window.searchConfig = {
4
- appId: '<%- conf.appId %>',
5
- apiKey: '<%- conf.apiKey %>',
6
- indexName: '<%- conf.indexName %>',
7
- hitsPerPage: 100,
8
- };
9
- utils.js('https://gcore.jsdelivr.net/algoliasearch/3/algoliasearch.min.js', { defer: true });
10
- utils.js('/js/search/algolia-search.js', { defer: true });
11
- });
12
- </script>
13
-
2
+ window.addEventListener('DOMContentLoaded', (event) => {
3
+ window.searchConfig = {
4
+ appId: '<%- conf.appId %>',
5
+ apiKey: '<%- conf.apiKey %>',
6
+ indexName: '<%- conf.indexName %>',
7
+ js: '<%- conf.js %>',
8
+ hitsPerPage: 100,
9
+ };
10
+ utils.js('/js/search/algolia-search.js', { defer: true });
11
+ });
12
+ </script>
package/layout/layout.ejs CHANGED
@@ -46,7 +46,7 @@ if (theme.style.prefers_theme === 'auto') {
46
46
  html += `<body>`
47
47
  html += site_background
48
48
  html += partial('_partial/cover/index')
49
- html += `<div class="l_body s:aa ${page_type} ${article_type}" id="start" layout="${page.layout}" ${indent ? 'text-indent' : ''}>`
49
+ html += `<div class="l_body ${page_type} ${article_type}" id="start" layout="${page.layout}" ${indent ? 'text-indent' : ''}>`
50
50
  html += `<aside class="l_left">`
51
51
  html += `<div class="leftbar-container${theme.style.leftbar?.blur ? ' leftbar-blur' : ''}">`
52
52
  html += partial('_partial/sidebar/index_leftbar')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hexo-theme-stellar",
3
- "version": "1.29.1",
3
+ "version": "1.30.1",
4
4
  "description": "Elegant and powerful theme for Hexo.",
5
5
  "main": "package.json",
6
6
  "scripts": {
@@ -64,4 +64,7 @@ module.exports = ctx => {
64
64
  ctx.theme.config.menubar = {}
65
65
  }
66
66
 
67
+ // chat users
68
+ ctx.theme.config.chat_users = data.chat_users;
69
+
67
70
  }
@@ -63,7 +63,7 @@ module.exports = ctx => {
63
63
  const pages = ctx.locals.get('pages')
64
64
  // wiki 所有页面
65
65
  const wiki_pages = pages.filter(p => (p.wiki != null)).map(p => new WikiPage(p))
66
- const wiki_list = Object.keys(wiki.tree)
66
+ const wiki_list = Object.keys(wiki.tree).filter(id => wiki_pages.some(p => p.wiki === id))
67
67
  // 上架的项目列表
68
68
  wiki.shelf = ctx.locals.get('data').wiki || []
69
69
 
@@ -99,11 +99,6 @@ module.exports = ctx => {
99
99
  let id = wiki_list[i];
100
100
  let item = wiki.tree[id]
101
101
  let sub_pages = wiki_pages.filter(p => p.wiki === id)
102
- if (!sub_pages || sub_pages.length == 0) {
103
- wiki_list.splice(i, 1)
104
- delete wiki.tree[id]
105
- continue
106
- }
107
102
 
108
103
  // 首页
109
104
  // 未特别指定首页时,获取TOC第一页作为首页
@@ -2,3 +2,29 @@
2
2
 
3
3
  hexo.extend.filter.register('after_render:html', require('./lib/img_lazyload').processSite);
4
4
  hexo.extend.filter.register('after_render:html', require('./lib/img_onerror').processSite);
5
+
6
+ function change_image(data) {
7
+ if (this.theme.config.tag_plugins.image.parse_markdown) {
8
+ // data.content = data.content.replace(
9
+ // /!\[(.*?)\]\((.*?)\s*(?:"(.*?)")?\)/g,
10
+ // '{% image $2 $3 %}'
11
+ // );
12
+ let splited_content = data.content.split(/(```[\s\S]*?```|{%\s*gallery\s*%}[\s\S]*?{%\s*endgallery\s*%})/g);
13
+ splited_content = splited_content.map((s) => {
14
+ let matches_no = s.match(/(```[\s\S]*?```|{%\s*gallery\s*%}[\s\S]*?{%\s*endgallery\s*%})/i);
15
+ let matches_img = s.match(/!\[(.*?)\]\((.*?)\s*(?:"(.*?)")?\)/i);
16
+ if (!matches_no && matches_img) {
17
+ s = s.replace(
18
+ /!\[(.*?)\]\((.*?)\s*(?:"(.*?)")?\)/g,
19
+ `{% image $2 $3 %}`
20
+ );
21
+ }
22
+ return s;
23
+ });
24
+ data.content = splited_content.join('');
25
+ }
26
+ return data;
27
+ }
28
+
29
+ hexo.extend.filter.register('before_post_render', change_image, 9);
30
+
@@ -30,7 +30,7 @@ function paginationWithEmpty(base, posts, options={}) {
30
30
 
31
31
  hexo.extend.generator.register('notebooks', function (locals) {
32
32
  const { site_tree, notebooks } = hexo.theme.config
33
- if (notebooks.tree.length === 0) {
33
+ if (!notebooks?.tree || Object.keys(notebooks.tree).length === 0) {
34
34
  return []
35
35
  }
36
36