hexo-theme-stellar 2.0.0-rc.2 → 2.0.0-rc.3

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 (220) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/_config.yml +108 -10
  3. package/_data/icons.yml +1 -0
  4. package/languages/en.yml +1 -0
  5. package/languages/zh-CN.yml +1 -0
  6. package/languages/zh-TW.yml +1 -0
  7. package/layout/_partial/comments/beaudar/layout.ejs +1 -1
  8. package/layout/_partial/comments/giscus/layout.ejs +1 -1
  9. package/layout/_partial/comments/utterances/layout.ejs +1 -1
  10. package/layout/_partial/cover/wiki_cover.ejs +2 -1
  11. package/layout/_partial/head.ejs +16 -10
  12. package/layout/_partial/main/article/post_footer.ejs +1 -1
  13. package/layout/_partial/main/article/post_read_next.ejs +4 -1
  14. package/layout/_partial/main/footer.ejs +8 -8
  15. package/layout/_partial/main/navbar/article_banner.ejs +3 -1
  16. package/layout/_partial/main/pin_slider.ejs +33 -20
  17. package/layout/_partial/menubtn.ejs +1 -1
  18. package/layout/_partial/primitives/region.ejs +3 -3
  19. package/layout/_partial/primitives/shell.ejs +1 -1
  20. package/layout/_partial/scripts/defines.ejs +20 -119
  21. package/layout/_partial/scripts/runtime.ejs +6 -4
  22. package/layout/_partial/scripts.ejs +7 -27
  23. package/layout/_partial/search/dialog.ejs +1 -1
  24. package/layout/_partial/sidebar/brand.ejs +1 -1
  25. package/layout/_partial/widgets/related.ejs +1 -1
  26. package/layout/_partial/widgets/tagtree.ejs +1 -1
  27. package/layout/archive.ejs +14 -23
  28. package/layout/index.ejs +4 -0
  29. package/layout/layout.ejs +2 -2
  30. package/layout/page.ejs +1 -1
  31. package/package.json +4 -3
  32. package/scripts/commands/stellar.js +15 -3
  33. package/scripts/events/index.js +10 -23
  34. package/scripts/events/lib/authors.js +1 -0
  35. package/scripts/events/lib/doc_tree.js +8 -7
  36. package/scripts/events/lib/notebooks.js +6 -21
  37. package/scripts/filters/index.js +8 -3
  38. package/scripts/filters/lib/img.js +15 -0
  39. package/scripts/filters/lib/img_lazyload.js +1 -0
  40. package/scripts/filters/lib/img_onerror.js +21 -12
  41. package/scripts/filters/lib/md_link.js +26 -0
  42. package/scripts/filters/lib/page-view-model.js +36 -16
  43. package/scripts/generators/author.js +0 -1
  44. package/scripts/generators/search.js +3 -3
  45. package/scripts/generators/stellar-icons.js +2 -0
  46. package/scripts/helpers/collection.js +3 -3
  47. package/scripts/helpers/comments_model.js +2 -2
  48. package/scripts/helpers/extension_assets.js +16 -2
  49. package/scripts/helpers/json_ld.js +5 -4
  50. package/scripts/helpers/md_link.js +7 -0
  51. package/scripts/helpers/page_meta.js +2 -0
  52. package/scripts/helpers/post_view_model.js +15 -12
  53. package/scripts/helpers/script_json.js +3 -0
  54. package/scripts/lib/browser-runtime.js +4 -11
  55. package/scripts/lib/collection-pipeline/adapters/notebook.js +4 -6
  56. package/scripts/lib/collection-pipeline/adapters/post.js +5 -2
  57. package/scripts/lib/collection-pipeline/adapters/topic.js +15 -10
  58. package/scripts/lib/collection-pipeline/index.js +13 -8
  59. package/scripts/lib/comments.js +20 -2
  60. package/scripts/lib/config-schema.js +13 -3
  61. package/scripts/lib/content-config.js +35 -23
  62. package/scripts/lib/contribution-contract.js +8 -16
  63. package/scripts/lib/contribution-registry.js +102 -51
  64. package/scripts/lib/doctor.js +14 -10
  65. package/scripts/lib/hero-effect-registry.js +0 -8
  66. package/scripts/lib/html-images.js +7 -6
  67. package/scripts/lib/image-metadata.js +308 -0
  68. package/scripts/lib/internal-constants.js +3 -29
  69. package/scripts/lib/models/index.js +21 -1537
  70. package/scripts/lib/models/notebook.js +292 -0
  71. package/scripts/lib/models/post.js +72 -0
  72. package/scripts/lib/models/shared.js +571 -0
  73. package/scripts/lib/models/topic.js +201 -0
  74. package/scripts/lib/models/wiki.js +413 -0
  75. package/scripts/lib/page-view-model-registry.js +126 -82
  76. package/scripts/lib/partial-navigation.js +64 -0
  77. package/scripts/lib/resource-assets.js +19 -0
  78. package/scripts/lib/script-json.js +13 -0
  79. package/scripts/lib/source-config.js +26 -16
  80. package/scripts/schema/config-rules.js +20 -15
  81. package/scripts/schema/content-config-rules.js +1 -1
  82. package/scripts/schema/content-config-schema.js +6 -4
  83. package/scripts/schema/model-schema.js +7 -5
  84. package/scripts/tags/lib/albums.js +1 -1
  85. package/scripts/tags/lib/friends.js +1 -1
  86. package/scripts/tags/lib/ghcard.js +1 -1
  87. package/scripts/tags/lib/posters.js +1 -1
  88. package/scripts/tags/lib/sites.js +2 -2
  89. package/source/css/_appearances/_mixins.styl +14 -16
  90. package/source/css/_appearances/minimal.styl +80 -46
  91. package/source/css/_common/button.styl +2 -2
  92. package/source/css/_common/cap.styl +1 -1
  93. package/source/css/_common/highlight.styl +2 -3
  94. package/source/css/_common/html.styl +5 -1
  95. package/source/css/_common/input.styl +1 -1
  96. package/source/css/_common/md-link.styl +13 -0
  97. package/source/css/_common/span.styl +1 -1
  98. package/source/css/_common/title.styl +2 -2
  99. package/source/css/_common/toast.styl +1 -1
  100. package/source/css/_components/collection.styl +3 -3
  101. package/source/css/_components/layout.styl +42 -8
  102. package/source/css/_components/list.styl +5 -3
  103. package/source/css/_components/md.styl +1 -2
  104. package/source/css/_components/pages/archives.styl +4 -4
  105. package/source/css/_components/pages/article-story.styl +1 -1
  106. package/source/css/_components/pages/article-tech.styl +2 -2
  107. package/source/css/_components/partial/article-footer.styl +1 -1
  108. package/source/css/_components/partial/article-share.styl +3 -0
  109. package/source/css/_components/partial/bread-nav.styl +2 -2
  110. package/source/css/_components/partial/cover.styl +4 -4
  111. package/source/css/_components/partial/footer.styl +2 -2
  112. package/source/css/_components/partial/paginator.styl +1 -1
  113. package/source/css/_components/partial/post-panel.styl +3 -3
  114. package/source/css/_components/partial/related.styl +14 -3
  115. package/source/css/_components/pin-slider.styl +7 -4
  116. package/source/css/_components/sidebar/brand.styl +3 -3
  117. package/source/css/_components/sidebar/search.styl +44 -20
  118. package/source/css/_components/tag-plugins/banner.styl +1 -1
  119. package/source/css/_components/tag-plugins/chat.styl +2 -2
  120. package/source/css/_components/tag-plugins/copy.styl +1 -1
  121. package/source/css/_components/tag-plugins/emoji.styl +1 -0
  122. package/source/css/_components/tag-plugins/folders.styl +2 -2
  123. package/source/css/_components/tag-plugins/folding.styl +2 -2
  124. package/source/css/_components/tag-plugins/friends.styl +2 -2
  125. package/source/css/_components/tag-plugins/friends_posts.styl +4 -2
  126. package/source/css/_components/tag-plugins/gallery.styl +4 -3
  127. package/source/css/_components/tag-plugins/hashtag.styl +1 -1
  128. package/source/css/_components/tag-plugins/image.styl +2 -0
  129. package/source/css/_components/tag-plugins/inline-labels.styl +2 -2
  130. package/source/css/_components/tag-plugins/link.styl +1 -1
  131. package/source/css/_components/tag-plugins/mark.styl +2 -2
  132. package/source/css/_components/tag-plugins/mbti.styl +6 -4
  133. package/source/css/_components/tag-plugins/mdrender.styl +1 -1
  134. package/source/css/_components/tag-plugins/navbar.styl +1 -1
  135. package/source/css/_components/tag-plugins/note.styl +1 -1
  136. package/source/css/_components/tag-plugins/okr.styl +2 -2
  137. package/source/css/_components/tag-plugins/poetry.styl +2 -2
  138. package/source/css/_components/tag-plugins/quot.styl +4 -2
  139. package/source/css/_components/tag-plugins/rating.styl +2 -2
  140. package/source/css/_components/tag-plugins/read/paper.styl +3 -3
  141. package/source/css/_components/tag-plugins/read/reel.styl +3 -3
  142. package/source/css/_components/tag-plugins/sites.styl +2 -2
  143. package/source/css/_components/tag-plugins/tabs.styl +1 -1
  144. package/source/css/_components/tag-plugins/timeline.styl +6 -6
  145. package/source/css/_components/tag-plugins/toc.styl +2 -2
  146. package/source/css/_components/tag-plugins/vote.styl +2 -2
  147. package/source/css/_components/widgets/ghrepo.styl +1 -1
  148. package/source/css/_components/widgets/ghuser.styl +4 -4
  149. package/source/css/_components/widgets/markdown.styl +3 -0
  150. package/source/css/_components/widgets/settings.styl +2 -2
  151. package/source/css/_components/widgets/toc.styl +24 -3
  152. package/source/css/_components/widgets/widgets.styl +1 -1
  153. package/source/css/_components/wiki-card.styl +3 -3
  154. package/source/css/_custom.styl +1 -0
  155. package/source/css/_defines/func.styl +2 -2
  156. package/source/css/_defines/theme_base.styl +0 -2
  157. package/source/css/_defines/typography.styl +10 -0
  158. package/source/css/_plugins/card-hover.styl +46 -43
  159. package/source/css/_plugins/index.styl +1 -1
  160. package/source/css/comments/artalk.styl +1 -1
  161. package/source/css/comments/twikoo.styl +2 -2
  162. package/source/css/comments/waline.styl +1 -1
  163. package/source/css/plugins/swiper.styl +2 -1
  164. package/source/js/color.js +21 -85
  165. package/source/js/main.js +63 -56
  166. package/source/js/navigation-init.js +58 -0
  167. package/source/js/plugins/adaptive-text.js +51 -25
  168. package/source/js/plugins/card-hover.js +5 -3
  169. package/source/js/plugins/download-file.js +26 -28
  170. package/source/js/plugins/video.js +22 -63
  171. package/source/js/profile.js +2 -0
  172. package/source/js/runtime/asset-loader.js +43 -34
  173. package/source/js/runtime/extension-registry.js +78 -57
  174. package/source/js/runtime/extensions/adaptive-text.js +14 -0
  175. package/source/js/runtime/extensions/card-hover.js +3 -2
  176. package/source/js/runtime/extensions/code-copy.js +19 -0
  177. package/source/js/runtime/extensions/comments.js +4 -3
  178. package/source/js/runtime/extensions/deferred-icons.js +13 -7
  179. package/source/js/runtime/extensions/diagrams.js +20 -0
  180. package/source/js/runtime/extensions/hero-effect.js +7 -3
  181. package/source/js/runtime/extensions/heti.js +12 -0
  182. package/source/js/runtime/extensions/lazy-loading.js +74 -0
  183. package/source/js/runtime/extensions/lightbox.js +28 -0
  184. package/source/js/runtime/extensions/link-prefetch.js +5 -0
  185. package/source/js/runtime/extensions/mathjax.js +24 -0
  186. package/source/js/runtime/extensions/page-controls.js +14 -0
  187. package/source/js/runtime/extensions/partial-navigation.js +172 -0
  188. package/source/js/runtime/extensions/reveal.js +29 -8
  189. package/source/js/runtime/extensions/search.js +4 -1
  190. package/source/js/runtime/extensions/services.js +113 -16
  191. package/source/js/runtime/extensions/settings.js +14 -10
  192. package/source/js/runtime/extensions/swiper.js +22 -0
  193. package/source/js/runtime/image-color.js +211 -0
  194. package/source/js/runtime/index.js +60 -43
  195. package/source/js/runtime/legacy-request-adapter.js +2 -0
  196. package/source/js/runtime/request-cache.js +26 -0
  197. package/source/js/search/algolia-search.js +1 -1
  198. package/source/js/search/highlight.js +6 -9
  199. package/source/js/search/local-search.js +128 -81
  200. package/source/js/services/artalk_latest_comment.js +6 -4
  201. package/source/js/services/contributors.js +6 -3
  202. package/source/js/services/friends.js +7 -4
  203. package/source/js/services/friends_and_posts.js +7 -4
  204. package/source/js/services/ghinfo.js +6 -3
  205. package/source/js/services/giscus_latest_comment.js +6 -3
  206. package/source/js/services/mdrender.js +10 -9
  207. package/source/js/services/memos.js +9 -3
  208. package/source/js/services/rating.js +13 -10
  209. package/source/js/services/rss.js +6 -3
  210. package/source/js/services/siteinfo.js +43 -14
  211. package/source/js/services/sites.js +9 -6
  212. package/source/js/services/timeline.js +6 -3
  213. package/source/js/services/twikoo_latest_comment.js +10 -5
  214. package/source/js/services/vote.js +11 -8
  215. package/source/js/services/waline_latest_comment.js +6 -3
  216. package/source/js/services/weibo.js +6 -3
  217. package/source/js/tagtree.js +7 -7
  218. package/scripts/events/lib/fix_image_tags.js +0 -44
  219. package/scripts/events/lib/get_image_ratios.js +0 -110
  220. package/source/js/runtime/extensions/feature.js +0 -200
