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

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 (223) hide show
  1. package/CHANGELOG.md +56 -1
  2. package/_config.yml +110 -10
  3. package/languages/en.yml +1 -0
  4. package/languages/zh-CN.yml +1 -0
  5. package/languages/zh-TW.yml +1 -0
  6. package/layout/_partial/comments/beaudar/layout.ejs +1 -1
  7. package/layout/_partial/comments/giscus/layout.ejs +1 -1
  8. package/layout/_partial/comments/utterances/layout.ejs +1 -1
  9. package/layout/_partial/cover/wiki_cover.ejs +2 -1
  10. package/layout/_partial/head.ejs +16 -10
  11. package/layout/_partial/main/article/post_footer.ejs +1 -1
  12. package/layout/_partial/main/article/post_read_next.ejs +4 -1
  13. package/layout/_partial/main/footer.ejs +8 -8
  14. package/layout/_partial/main/listing_nav/blog.ejs +2 -1
  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 +2 -2
  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 +7 -4
  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 +1 -0
  46. package/scripts/helpers/brand.js +0 -5
  47. package/scripts/helpers/collection.js +3 -3
  48. package/scripts/helpers/comments_model.js +2 -2
  49. package/scripts/helpers/extension_assets.js +16 -2
  50. package/scripts/helpers/json_ld.js +5 -4
  51. package/scripts/helpers/md_link.js +7 -0
  52. package/scripts/helpers/page_meta.js +2 -0
  53. package/scripts/helpers/post_view_model.js +15 -12
  54. package/scripts/helpers/script_json.js +3 -0
  55. package/scripts/lib/browser-runtime.js +4 -11
  56. package/scripts/lib/collection-pipeline/adapters/notebook.js +4 -6
  57. package/scripts/lib/collection-pipeline/adapters/post.js +5 -2
  58. package/scripts/lib/collection-pipeline/adapters/topic.js +15 -10
  59. package/scripts/lib/collection-pipeline/index.js +13 -8
  60. package/scripts/lib/comments.js +20 -2
  61. package/scripts/lib/config-schema.js +13 -3
  62. package/scripts/lib/content-config.js +35 -23
  63. package/scripts/lib/contribution-contract.js +8 -16
  64. package/scripts/lib/contribution-registry.js +102 -51
  65. package/scripts/lib/doctor.js +14 -10
  66. package/scripts/lib/hero-effect-registry.js +0 -8
  67. package/scripts/lib/html-images.js +7 -6
  68. package/scripts/lib/image-metadata.js +308 -0
  69. package/scripts/lib/internal-constants.js +3 -29
  70. package/scripts/lib/models/index.js +21 -1537
  71. package/scripts/lib/models/notebook.js +292 -0
  72. package/scripts/lib/models/post.js +72 -0
  73. package/scripts/lib/models/shared.js +571 -0
  74. package/scripts/lib/models/topic.js +201 -0
  75. package/scripts/lib/models/wiki.js +413 -0
  76. package/scripts/lib/page-view-model-registry.js +126 -82
  77. package/scripts/lib/partial-navigation.js +64 -0
  78. package/scripts/lib/resource-assets.js +19 -0
  79. package/scripts/lib/script-json.js +13 -0
  80. package/scripts/lib/source-config.js +26 -16
  81. package/scripts/schema/config-rules.js +21 -15
  82. package/scripts/schema/content-config-rules.js +2 -1
  83. package/scripts/schema/content-config-schema.js +6 -4
  84. package/scripts/schema/model-schema.js +8 -5
  85. package/scripts/tags/lib/albums.js +1 -1
  86. package/scripts/tags/lib/friends.js +1 -1
  87. package/scripts/tags/lib/ghcard.js +1 -1
  88. package/scripts/tags/lib/posters.js +1 -1
  89. package/scripts/tags/lib/sites.js +2 -2
  90. package/source/css/_appearances/_mixins.styl +14 -16
  91. package/source/css/_appearances/minimal.styl +86 -46
  92. package/source/css/_common/button.styl +2 -2
  93. package/source/css/_common/cap.styl +1 -1
  94. package/source/css/_common/highlight.styl +2 -3
  95. package/source/css/_common/html.styl +5 -1
  96. package/source/css/_common/input.styl +1 -1
  97. package/source/css/_common/loading.styl +2 -0
  98. package/source/css/_common/md-link.styl +10 -0
  99. package/source/css/_common/span.styl +1 -1
  100. package/source/css/_common/title.styl +2 -2
  101. package/source/css/_common/toast.styl +1 -1
  102. package/source/css/_components/collection.styl +17 -9
  103. package/source/css/_components/layout.styl +42 -8
  104. package/source/css/_components/list.styl +6 -3
  105. package/source/css/_components/md.styl +1 -2
  106. package/source/css/_components/pages/archives.styl +4 -4
  107. package/source/css/_components/pages/article-story.styl +1 -1
  108. package/source/css/_components/pages/article-tech.styl +2 -2
  109. package/source/css/_components/partial/article-footer.styl +1 -1
  110. package/source/css/_components/partial/article-share.styl +3 -0
  111. package/source/css/_components/partial/bread-nav.styl +2 -2
  112. package/source/css/_components/partial/cover.styl +4 -4
  113. package/source/css/_components/partial/footer.styl +2 -2
  114. package/source/css/_components/partial/paginator.styl +1 -1
  115. package/source/css/_components/partial/post-panel.styl +3 -3
  116. package/source/css/_components/partial/related.styl +14 -3
  117. package/source/css/_components/pin-slider.styl +7 -4
  118. package/source/css/_components/sidebar/brand.styl +3 -3
  119. package/source/css/_components/sidebar/nav-area.styl +1 -1
  120. package/source/css/_components/sidebar/search.styl +44 -21
  121. package/source/css/_components/tag-plugins/banner.styl +1 -1
  122. package/source/css/_components/tag-plugins/chat.styl +2 -2
  123. package/source/css/_components/tag-plugins/copy.styl +1 -1
  124. package/source/css/_components/tag-plugins/emoji.styl +1 -0
  125. package/source/css/_components/tag-plugins/folders.styl +2 -2
  126. package/source/css/_components/tag-plugins/folding.styl +2 -2
  127. package/source/css/_components/tag-plugins/friends.styl +2 -2
  128. package/source/css/_components/tag-plugins/friends_posts.styl +4 -2
  129. package/source/css/_components/tag-plugins/gallery.styl +4 -3
  130. package/source/css/_components/tag-plugins/hashtag.styl +1 -1
  131. package/source/css/_components/tag-plugins/image.styl +2 -0
  132. package/source/css/_components/tag-plugins/inline-labels.styl +2 -2
  133. package/source/css/_components/tag-plugins/link.styl +1 -1
  134. package/source/css/_components/tag-plugins/mark.styl +2 -2
  135. package/source/css/_components/tag-plugins/mbti.styl +6 -4
  136. package/source/css/_components/tag-plugins/mdrender.styl +1 -1
  137. package/source/css/_components/tag-plugins/navbar.styl +1 -1
  138. package/source/css/_components/tag-plugins/note.styl +1 -1
  139. package/source/css/_components/tag-plugins/okr.styl +5 -3
  140. package/source/css/_components/tag-plugins/poetry.styl +2 -2
  141. package/source/css/_components/tag-plugins/quot.styl +4 -2
  142. package/source/css/_components/tag-plugins/rating.styl +2 -2
  143. package/source/css/_components/tag-plugins/read/paper.styl +3 -3
  144. package/source/css/_components/tag-plugins/read/reel.styl +3 -3
  145. package/source/css/_components/tag-plugins/sites.styl +2 -2
  146. package/source/css/_components/tag-plugins/tabs.styl +1 -1
  147. package/source/css/_components/tag-plugins/timeline.styl +6 -6
  148. package/source/css/_components/tag-plugins/toc.styl +2 -2
  149. package/source/css/_components/tag-plugins/vote.styl +2 -2
  150. package/source/css/_components/widgets/ghrepo.styl +1 -1
  151. package/source/css/_components/widgets/ghuser.styl +4 -4
  152. package/source/css/_components/widgets/markdown.styl +3 -0
  153. package/source/css/_components/widgets/settings.styl +2 -2
  154. package/source/css/_components/widgets/toc.styl +24 -3
  155. package/source/css/_components/widgets/widgets.styl +1 -1
  156. package/source/css/_components/wiki-card.styl +3 -3
  157. package/source/css/_custom.styl +2 -1
  158. package/source/css/_defines/func.styl +2 -2
  159. package/source/css/_defines/theme_base.styl +0 -2
  160. package/source/css/_defines/typography.styl +10 -0
  161. package/source/css/_plugins/card-hover.styl +46 -43
  162. package/source/css/_plugins/index.styl +1 -1
  163. package/source/css/comments/artalk.styl +1 -1
  164. package/source/css/comments/twikoo.styl +2 -2
  165. package/source/css/comments/waline.styl +1 -1
  166. package/source/css/plugins/swiper.styl +2 -1
  167. package/source/js/color.js +21 -85
  168. package/source/js/main.js +63 -56
  169. package/source/js/navigation-init.js +58 -0
  170. package/source/js/plugins/adaptive-text.js +51 -25
  171. package/source/js/plugins/card-hover.js +5 -3
  172. package/source/js/plugins/download-file.js +26 -28
  173. package/source/js/plugins/video.js +22 -63
  174. package/source/js/profile.js +2 -0
  175. package/source/js/runtime/asset-loader.js +43 -34
  176. package/source/js/runtime/extension-registry.js +78 -57
  177. package/source/js/runtime/extensions/adaptive-text.js +14 -0
  178. package/source/js/runtime/extensions/card-hover.js +3 -2
  179. package/source/js/runtime/extensions/code-copy.js +19 -0
  180. package/source/js/runtime/extensions/comments.js +4 -3
  181. package/source/js/runtime/extensions/deferred-icons.js +13 -7
  182. package/source/js/runtime/extensions/diagrams.js +20 -0
  183. package/source/js/runtime/extensions/hero-effect.js +7 -3
  184. package/source/js/runtime/extensions/heti.js +12 -0
  185. package/source/js/runtime/extensions/lazy-loading.js +74 -0
  186. package/source/js/runtime/extensions/lightbox.js +28 -0
  187. package/source/js/runtime/extensions/link-prefetch.js +5 -0
  188. package/source/js/runtime/extensions/mathjax.js +24 -0
  189. package/source/js/runtime/extensions/page-controls.js +14 -0
  190. package/source/js/runtime/extensions/partial-navigation.js +172 -0
  191. package/source/js/runtime/extensions/reveal.js +29 -8
  192. package/source/js/runtime/extensions/search.js +4 -1
  193. package/source/js/runtime/extensions/services.js +113 -16
  194. package/source/js/runtime/extensions/settings.js +14 -10
  195. package/source/js/runtime/extensions/swiper.js +22 -0
  196. package/source/js/runtime/image-color.js +211 -0
  197. package/source/js/runtime/index.js +60 -43
  198. package/source/js/runtime/legacy-request-adapter.js +2 -0
  199. package/source/js/runtime/request-cache.js +26 -0
  200. package/source/js/search/algolia-search.js +1 -1
  201. package/source/js/search/highlight.js +6 -9
  202. package/source/js/search/local-search.js +128 -81
  203. package/source/js/services/artalk_latest_comment.js +6 -4
  204. package/source/js/services/contributors.js +6 -3
  205. package/source/js/services/friends.js +7 -4
  206. package/source/js/services/friends_and_posts.js +7 -4
  207. package/source/js/services/ghinfo.js +6 -3
  208. package/source/js/services/giscus_latest_comment.js +6 -3
  209. package/source/js/services/mdrender.js +10 -9
  210. package/source/js/services/memos.js +9 -3
  211. package/source/js/services/rating.js +13 -10
  212. package/source/js/services/rss.js +6 -3
  213. package/source/js/services/siteinfo.js +37 -14
  214. package/source/js/services/sites.js +9 -6
  215. package/source/js/services/timeline.js +6 -3
  216. package/source/js/services/twikoo_latest_comment.js +10 -5
  217. package/source/js/services/vote.js +11 -8
  218. package/source/js/services/waline_latest_comment.js +6 -3
  219. package/source/js/services/weibo.js +6 -3
  220. package/source/js/tagtree.js +7 -7
  221. package/scripts/events/lib/fix_image_tags.js +0 -44
  222. package/scripts/events/lib/get_image_ratios.js +0 -110
  223. package/source/js/runtime/extensions/feature.js +0 -200
package/CHANGELOG.md CHANGED
@@ -1,5 +1,60 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.0.0-rc.4
4
+
5
+ > 发布日期:2026-09-10
6
+
7
+ 本节记录从公开候选 `2.0.0-rc.3` 到 `2.0.0-rc.4` 最终文件树的净变化。
8
+
9
+ ### 修复与改进
10
+
11
+ - 恢复博客列表导航中的专栏入口,使用当前上架专栏索引判断是否显示。
12
+ - 修复移动端专栏文章列表横向溢出,调整 OKR 标签宽度与右对齐;移动端根字号增量由 2px 调整为 1px。
13
+ - 统一集合控件、侧栏菜单与搜索结果字体,修复导航前缀和长标题的布局。
14
+ - minimal 外观下文章、专栏封面与置顶轮播在普通及交互状态均去除边框,保留键盘焦点 outline。
15
+ - Markdown 行内链接的站点信息请求失败时保留原图标,不再显示红色断链图标;数据加载失败时隐藏加载指示器。
16
+ - 将仅用于源码检查的 `glob` 移至开发依赖,并显式声明 ESLint 配置需要的 `@eslint/js` 与 `globals`。
17
+
18
+ ### 升级注意(配置变更与破坏性改动)
19
+
20
+ - 站点 Brand 的 GitHub 数据区改为显式读取 `leftbar.brand.ghuser`,默认 `null` 不显示;不再从 ghuser Widget 的 username 推断。需要保留统计时设置 `leftbar.brand.ghuser: 你的GitHub用户名`。该数据区仍仅在左栏 regular 样式下显示,Collection Brand 的仓库统计保持原有来源。
21
+
22
+ Full Changelog: [2.0.0-rc.3...2.0.0-rc.4](https://github.com/xaoxuu/hexo-theme-stellar/compare/2.0.0-rc.3...2.0.0-rc.4)
23
+
24
+ ## 2.0.0-rc.3
25
+
26
+ > 发布日期:2026-09-10
27
+
28
+ 本节记录从公开候选 `2.0.0-rc.2` 到 `2.0.0-rc.3` 最终文件树的净变化。
29
+
30
+ ### 新功能
31
+
32
+ - 默认启用同集合局部导航:外壳兼容时更新正文、右栏和页面元数据,保留导航区域;支持历史滚动恢复,不兼容页面或请求失败时整页跳转。
33
+ - 图片尺寸与 HSLA 平均色在 server/generate 时自动增量提取并持久缓存,补全生成 HTML,不修改 Markdown 或原图;新增 `hexo stellar images` 及 `--dry-run/--page/--refresh` 选项。
34
+ - Markdown 文本链接、文章参考链接、远程 Markdown 与评论链接支持站点图标增强;站点信息支持 `appicon/favicon`,保留 `icon` 回退,行内请求失败显示断链图标。
35
+ - 新增字体平滑与设计字重映射;卡片 Spotlight 与 Tilt 可独立开关。
36
+ - 第三方 JS/CSS 地址可在对应搜索、评论、Feature 或 Markdown 服务配置中覆盖;Artalk 默认使用服务端配套资源。
37
+
38
+ ### 修复与改进
39
+
40
+ - 共享 Collection 模型并隔离构建缓存,复用 PageViewModel 和归档文章投影,减少重复解析与校验;忽略 Collection 目录中的 macOS `.DS_Store` 文件。
41
+ - 完善 Extension 的页面/文档作用域、异步取消及卸载清理;修复 Flying Pages 初始化、图片懒加载与 Safari 错误占位时序,Reveal 待入场透明度在卸载时恢复。
42
+ - 修复文章上下篇、作者页 Topic 文章与作者横幅;Topic 文章默认继承全局分享配置,Wiki 与 Notebook 仍默认关闭分享。
43
+ - Doctor 与构建统一恢复可用的配置:普通字段问题和不适用的表现参数给出 warning,缺少集合显示名时使用 Collection ID;根结构与归属冲突仍阻止构建。
44
+ - 本地搜索按章节组织结果并分批查询、渲染,改进摘要、高亮、加载更多和结束提示。
45
+ - 调整 minimal 外观、暗色背景、移动导航、品牌、目录吸顶与当前条目滚动;修复 Markdown Widget 背景、稀疏 Wiki 网格宽度、画廊列数以及轮播、图片标签、头像、MBTI 卡片的比例与布局。
46
+ - GitHub 卡片默认服务切换为 `https://github-stats-extended.vercel.app`;图片颜色处理新增 Sharp 直接依赖。
47
+
48
+ ### 升级注意(配置变更与破坏性改动)
49
+
50
+ - 将 `footer.sections` 改为 `footer.sitemap`;分组保留 `title/items`,但 items 中的 `{title, url}` 对象需改写为 `'[标题](地址)'` Markdown 字符串。默认 sitemap 为空数组;默认页脚正文新增 CC BY-NC-SA 4.0 说明,可自行覆盖 `footer.content`。
51
+ - 将 `features.card_hover.enabled` 替换为独立的 `spotlight` 与 `tilt` 布尔值;希望保持原先全部开启效果时两项均设为 `true`,默认均为 `false`。
52
+ - `features.partial_navigation.enabled` 默认开启,含非主题管理可执行脚本的页面使用整页导航;需要全部整页跳转时将其关闭。
53
+ - `features.image_optimization.enabled` 默认开启,首次处理远程图片可能增加构建时间;关闭后仍复用站点 `source/_data/caches/images_metadata.json`。`features.lazy_loading.auto_aspect_ratio` 继续控制尺寸/比例补全。
54
+ - 第三方资源覆盖不保证任意上游 API 版本兼容;KaTeX 自定义 CSS 时需配套更新 `css_integrity`,或设为 `null` 不附加 SRI。仅覆盖 CSS 地址时会清除继承的旧哈希。
55
+
56
+ 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)
57
+
3
58
  ## 2.0.0-rc.2