package/CHANGELOG.md CHANGED
@@ -1,5 +1,39 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.0.0-rc.3
4
+
5
+ > 发布日期:2026-09-10
6
+
7
+ 本节记录从公开候选 `2.0.0-rc.2` 到 `2.0.0-rc.3` 最终文件树的净变化。
8
+
9
+ ### 新功能
10
+
11
+ - 默认启用同集合局部导航:外壳兼容时更新正文、右栏和页面元数据,保留导航区域;支持历史滚动恢复,不兼容页面或请求失败时整页跳转。
12
+ - 图片尺寸与 HSLA 平均色在 server/generate 时自动增量提取并持久缓存,补全生成 HTML,不修改 Markdown 或原图;新增 `hexo stellar images` 及 `--dry-run/--page/--refresh` 选项。
13
+ - Markdown 文本链接、文章参考链接、远程 Markdown 与评论链接支持站点图标增强;站点信息支持 `appicon/favicon`,保留 `icon` 回退,行内请求失败显示断链图标。
14
+ - 新增字体平滑与设计字重映射;卡片 Spotlight 与 Tilt 可独立开关。
15
+ - 第三方 JS/CSS 地址可在对应搜索、评论、Feature 或 Markdown 服务配置中覆盖;Artalk 默认使用服务端配套资源。
16
+
17
+ ### 修复与改进
18
+
19
+ - 共享 Collection 模型并隔离构建缓存,复用 PageViewModel 和归档文章投影,减少重复解析与校验;忽略 Collection 目录中的 macOS `.DS_Store` 文件。
20
+ - 完善 Extension 的页面/文档作用域、异步取消及卸载清理;修复 Flying Pages 初始化、图片懒加载与 Safari 错误占位时序,Reveal 待入场透明度在卸载时恢复。
21
+ - 修复文章上下篇、作者页 Topic 文章与作者横幅;Topic 文章默认继承全局分享配置,Wiki 与 Notebook 仍默认关闭分享。
22
+ - Doctor 与构建统一恢复可用的配置:普通字段问题和不适用的表现参数给出 warning,缺少集合显示名时使用 Collection ID;根结构与归属冲突仍阻止构建。
23
+ - 本地搜索按章节组织结果并分批查询、渲染,改进摘要、高亮、加载更多和结束提示。
24
+ - 调整 minimal 外观、暗色背景、移动导航、品牌、目录吸顶与当前条目滚动;修复 Markdown Widget 背景、稀疏 Wiki 网格宽度、画廊列数以及轮播、图片标签、头像、MBTI 卡片的比例与布局。
25
+ - GitHub 卡片默认服务切换为 `https://github-stats-extended.vercel.app`;图片颜色处理新增 Sharp 直接依赖。
26
+
27
+ ### 升级注意(配置变更与破坏性改动)
28
+
29
+ - 将 `footer.sections` 改为 `footer.sitemap`;分组保留 `title/items`,但 items 中的 `{title, url}` 对象需改写为 `'[标题](地址)'` Markdown 字符串。默认 sitemap 为空数组;默认页脚正文新增 CC BY-NC-SA 4.0 说明,可自行覆盖 `footer.content`。
30
+ - 将 `features.card_hover.enabled` 替换为独立的 `spotlight` 与 `tilt` 布尔值;希望保持原先全部开启效果时两项均设为 `true`,默认均为 `false`。
31
+ - `features.partial_navigation.enabled` 默认开启,含非主题管理可执行脚本的页面使用整页导航;需要全部整页跳转时将其关闭。
32
+ - `features.image_optimization.enabled` 默认开启,首次处理远程图片可能增加构建时间;关闭后仍复用站点 `source/_data/caches/images_metadata.json`。`features.lazy_loading.auto_aspect_ratio` 继续控制尺寸/比例补全。
33
+ - 第三方资源覆盖不保证任意上游 API 版本兼容;KaTeX 自定义 CSS 时需配套更新 `css_integrity`,或设为 `null` 不附加 SRI。仅覆盖 CSS 地址时会清除继承的旧哈希。
34
+
35
+ Full Changelog: [2.0.0-rc.2...2.0.0-rc.3](https://github.com/xaoxuu/hexo-theme-stellar/compare/2.0.0-rc.2...2.0.0-rc.3)
36
+
3
37
  ## 2.0.0-rc.2
4
38
 
5
39
  > 发布日期:2026-09-07
package/_config.yml CHANGED
@@ -128,10 +128,35 @@ rightbar:
128
128
 
129
129
  # 配置主内容区页脚。
130
130
  footer:
131
- # 设置页脚正文,支持 Markdown 与主题模板变量;空字符串表示隐藏正文。
132
- content: 本站由 [{author.name}](/) 使用 [{theme.name} {theme.version}]({theme.tree}) 主题创建。
133
131
  # 设置主内容区页脚导航分栏;空数组表示不显示分栏。
134
- sections: []
132
+ sitemap: []
133
+ # - title: 博客
134
+ # items:
135
+ # - '[近期发布](/)'
136
+ # - '[分类](/blog/categories/)'
137
+ # - '[标签](/blog/tags/)'
138
+ # - '[归档](/blog/archives/)'
139
+ # - title: 项目
140
+ # items:
141
+ # - '[xxx](/)'
142
+ # - '[xxx](/)'
143
+ # - '[xxx](/)'
144
+ # - '[xxx](/)'
145
+ # - title: 社交
146
+ # items:
147
+ # - '[xxx](/)'
148
+ # - '[xxx](/)'
149
+ # - '[xxx](/)'
150
+ # - '[xxx](/)'
151
+ # - title: 关于
152
+ # items:
153
+ # - '[xxx](/)'
154
+ # - '[xxx](/)'
155
+ # - '[xxx](/)'
156
+ # - '[xxx](/)'
157
+ content: | # 支持 Markdown 格式
158
+ 本站由 [{author.name}](/) 使用 [{theme.name} {theme.version}]({theme.tree}) 主题创建。
159
+ 本博客所有文章除特别声明外,均采用 [CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/) 许可协议,转载请注明出处。
135
160
 
136
161
  # 配置各页面与内容 Profile 的专属设置、路由、导航和 Region 默认值;省略字段时继承站点级 Region。
137
162
  profiles:
@@ -457,7 +482,7 @@ article:
457
482
  footer:
458
483
  # 设置文章许可协议;false 表示不显示许可信息。
459
484
  license: 本文采用 [署名-非商业性使用-相同方式共享 4.0 国际](https://creativecommons.org/licenses/by-nc-sa/4.0/) 许可协议,转载请注明出处。
460
- # 设置文章分享服务;普通博客默认全部启用,Collection 内容页默认关闭,可通过 footer.share 显式开启。
485
+ # 设置文章分享服务;普通博客与 Topic 专栏博客默认全部启用,Wiki 与 Notebook 默认关闭,可通过 footer.share 显式开启。
461
486
  # 支持 wechat、weibo、x、telegram、whatsapp、email、link、system;空数组表示不显示分享入口。
462
487
  share:
463
488
  - wechat
@@ -500,6 +525,20 @@ appearance:
500
525
 
501
526
  # 配置全站排版。
502
527
  typography:
528
+ # 设置全站 -webkit-font-smoothing;可选值为 auto、none 或 antialiased。
529
+ font_smoothing: antialiased
530
+ # 将设计字重映射到字体实际提供的字重;例如将 500 改为 600。
531
+ # 映射只执行一次,目标值范围为 1–1000。
532
+ font_weight:
533
+ 100: 100
534
+ 200: 200
535
+ 300: 300
536
+ 400: 400
537
+ 500: 500
538
+ 600: 600
539
+ 700: 700
540
+ 800: 800
541
+ 900: 900
503
542
  # 配置字体族。
504
543
  font_family:
505
544
  # 设置正文的字体候选列表。
@@ -614,6 +653,8 @@ search:
614
653
  cache_ttl_seconds: 86400
615
654
  # 配置 Algolia 搜索参数。
616
655
  algolia:
656
+ # 自定义资源地址;null 使用主题默认资源。
657
+ js: https://gcore.jsdelivr.net/algoliasearch/3/algoliasearch.min.js
617
658
  # 设置 Algolia Application ID。
618
659
  appId: null
619
660
  # 设置 Algolia Search API Key。
@@ -629,6 +670,8 @@ comments:
629
670
  title: null
630
671
  # 配置 Beaudar 参数,字段会传递给 Beaudar 客户端。
631
672
  beaudar:
673
+ # 自定义资源地址;null 使用主题默认资源。
674
+ js: https://beaudar.lipk.org/client.js
632
675
  # 设置关联的 GitHub 仓库,格式为 owner/repo。
633
676
  repo: xxx/xxx
634
677
  # 设置 Issue 映射方式。
@@ -651,6 +694,8 @@ comments:
651
694
  branch: main
652
695
  # 配置 Utterances 参数,字段会传递给 Utterances 客户端。
653
696
  utterances:
697
+ # 自定义资源地址;null 使用主题默认资源。
698
+ js: https://utteranc.es/client.js
654
699
  # 设置关联的 GitHub 仓库,格式为 owner/repo。
655
700
  repo: xxx/xxx
656
701
  # 设置 Issue 映射方式。
@@ -663,6 +708,8 @@ comments:
663
708
  label: null
664
709
  # 配置 Giscus 参数,字段会作为 data 属性传递给 Giscus 客户端。
665
710
  giscus:
711
+ # 自定义资源地址;null 使用主题默认资源。
712
+ js: https://giscus.app/client.js
666
713
  # 设置关联的 GitHub 仓库,格式为 owner/repo。
667
714
  data-repo: xxx/xxx
668
715
  # 设置 Giscus 仓库 ID;null 表示未配置。
@@ -691,10 +738,18 @@ comments:
691
738
  crossorigin: anonymous
692
739
  # 配置 Twikoo 参数,字段会传递给 Twikoo 客户端。
693
740
  twikoo:
741
+ # 自定义资源地址;null 使用主题默认资源。
742
+ js: https://gcore.jsdelivr.net/npm/twikoo@1.6/dist/twikoo.all.min.js
694
743
  # 设置 Twikoo 环境 ID 或服务地址。
695
744
  envId: https://xxx
696
745
  # 配置 Waline 参数,字段会传递给 Waline 客户端。
697
746
  waline:
747
+ # 自定义资源地址;null 使用主题默认资源。
748
+ js: https://gcore.jsdelivr.net/npm/@waline/client@3.15.2/dist/waline.js
749
+ # 自定义资源地址;null 使用主题默认资源。
750
+ css: https://gcore.jsdelivr.net/npm/@waline/client@3.15.2/dist/waline.css
751
+ # 自定义资源地址;null 使用主题默认资源。
752
+ meta_css: https://gcore.jsdelivr.net/npm/@waline/client@3.15.2/dist/waline-meta.css
698
753
  # 设置 Waline 服务端地址。
699
754
  serverURL: https://waline.vercel.app
700
755
  # 控制是否启用评论计数。
@@ -703,6 +758,10 @@ comments:
703
758
  pageview: false
704
759
  # 配置 Artalk 参数,字段会传递给 Artalk 客户端。
705
760
  artalk:
761
+ # 自定义资源地址;null 使用服务端内置的配套资源。
762
+ js: null
763
+ # 自定义资源地址;null 使用服务端内置的配套资源。
764
+ css: null
706
765
  # 设置 Artalk 服务端地址;null 表示未配置。
707
766
  server: null
708
767
  # 设置 Artalk 站点名称;空字符串表示未配置。
@@ -785,24 +844,45 @@ tags:
785
844
 
786
845
  # 配置可选的浏览器功能。
787
846
  features:
847
+ # 同集合内容页面只更新正文和右栏;不兼容的页面自动整页跳转。
848
+ partial_navigation:
849
+ enabled: true
850
+ # 配置轮播使用的第三方资源;不改变按需加载条件。
851
+ swiper:
852
+ # 自定义脚本地址;null 使用默认资源。
853
+ js: https://unpkg.com/swiper@10.3/swiper-bundle.min.js
854
+ # 自定义样式地址;null 使用默认资源。
855
+ css: https://unpkg.com/swiper@10.3/swiper-bundle.min.css
788
856
  # 配置配色模式切换功能。
789
857
  color_scheme_switch:
790
858
  # 控制是否启用配色模式切换。
791
859
  enabled: false
860
+ # 自动优化图片体验:增量提取尺寸与平均色,不压缩或替换原图。
861
+ image_optimization:
862
+ # server/generate 自动补齐缺失元数据;关闭后仍复用已有结果,手动 images 命令可用。
863
+ enabled: true
792
864
  # 配置图片懒加载。
793
865
  lazy_loading:
866
+ # 自定义资源地址;null 使用主题默认资源。
867
+ js: https://gcore.jsdelivr.net/npm/vanilla-lazyload@19.1/dist/lazyload.min.js
794
868
  # 设置懒加载过渡效果;可选值为 blur 或 fade。
795
869
  transition: fade
796
- # 控制是否自动补全图片宽高比。
870
+ # 从站点图片元数据补全尺寸与比例;server/generate 自动增量预处理,不修改 Markdown。
797
871
  auto_aspect_ratio: true
798
872
  # 配置图片灯箱。
799
873
  lightbox:
874
+ # 自定义资源地址;null 使用主题默认资源。
875
+ js: https://gcore.jsdelivr.net/npm/@fancyapps/ui@5.0/dist/fancybox/fancybox.umd.js
876
+ # 自定义资源地址;null 使用主题默认资源。
877
+ css: https://gcore.jsdelivr.net/npm/@fancyapps/ui@5.0/dist/fancybox/fancybox.css
800
878
  # 控制是否启用图片灯箱。
801
879
  enabled: true
802
880
  # 设置灯箱匹配图片的 CSS 选择器。
803
881
  selector: '.timenode p>img'
804
882
  # 配置链接预取。
805
883
  link_prefetch:
884
+ # 自定义资源地址;null 使用主题默认资源。
885
+ js: https://gcore.jsdelivr.net/npm/flying-pages@2/flying-pages.min.js
806
886
  # 控制是否启用链接预取。
807
887
  enabled: true
808
888
  # 配置滚动揭示动画。
@@ -811,10 +891,16 @@ features:
811
891
  enabled: true
812
892
  # 配置卡片悬停效果。
813
893
  card_hover:
814
- # 控制是否启用卡片悬停效果。
815
- enabled: false
894
+ # 控制是否启用鼠标跟随光照。
895
+ spotlight: false
896
+ # 控制是否启用 3D 倾斜。
897
+ tilt: false
816
898
  # 配置 Heti 中文排版增强。
817
899
  heti:
900
+ # 自定义资源地址;null 使用主题默认资源。
901
+ js: https://unpkg.com/heti@0.9/umd/heti-addon.min.js
902
+ # 自定义资源地址;null 使用主题默认资源。
903
+ css: https://unpkg.com/heti@0.9/umd/heti.min.css
818
904
  # 控制是否启用 Heti。
819
905
  enabled: false
820
906
  # 配置数学公式渲染。
@@ -822,15 +908,23 @@ features:
822
908
  # 设置数学公式 Provider;可选值为 katex、mathjax 或 null。
823
909
  provider: null
824
910
  # 设置 KaTeX 参数;空对象表示使用 Provider 默认参数。
825
- katex: {}
911
+ katex:
912
+ # 自定义资源地址;null 使用主题默认资源。
913
+ css: https://cdn.jsdelivr.net/npm/katex@0.16.23/dist/katex.min.css
914
+ # CSS 的配套完整性哈希;null 不附加 SRI,自定义 CSS 时请同时提供匹配哈希。
915
+ css_integrity: sha384-//SZkxyB7axjCAopkAL1E1rve+ZSPKapD89Lo/lLhcsXR+zOYl5z6zJZEFXil+q0
826
916
  # 设置 MathJax 参数;空对象表示使用 Provider 默认参数。
827
- mathjax: {}
917
+ mathjax:
918
+ # 自定义资源地址;null 使用主题默认资源。
919
+ js: https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.2.2/es5/tex-mml-chtml.min.js
828
920
  # 配置图表渲染。
829
921
  diagrams:
830
922
  # 设置图表 Provider;可选值为 mermaid 或 null。
831
923
  provider: null
832
924
  # 配置 Mermaid 参数。
833
925
  mermaid:
926
+ # 自定义资源地址;null 使用主题默认资源。
927
+ js: https://gcore.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js
834
928
  # 设置 Mermaid 主题;可选值为 default、dark、forest 或 neutral。
835
929
  theme: neutral
836
930
 
@@ -840,6 +934,10 @@ features:
840
934
 
841
935
  # 配置主题使用的数据服务。
842
936
  services:
937
+ # 配置所有动态 Markdown 内容共享的 Marked 客户端。
938
+ markdown:
939
+ # 自定义脚本地址;null 使用默认资源。
940
+ js: https://gcore.jsdelivr.net/npm/marked@13.0/lib/marked.umd.min.js
843
941
  # 配置站点信息服务。
844
942
  site_info:
845
943
  # 设置站点信息 Provider;可选值为 site_info_api 或 null。
@@ -879,7 +977,7 @@ services:
879
977
  # 配置 github_readme_stats Provider。
880
978
  github_readme_stats:
881
979
  # 设置 GitHub 卡片接口地址。
882
- endpoint: https://github-readme-stats.vercel.app
980
+ endpoint: https://github-stats-extended.vercel.app
883
981
  # 配置 GitHub 基础服务地址。
884
982
  github:
885
983
  # 设置 GitHub API 地址。
package/_data/icons.yml CHANGED
@@ -8,6 +8,7 @@ default:leftbar: <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32"
8
8
  default:leftbar-toggle: <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" d="M3.172 4.172C2 5.343 2 7.229 2 11v2c0 3.771 0 5.657 1.172 6.828S6.229 21 10 21h5V3h-5C6.229 3 4.343 3 3.172 4.172" clip-rule="evenodd" opacity=".5"/><path fill="currentColor" d="M5.5 9.25a.75.75 0 0 0 0 1.5h6a.75.75 0 0 0 0-1.5zm1 4a.75.75 0 0 0 0 1.5h4a.75.75 0 0 0 0-1.5zM22 13v-2c0-3.771 0-5.657-1.172-6.828c-.974-.975-3.192-1.139-5.828-1.166v17.988c2.636-.027 4.854-.191 5.828-1.166C22 18.657 22 16.771 22 13"/></svg>
9
9
  default:settings: <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><g fill="currentColor"><path fill-rule="evenodd" d="M12.4277 2C11.3139 2 10.2995 2.6007 8.27081 3.80211L7.58466 4.20846C5.55594 5.40987 4.54158 6.01057 3.98466 7C3.42773 7.98943 3.42773 9.19084 3.42773 11.5937V12.4063C3.42773 14.8092 3.42773 16.0106 3.98466 17C4.54158 17.9894 5.55594 18.5901 7.58466 19.7915L8.27081 20.1979C10.2995 21.3993 11.3139 22 12.4277 22C13.5416 22 14.5559 21.3993 16.5847 20.1979L17.2708 19.7915C19.2995 18.5901 20.3139 17.9894 20.8708 17C21.4277 16.0106 21.4277 14.8092 21.4277 12.4063V11.5937C21.4277 9.19084 21.4277 7.98943 20.8708 7C20.3139 6.01057 19.2995 5.40987 17.2708 4.20846L16.5847 3.80211C14.5559 2.6007 13.5416 2 12.4277 2Z" clip-rule="evenodd" opacity=".5"/><path d="M12.4277 8.25C10.3567 8.25 8.67773 9.92893 8.67773 12C8.67773 14.0711 10.3567 15.75 12.4277 15.75C14.4988 15.75 16.1777 14.0711 16.1777 12C16.1777 9.92893 14.4988 8.25 12.4277 8.25Z"/></g></svg>
10
10
  default:link: <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><g fill="currentColor"><g opacity=".5"><path d="M19.7388 4.26118C17.0572 1.57961 12.7095 1.57961 10.0279 4.26118L9.30707 4.98203C9.01418 5.27492 9.01418 5.7498 9.30707 6.04269C9.59997 6.33558 10.0748 6.33558 10.3677 6.04269L11.0886 5.32184C13.1844 3.22605 16.5823 3.22605 18.6781 5.32184C20.7739 7.41763 20.7739 10.8156 18.6781 12.9114L17.9573 13.6322C17.6644 13.9251 17.6644 14.4 17.9573 14.6929C18.2502 14.9858 18.725 14.9858 19.0179 14.6929L19.7388 13.972C22.4203 11.2905 22.4203 6.94276 19.7388 4.26118Z"/><path d="M6.04269 9.30707C6.33558 9.59997 6.33558 10.0748 6.04269 10.3677L5.32184 11.0886C3.22605 13.1844 3.22605 16.5823 5.32184 18.6781C7.41763 20.7739 10.8156 20.7739 12.9114 18.6781L13.6322 17.9573C13.9251 17.6644 14.4 17.6644 14.6929 17.9573C14.9858 18.2501 14.9858 18.725 14.6929 19.0179L13.972 19.7388C11.2905 22.4203 6.94276 22.4203 4.26118 19.7388C1.57961 17.0572 1.57961 12.7095 4.26118 10.0279L4.98203 9.30707C5.27492 9.01418 5.7498 9.01418 6.04269 9.30707Z"/></g><path d="M14.6933 9.30707C14.9862 9.59997 14.9862 10.0748 14.6933 10.3677L10.3682 14.6928C10.0753 14.9857 9.60045 14.9857 9.30756 14.6928C9.01467 14.3999 9.01467 13.9251 9.30756 13.6322L13.6327 9.30707C13.9255 9.01418 14.4004 9.01418 14.6933 9.30707Z"/></g></svg>
11
+ default:link-broken: <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/ --><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-width="1.5"><path d="m10 5.049l.367-.343c2.432-2.275 6.376-2.275 8.809 0s2.432 5.961 0 8.235L16.974 15M14 18.928l-.366.35c-2.422 2.316-6.38 2.286-8.802-.03c-2.398-2.293-2.456-6.033-.091-8.358l.905-.89" opacity=".5"/><path d="M6.587 3L7.5 5.205m-3.998.882L9.05 8.795"/></g></svg>
11
12
  default:trash: <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><g fill="currentColor"><path d="M3 6.38597C3 5.90152 3.34538 5.50879 3.77143 5.50879L6.43567 5.50832C6.96502 5.49306 7.43202 5.11033 7.61214 4.54412C7.61688 4.52923 7.62232 4.51087 7.64185 4.44424L7.75665 4.05256C7.8269 3.81241 7.8881 3.60318 7.97375 3.41617C8.31209 2.67736 8.93808 2.16432 9.66147 2.03297C9.84457 1.99972 10.0385 1.99986 10.2611 2.00002H13.7391C13.9617 1.99986 14.1556 1.99972 14.3387 2.03297C15.0621 2.16432 15.6881 2.67736 16.0264 3.41617C16.1121 3.60318 16.1733 3.81241 16.2435 4.05256L16.3583 4.44424C16.3778 4.51087 16.3833 4.52923 16.388 4.54412C16.5682 5.11033 17.1278 5.49353 17.6571 5.50879H20.2286C20.6546 5.50879 21 5.90152 21 6.38597C21 6.87043 20.6546 7.26316 20.2286 7.26316H3.77143C3.34538 7.26316 3 6.87043 3 6.38597Z"/><path fill-rule="evenodd" d="M9.42543 11.4815C9.83759 11.4381 10.2051 11.7547 10.2463 12.1885L10.7463 17.4517C10.7875 17.8855 10.4868 18.2724 10.0747 18.3158C9.66253 18.3592 9.29499 18.0426 9.25378 17.6088L8.75378 12.3456C8.71256 11.9118 9.01327 11.5249 9.42543 11.4815Z" clip-rule="evenodd"/><path fill-rule="evenodd" d="M14.5747 11.4815C14.9868 11.5249 15.2875 11.9118 15.2463 12.3456L14.7463 17.6088C14.7051 18.0426 14.3376 18.3592 13.9254 18.3158C13.5133 18.2724 13.2126 17.8855 13.2538 17.4517L13.7538 12.1885C13.795 11.7547 14.1625 11.4381 14.5747 11.4815Z" clip-rule="evenodd"/><path d="M11.5956 22.0001H12.4044C15.1871 22.0001 16.5785 22.0001 17.4831 21.1142C18.3878 20.2283 18.4803 18.7751 18.6654 15.8686L18.9321 11.6807C19.0326 10.1037 19.0828 9.31524 18.6289 8.81558C18.1751 8.31592 17.4087 8.31592 15.876 8.31592H8.12405C6.59127 8.31592 5.82488 8.31592 5.37105 8.81558C4.91722 9.31524 4.96744 10.1037 5.06788 11.6807L5.33459 15.8686C5.5197 18.7751 5.61225 20.2283 6.51689 21.1142C7.42153 22.0001 8.81289 22.0001 11.5956 22.0001Z" opacity=".5"/></g></svg>
12
13
  default:rightbar: <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6h11m-11 6h11m-11 6h11M4 6h1v4m-1 0h2m0 8H4c0-1 2-2 2-3s-1-1.5-2-1"/></svg>
13
14
  default:profile: <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><g fill="currentColor"><path d="M12 2a10 10 0 1 0 0 20a10 10 0 0 0 0-20" opacity=".5"/><path d="M12 6a3 3 0 1 0 0 6a3 3 0 0 0 0-6m0 7.5c-3.04 0-5.5 1.57-5.5 3.5c0 .65.28 1.26.77 1.77A7.96 7.96 0 0 0 12 20.5a7.96 7.96 0 0 0 4.73-1.73c.49-.51.77-1.12.77-1.77c0-1.93-2.46-3.5-5.5-3.5"/></g></svg>
package/languages/en.yml CHANGED
@@ -84,6 +84,7 @@ search:
84
84
  scope_all: All
85
85
  scope_blog: Blog
86
86
  no_results: No Results!
87
+ no_more: No more results
87
88
  close: Close search
88
89
 
89
90
  settings:
@@ -84,6 +84,7 @@ search:
84
84
  scope_all: 全站
85
85
  scope_blog: 博客
86
86
  no_results: 没有找到内容!
87
+ no_more: 没有更多了
87
88
  close: 关闭搜索
88
89
 
89
90
  settings:
@@ -84,6 +84,7 @@ search:
84
84
  scope_all: 全站
85
85
  scope_blog: 部落格
86
86
  no_results: 沒有找到內容!
87
+ no_more: 沒有更多了
87
88
  close: 關閉搜尋
88
89
 
89
90
  settings:
@@ -4,7 +4,7 @@ function layoutDiv() {
4
4
  const cmt = comments;
5
5
  if (cmt && cmt.service && (cmt.service.length > 0)) {
6
6
  const name = cmt.service;
7
- const body = cmt.options;
7
+ var body = cmt.options;
8
8
  el += '<div id="' + name + '"';
9
9
  for (let key of Object.keys(body)) {
10
10
  if (body[key] !== null) {
@@ -4,7 +4,7 @@ function layoutDiv() {
4
4
  const cmt = comments;
5
5
  if (cmt?.service?.length > 0) {
6
6
  const name = cmt.service;
7
- var body = Object.assign({}, cmt.options);
7
+ var body = cmt.options;
8
8
  el += '<div id="' + name + '"';
9
9
  for (let key of Object.keys(body)) {
10
10
  if (body[key] !== null) {
@@ -4,7 +4,7 @@ function layoutDiv() {
4
4
  const cmt = comments;
5
5
  if (cmt && cmt.service && (cmt.service.length > 0)) {
6
6
  const name = cmt.service;
7
- const body = cmt.options;
7
+ var body = cmt.options;
8
8
  el += '<div id="' + name + '"';
9
9
  for (let key of Object.keys(body)) {
10
10
  if (body[key] !== null) {
@@ -32,6 +32,7 @@ function layoutWikiCover() {
32
32
  var effectPresentation = effect.presentation && typeof effect.presentation === 'object' && !Array.isArray(effect.presentation) ? effect.presentation : {};
33
33
  var effectBackground = typeof effectPresentation.background === 'string' ? effectPresentation.background : '#000000';
34
34
  var respectsReducedMotion = effectRuntime.respectReducedMotion !== false;
35
+ var effectResourceJson = escape_html(JSON.stringify(hero_effect_resource(effect.type)));
35
36
  var effectOptionsJson = escape_html(JSON.stringify(effectOptions));
36
37
  var effectRuntimeJson = escape_html(JSON.stringify(effectRuntime));
37
38
  var projectName = cover.projectName;
@@ -49,7 +50,7 @@ function layoutWikiCover() {
49
50
  el += '<img class="wiki-cover-background-blur" src="' + escape_html(background) + '" alt="" />';
50
51
  }
51
52
  if (hasEffect) {
52
- el += '<canvas data-hero-effect="' + escape_html(effect.type) + '" data-effect-options="' + effectOptionsJson + '" data-effect-runtime="' + effectRuntimeJson + '"></canvas>';
53
+ el += '<canvas data-hero-effect="' + escape_html(effect.type) + '" data-effect-resource="' + effectResourceJson + '" data-effect-options="' + effectOptionsJson + '" data-effect-runtime="' + effectRuntimeJson + '"></canvas>';
53
54
  }
54
55
  el += '<div class="wiki-cover-background-overlay"></div></div>';
55
56
  el += '<div class="wiki-cover-layout"' + adaptiveTextAttr + '>';
@@ -14,6 +14,12 @@ var stellarResources = {
14
14
  fallbacks: stellar_config('fallbacks')
15
15
  }
16
16
 
17
+ function cssString(value) {
18
+ return '"' + String(value).replace(/["\\<\u0000-\u001f]/g, function(character) {
19
+ return '\\' + character.codePointAt(0).toString(16) + ' ';
20
+ }) + '"';
21
+ }
22
+
17
23
  function generate_title() {
18
24
  if (pageRender) {
19
25
  return pageRender.seo.title
@@ -185,8 +191,8 @@ function generate_canonical() {
185
191
  <%- custom_inject('headBegin') %>
186
192
  <meta charset="utf-8">
187
193
  <meta name="hexo-theme" content="<%- stellar_info('tree') %>" theme-name="<%- stellar_info('name') %>" theme-version="<%- stellar_info('version') %>">
188
- <%- generate_canonical() %>
189
- <%- generate_robots() %>
194
+ <%- page_meta(generate_canonical()) %>
195
+ <%- page_meta(generate_robots()) %>
190
196
  <%- meta_generator() %>
191
197
  <meta http-equiv='x-dns-prefetch-control' content='on' />
192
198
  <%- preconnect() %>
@@ -198,11 +204,11 @@ function generate_canonical() {
198
204
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
199
205
  <meta name="theme-color" media="(prefers-color-scheme: dark)" content="#000">
200
206
  <meta name="theme-color" content="#f9fafb">
201
- <title><%- generate_title() %></title>
202
- <script>
207
+ <title data-stellar-page-meta><%- generate_title() %></title>
208
+ <script data-stellar-script="core">
203
209
  (function () {
204
210
  var key = 'stellar:v2:leftbar-state';
205
- var fallback = <%- JSON.stringify(stellar_config('leftbar.defaultState')) %>;
211
+ var fallback = <%- script_json(stellar_config('leftbar.defaultState')) %>;
206
212
  try {
207
213
  var value = localStorage.getItem(key);
208
214
  document.documentElement.dataset.leftbarState = value === 'collapsed' || value === 'expanded' ? value : fallback;
@@ -212,10 +218,10 @@ function generate_canonical() {
212
218
  })();
213
219
  </script>
214
220
 
215
- <%- render_open_graph() %>
216
- <%- generate_description() %>
221
+ <%- page_meta(render_open_graph()) %>
222
+ <%- page_meta(generate_description()) %>
217
223
 
218
- <%- generate_keywords() %>
224
+ <%- page_meta(generate_keywords()) %>
219
225
 
220
226
  <!-- feed -->
221
227
  <% if (config.feed && config.feed.path) { %>
@@ -234,7 +240,7 @@ function generate_canonical() {
234
240
 
235
241
  <link rel="preload" href="<%- url_for(`${stellar_info('main_css')}?v=${stellar_info('version')}`) %>" as="style">
236
242
  <link rel="stylesheet" href="<%- url_for(`${stellar_info('main_css')}?v=${stellar_info('version')}`) %>">
237
- <style>:root{--text-loading:<%- JSON.stringify(__('message.loading')) %>;--text-loading-error:<%- JSON.stringify(__('message.loading_failed')) %>}</style>
243
+ <style>:root{--text-loading:<%- cssString(__('message.loading')) %>;--text-loading-error:<%- cssString(__('message.loading_failed')) %>}</style>
238
244
 
239
245
 
240
246
  <% if (config.favicon) { %>
@@ -247,7 +253,7 @@ function generate_canonical() {
247
253
  <% } %>
248
254
  <% } %>
249
255
 
250
- <%- json_ld(pageViewModel || undefined) %>
256
+ <%- page_meta(json_ld(pageViewModel || undefined)) %>
251
257
  <%- custom_inject('headEnd') %>
252
258
 
253
259
  <!-- icons.yml 驱动的 CSS 装饰图标 -->
@@ -1,7 +1,7 @@
1
1
  <%
2
2
  function referenceList(items) {
3
3
  return items.map(function(ref) {
4
- return `<li class="post-title">${markdown(ref)}</li>`
4
+ return `<li class="post-title">${enhance_md_links(markdown(ref))}</li>`
5
5
  }).join('')
6
6
  }
7
7
 
@@ -3,7 +3,10 @@ function itemHtml(id, item, label) {
3
3
  var el = `<div class="item" id="${id}">`
4
4
  if (item) {
5
5
  var title = item.title || (item.date ? date(item.date, config.date_format) : '')
6
- el += `<div class="note">${label}</div>`
6
+ var note = id === 'prev'
7
+ ? `${icon('default:arrow-left')} ${label}`
8
+ : `${label} ${icon('default:arrow-right')}`
9
+ el += `<div class="note">${note}</div>`
7
10
  el += `<a href="${pretty_url(item.path)}">${escape_html(title)}</a>`
8
11
  }
9
12
  return el + '</div>'
@@ -6,18 +6,18 @@ function layoutDiv() {
6
6
  el += `<footer class="page-footer${scrollreveal(' ')} footnote">`
7
7
  el += '<hr>'
8
8
  // sitemap
9
- var sections = siteFooter.sections
10
- if (sections.length > 0) {
11
- var count = sections.length
9
+ var sitemap = siteFooter.sitemap
10
+ if (sitemap.length > 0) {
11
+ var count = sitemap.length
12
12
  if ([6].includes(count)) {
13
13
  count = 3
14
14
  } else if ([7,8].includes(count)) {
15
15
  count = 4
16
16
  } else {
17
- count = Math.min(sections.length, 5)
17
+ count = Math.min(sitemap.length, 5)
18
18
  }
19
19
  el += `<div class="sitemap" style="column-count:${count};">`
20
- for (var group of sections) {
20
+ for (var group of sitemap) {
21
21
  var title = escape_html(group.title)
22
22
  var items = group.items
23
23
  if (items == undefined || items.length == 0) {
@@ -25,9 +25,9 @@ function layoutDiv() {
25
25
  }
26
26
  el += '<div class="sitemap-group">'
27
27
  el += '<span class="fs15">' + title + '</span>'
28
- items.forEach((item, i) => {
29
- el += '<a href="' + escape_html(url_for(item.url)) + '">'
30
- el += escape_html(__(item.title))
28
+ items.forEach((item) => {
29
+ el += '<a href="' + escape_html(url_for(md_link(item))) + '">'
30
+ el += __(md_text(item))
31
31
  el += '</a>'
32
32
  });
33
33
  el += '</div>'
@@ -7,7 +7,9 @@ var postViewModel = ['post', 'topic'].includes(renderViewModel?.collection?.prof
7
7
  var wikiViewModel = renderViewModel?.collection?.profile === 'wiki' ? renderViewModel : null
8
8
  var notebookViewModel = renderViewModel?.collection?.profile === 'notebook' ? renderViewModel : null
9
9
  var pageConfig = content_config(page)
10
- var banner = Object.assign({}, wikiViewModel
10
+ var banner = Object.assign({}, page.author
11
+ ? { image: page.author.banner, avatar: page.author.avatar, tagline: page.author.description }
12
+ : wikiViewModel
11
13
  ? wikiViewModel.render.article.banner
12
14
  : notebookViewModel
13
15
  ? notebookViewModel.render.article.banner
@@ -137,20 +137,24 @@ if (pinItems.length > 0) {
137
137
  }
138
138
  el += '</div>'
139
139
  %>
140
+ <script>document.documentElement.classList.add('stellar-pin-pending');</script>
140
141
  <%- el %>
141
142
  <script>
143
+ let pinSliderCleanup;
144
+ let pinSliderHidden = false;
142
145
  function mountPinSliderWhenReady() {
143
- var cleanup = initPinSlider();
144
- if (typeof cleanup === 'function') {
145
- window.addEventListener('pagehide', cleanup, { once: true });
146
- }
147
- }
148
- if (document.readyState === 'loading') {
149
- document.addEventListener('DOMContentLoaded', mountPinSliderWhenReady, { once: true });
150
- } else {
151
- mountPinSliderWhenReady();
146
+ pinSliderCleanup?.();
147
+ try { pinSliderCleanup = pinSliderHidden ? null : initPinSlider(); }
148
+ finally { document.documentElement.classList.remove('stellar-pin-pending'); }
152
149
  }
150
+ window.addEventListener('pagehide', () => { pinSliderHidden = true; pinSliderCleanup?.(); pinSliderCleanup = null; });
151
+ window.addEventListener('pageshow', event => { pinSliderHidden = false; if (event.persisted) mountPinSliderWhenReady(); });
152
+ if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', mountPinSliderWhenReady, { once: true });
153
+ else mountPinSliderWhenReady();
153
154
  function initPinSlider() {
155
+ let colorTimer;
156
+ var colorController = null;
157
+ var colorRevision = 0;
154
158
  var slider = document.getElementById('pin-slider');
155
159
  if (!slider) return;
156
160
  var track = slider.querySelector('.pin-slider-track');
@@ -209,24 +213,28 @@ function initPinSlider() {
209
213
  // 左右箭头颜色随当前幻灯片封面自适应(contrast:深色背景白箭头、浅色背景深箭头)
210
214
  var navColorRetries = 0;
211
215
  function updateNavColor() {
216
+ var revision = ++colorRevision;
217
+ colorController?.abort();
218
+ colorController = new AbortController();
212
219
  var navs = slider.querySelectorAll('.pin-slider-nav');
213
220
  if (navs.length === 0) return;
214
- if (!window.stellar || !window.stellar.color || !window.resolveAdaptiveBackdrop) {
221
+ if (!window.stellar || !window.stellar.color?.getAverageColor) {
215
222
  // 懒加载的 color.js / 插件尚未就绪时重试
216
223
  if (navColorRetries < 25) {
217
224
  navColorRetries++;
218
- setTimeout(updateNavColor, 200);
225
+ clearTimeout(colorTimer);
226
+ colorTimer = setTimeout(updateNavColor, 200);
219
227
  }
220
228
  return;
221
229
  }
222
230
  var slide = slides[index];
223
231
  if (!slide) return;
224
- var cover = slide.style.getPropertyValue('--pin-cover-url');
225
- if (!cover) return;
226
- var m = cover.match(/url\((['"]?)(.*?)\1\)/i);
227
- if (!m) return;
228
- stellar.color.getAverageColor(m[2], { background: window.resolveAdaptiveBackdrop(slide) }).then(function (rgb) {
229
- if (!rgb) return;
232
+ stellar.color.getAverageColor(slide.querySelector('.pin-slide-bg'), { signal: colorController.signal }).then(function (rgb) {
233
+ if (revision !== colorRevision) return;
234
+ if (!rgb) {
235
+ for (var i = 0; i < navs.length; i++) navs[i].style.removeProperty('--text-banner');
236
+ return;
237
+ }
230
238
  var color = stellar.color.adaptiveTextColor(rgb, { style: 'contrast' });
231
239
  for (var i = 0; i < navs.length; i++) {
232
240
  navs[i].style.setProperty('--text-banner', color);
@@ -278,13 +286,14 @@ function initPinSlider() {
278
286
  next();
279
287
  }
280
288
  }
281
- if (dotsEl) {
282
- dotsEl.addEventListener('click', function(e) {
289
+ const onDotClick = function(e) {
283
290
  var btn = e.target.closest ? e.target.closest('.pin-slider-dot') : null;
284
291
  if (btn) {
285
292
  goTo(parseInt(btn.getAttribute('data-index'), 10) || 0);
286
293
  }
287
- });
294
+ };
295
+ if (dotsEl) {
296
+ dotsEl.addEventListener('click', onDotClick);
288
297
  dotsEl.addEventListener('animationend', onProgressEnd);
289
298
  }
290
299
  var navPrev = slider.querySelector('.pin-slider-nav.prev');
@@ -310,6 +319,9 @@ function initPinSlider() {
310
319
  slider.style.visibility = 'visible';
311
320
  start();
312
321
  return function() {
322
+ colorRevision++;
323
+ colorController?.abort();
324
+ clearTimeout(colorTimer);
313
325
  stop();
314
326
  slider.removeEventListener('mouseenter', stop);
315
327
  slider.removeEventListener('mouseleave', start);
@@ -318,6 +330,7 @@ function initPinSlider() {
318
330
  slider.removeEventListener('touchstart', onTouchStart);
319
331
  slider.removeEventListener('touchend', onTouchEnd);
320
332
  if (dotsEl) {
333
+ dotsEl.removeEventListener('click', onDotClick);
321
334
  dotsEl.removeEventListener('animationend', onProgressEnd);
322
335
  }
323
336
  if (navPrev) {
@@ -1,4 +1,4 @@
1
- <div class="site-dock" role="group" aria-label="Layout panels">
1
+ <div data-stellar-runtime-region class="site-dock" role="group" aria-label="Layout panels">
2
2
  <button type="button" class="<%- ui_classes('site-dock__button site-dock__button--rightbar', 'interactive') %>" aria-label="Open rightbar" aria-controls="rightbar-region" aria-expanded="false" data-shell-action="toggle-rightbar-drawer">
3
3
  <%- icon('default:rightbar', '', true) %>
4
4
  </button>