4
59
 
5
60
  > 发布日期:2026-09-07
@@ -56,7 +111,7 @@ Full Changelog: [2.0.0-rc.1...2.0.0-rc.2](https://github.com/xaoxuu/hexo-theme-s
56
111
  - 浏览器后处理必须原样保留 `public/js/runtime/**/*.js` 的 ESM 语义、相对 import 与 JavaScript MIME 类型。
57
112
  - v2 当前源码从仓库 `main` 安装并需要执行 `npm install --prefix themes/stellar`;npm 包是否为 v2 以实际公开版本为准。
58
113
 
59
- Full Changelog: [1.44.0...main](https://github.com/xaoxuu/hexo-theme-stellar/compare/1.44.0...main)
114
+ Full Changelog: [1.44.0...2.0.0-rc.1](https://github.com/xaoxuu/hexo-theme-stellar/compare/1.44.0...2.0.0-rc.1)
60
115
 
61
116
  ## 1.44.0
62
117
 
package/_config.yml CHANGED
@@ -40,6 +40,8 @@ leftbar:
40
40
  brand:
41
41
  # 设置 Leftbar Brand 的视觉样式;可选值为 regular 或 compact。
42
42
  style: regular
43
+ # 设置站点 Brand 数据区的 GitHub 用户名;留空不显示。
44
+ ghuser: null
43
45
  # 配置品牌图片。
44
46
  image:
45
47
  # 设置品牌图片地址;null 表示隐藏图片。
@@ -128,10 +130,35 @@ rightbar:
128
130
 
129
131
  # 配置主内容区页脚。
130
132
  footer:
131
- # 设置页脚正文,支持 Markdown 与主题模板变量;空字符串表示隐藏正文。
132
- content: 本站由 [{author.name}](/) 使用 [{theme.name} {theme.version}]({theme.tree}) 主题创建。
133
133
  # 设置主内容区页脚导航分栏;空数组表示不显示分栏。
134
- sections: []
134
+ sitemap: []
135
+ # - title: 博客
136
+ # items:
137
+ # - '[近期发布](/)'
138
+ # - '[分类](/blog/categories/)'
139
+ # - '[标签](/blog/tags/)'
140
+ # - '[归档](/blog/archives/)'
141
+ # - title: 项目
142
+ # items:
143
+ # - '[xxx](/)'
144
+ # - '[xxx](/)'
145
+ # - '[xxx](/)'
146
+ # - '[xxx](/)'
147
+ # - title: 社交
148
+ # items:
149
+ # - '[xxx](/)'
150
+ # - '[xxx](/)'
151
+ # - '[xxx](/)'
152
+ # - '[xxx](/)'
153
+ # - title: 关于
154
+ # items:
155
+ # - '[xxx](/)'
156
+ # - '[xxx](/)'
157
+ # - '[xxx](/)'
158
+ # - '[xxx](/)'
159
+ content: | # 支持 Markdown 格式
160
+ 本站由 [{author.name}](/) 使用 [{theme.name} {theme.version}]({theme.tree}) 主题创建。
161
+ 本博客所有文章除特别声明外,均采用 [CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/) 许可协议,转载请注明出处。
135
162
 
136
163
  # 配置各页面与内容 Profile 的专属设置、路由、导航和 Region 默认值;省略字段时继承站点级 Region。
137
164
  profiles:
@@ -457,7 +484,7 @@ article:
457
484
  footer:
458
485
  # 设置文章许可协议;false 表示不显示许可信息。
459
486
  license: 本文采用 [署名-非商业性使用-相同方式共享 4.0 国际](https://creativecommons.org/licenses/by-nc-sa/4.0/) 许可协议,转载请注明出处。
460
- # 设置文章分享服务;普通博客默认全部启用,Collection 内容页默认关闭,可通过 footer.share 显式开启。
487
+ # 设置文章分享服务;普通博客与 Topic 专栏博客默认全部启用,Wiki 与 Notebook 默认关闭,可通过 footer.share 显式开启。
461
488
  # 支持 wechat、weibo、x、telegram、whatsapp、email、link、system;空数组表示不显示分享入口。
462
489
  share:
463
490
  - wechat
@@ -500,6 +527,20 @@ appearance:
500
527
 
501
528
  # 配置全站排版。
502
529
  typography:
530
+ # 设置全站 -webkit-font-smoothing;可选值为 auto、none 或 antialiased。
531
+ font_smoothing: antialiased
532
+ # 将设计字重映射到字体实际提供的字重;例如将 500 改为 600。
533
+ # 映射只执行一次,目标值范围为 1–1000。
534
+ font_weight:
535
+ 100: 100
536
+ 200: 200
537
+ 300: 300
538
+ 400: 400
539
+ 500: 500
540
+ 600: 600
541
+ 700: 700
542
+ 800: 800
543
+ 900: 900
503
544
  # 配置字体族。
504
545
  font_family:
505
546
  # 设置正文的字体候选列表。
@@ -614,6 +655,8 @@ search:
614
655
  cache_ttl_seconds: 86400
615
656
  # 配置 Algolia 搜索参数。
616
657
  algolia:
658
+ # 自定义资源地址;null 使用主题默认资源。
659
+ js: https://gcore.jsdelivr.net/algoliasearch/3/algoliasearch.min.js
617
660
  # 设置 Algolia Application ID。
618
661
  appId: null
619
662
  # 设置 Algolia Search API Key。
@@ -629,6 +672,8 @@ comments:
629
672
  title: null
630
673
  # 配置 Beaudar 参数,字段会传递给 Beaudar 客户端。
631
674
  beaudar:
675
+ # 自定义资源地址;null 使用主题默认资源。
676
+ js: https://beaudar.lipk.org/client.js
632
677
  # 设置关联的 GitHub 仓库,格式为 owner/repo。
633
678
  repo: xxx/xxx
634
679
  # 设置 Issue 映射方式。
@@ -651,6 +696,8 @@ comments:
651
696
  branch: main
652
697
  # 配置 Utterances 参数,字段会传递给 Utterances 客户端。
653
698
  utterances:
699
+ # 自定义资源地址;null 使用主题默认资源。
700
+ js: https://utteranc.es/client.js
654
701
  # 设置关联的 GitHub 仓库,格式为 owner/repo。
655
702
  repo: xxx/xxx
656
703
  # 设置 Issue 映射方式。
@@ -663,6 +710,8 @@ comments:
663
710
  label: null
664
711
  # 配置 Giscus 参数,字段会作为 data 属性传递给 Giscus 客户端。
665
712
  giscus:
713
+ # 自定义资源地址;null 使用主题默认资源。
714
+ js: https://giscus.app/client.js
666
715
  # 设置关联的 GitHub 仓库,格式为 owner/repo。
667
716
  data-repo: xxx/xxx
668
717
  # 设置 Giscus 仓库 ID;null 表示未配置。
@@ -691,10 +740,18 @@ comments:
691
740
  crossorigin: anonymous
692
741
  # 配置 Twikoo 参数,字段会传递给 Twikoo 客户端。
693
742
  twikoo:
743
+ # 自定义资源地址;null 使用主题默认资源。
744
+ js: https://gcore.jsdelivr.net/npm/twikoo@1.6/dist/twikoo.all.min.js
694
745
  # 设置 Twikoo 环境 ID 或服务地址。
695
746
  envId: https://xxx
696
747
  # 配置 Waline 参数,字段会传递给 Waline 客户端。
697
748
  waline:
749
+ # 自定义资源地址;null 使用主题默认资源。
750
+ js: https://gcore.jsdelivr.net/npm/@waline/client@3.15.2/dist/waline.js
751
+ # 自定义资源地址;null 使用主题默认资源。
752
+ css: https://gcore.jsdelivr.net/npm/@waline/client@3.15.2/dist/waline.css
753
+ # 自定义资源地址;null 使用主题默认资源。
754
+ meta_css: https://gcore.jsdelivr.net/npm/@waline/client@3.15.2/dist/waline-meta.css
698
755
  # 设置 Waline 服务端地址。
699
756
  serverURL: https://waline.vercel.app
700
757
  # 控制是否启用评论计数。
@@ -703,6 +760,10 @@ comments:
703
760
  pageview: false
704
761
  # 配置 Artalk 参数,字段会传递给 Artalk 客户端。
705
762
  artalk:
763
+ # 自定义资源地址;null 使用服务端内置的配套资源。
764
+ js: null
765
+ # 自定义资源地址;null 使用服务端内置的配套资源。
766
+ css: null
706
767
  # 设置 Artalk 服务端地址;null 表示未配置。
707
768
  server: null
708
769
  # 设置 Artalk 站点名称;空字符串表示未配置。
@@ -785,24 +846,45 @@ tags:
785
846
 
786
847
  # 配置可选的浏览器功能。
787
848
  features:
849
+ # 同集合内容页面只更新正文和右栏;不兼容的页面自动整页跳转。
850
+ partial_navigation:
851
+ enabled: true
852
+ # 配置轮播使用的第三方资源;不改变按需加载条件。
853
+ swiper:
854
+ # 自定义脚本地址;null 使用默认资源。
855
+ js: https://unpkg.com/swiper@10.3/swiper-bundle.min.js
856
+ # 自定义样式地址;null 使用默认资源。
857
+ css: https://unpkg.com/swiper@10.3/swiper-bundle.min.css
788
858
  # 配置配色模式切换功能。
789
859
  color_scheme_switch:
790
860
  # 控制是否启用配色模式切换。
791
861
  enabled: false
862
+ # 自动优化图片体验:增量提取尺寸与平均色,不压缩或替换原图。
863
+ image_optimization:
864
+ # server/generate 自动补齐缺失元数据;关闭后仍复用已有结果,手动 images 命令可用。
865
+ enabled: true
792
866
  # 配置图片懒加载。
793
867
  lazy_loading:
868
+ # 自定义资源地址;null 使用主题默认资源。
869
+ js: https://gcore.jsdelivr.net/npm/vanilla-lazyload@19.1/dist/lazyload.min.js
794
870
  # 设置懒加载过渡效果;可选值为 blur 或 fade。
795
871
  transition: fade
796
- # 控制是否自动补全图片宽高比。
872
+ # 从站点图片元数据补全尺寸与比例;server/generate 自动增量预处理,不修改 Markdown。
797
873
  auto_aspect_ratio: true
798
874
  # 配置图片灯箱。
799
875
  lightbox:
876
+ # 自定义资源地址;null 使用主题默认资源。
877
+ js: https://gcore.jsdelivr.net/npm/@fancyapps/ui@5.0/dist/fancybox/fancybox.umd.js
878
+ # 自定义资源地址;null 使用主题默认资源。
879
+ css: https://gcore.jsdelivr.net/npm/@fancyapps/ui@5.0/dist/fancybox/fancybox.css
800
880
  # 控制是否启用图片灯箱。
801
881
  enabled: true
802
882
  # 设置灯箱匹配图片的 CSS 选择器。
803
883
  selector: '.timenode p>img'
804
884
  # 配置链接预取。
805
885
  link_prefetch:
886
+ # 自定义资源地址;null 使用主题默认资源。
887
+ js: https://gcore.jsdelivr.net/npm/flying-pages@2/flying-pages.min.js
806
888
  # 控制是否启用链接预取。
807
889
  enabled: true
808
890
  # 配置滚动揭示动画。
@@ -811,10 +893,16 @@ features:
811
893
  enabled: true
812
894
  # 配置卡片悬停效果。
813
895
  card_hover:
814
- # 控制是否启用卡片悬停效果。
815
- enabled: false
896
+ # 控制是否启用鼠标跟随光照。
897
+ spotlight: false
898
+ # 控制是否启用 3D 倾斜。
899
+ tilt: false
816
900
  # 配置 Heti 中文排版增强。
817
901
  heti:
902
+ # 自定义资源地址;null 使用主题默认资源。
903
+ js: https://unpkg.com/heti@0.9/umd/heti-addon.min.js
904
+ # 自定义资源地址;null 使用主题默认资源。
905
+ css: https://unpkg.com/heti@0.9/umd/heti.min.css
818
906
  # 控制是否启用 Heti。
819
907
  enabled: false
820
908
  # 配置数学公式渲染。
@@ -822,15 +910,23 @@ features:
822
910
  # 设置数学公式 Provider;可选值为 katex、mathjax 或 null。
823
911
  provider: null
824
912
  # 设置 KaTeX 参数;空对象表示使用 Provider 默认参数。
825
- katex: {}
913
+ katex:
914
+ # 自定义资源地址;null 使用主题默认资源。
915
+ css: https://cdn.jsdelivr.net/npm/katex@0.16.23/dist/katex.min.css
916
+ # CSS 的配套完整性哈希;null 不附加 SRI,自定义 CSS 时请同时提供匹配哈希。
917
+ css_integrity: sha384-//SZkxyB7axjCAopkAL1E1rve+ZSPKapD89Lo/lLhcsXR+zOYl5z6zJZEFXil+q0
826
918
  # 设置 MathJax 参数;空对象表示使用 Provider 默认参数。
827
- mathjax: {}
919
+ mathjax:
920
+ # 自定义资源地址;null 使用主题默认资源。
921
+ js: https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.2.2/es5/tex-mml-chtml.min.js
828
922
  # 配置图表渲染。
829
923
  diagrams:
830
924
  # 设置图表 Provider;可选值为 mermaid 或 null。
831
925
  provider: null
832
926
  # 配置 Mermaid 参数。
833
927
  mermaid:
928
+ # 自定义资源地址;null 使用主题默认资源。
929
+ js: https://gcore.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js
834
930
  # 设置 Mermaid 主题;可选值为 default、dark、forest 或 neutral。
835
931
  theme: neutral
836
932
 
@@ -840,6 +936,10 @@ features:
840
936
 
841
937
  # 配置主题使用的数据服务。
842
938
  services:
939
+ # 配置所有动态 Markdown 内容共享的 Marked 客户端。
940
+ markdown:
941
+ # 自定义脚本地址;null 使用默认资源。
942
+ js: https://gcore.jsdelivr.net/npm/marked@13.0/lib/marked.umd.min.js
843
943
  # 配置站点信息服务。
844
944
  site_info:
845
945
  # 设置站点信息 Provider;可选值为 site_info_api 或 null。
@@ -879,7 +979,7 @@ services:
879
979
  # 配置 github_readme_stats Provider。
880
980
  github_readme_stats:
881
981
  # 设置 GitHub 卡片接口地址。
882
- endpoint: https://github-readme-stats.vercel.app
982
+ endpoint: https://github-stats-extended.vercel.app
883
983
  # 配置 GitHub 基础服务地址。
884
984
  github:
885
985
  # 设置 GitHub API 地址。
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>'
@@ -41,7 +41,8 @@ function layoutDiv() {
41
41
  }
42
42
  }
43
43
 
44
- if (stellar_data('topic')?.publish_list?.length > 0) {
44
+ var topicItems = stellar_data('topicIndex.items');
45
+ if (Array.isArray(topicItems) && topicItems.length > 0) {
45
46
  if (page.layout == 'index_topic') {
46
47
  el += '<a class="active" href="' + pretty_url(stellar_config('profiles.topic.path')) + '">' + __("btn.topic") + '</a>';
47
48
  } else {
@@ -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) {