hexo-theme-stellar 1.31.0 → 1.32.0
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.
- package/_config.yml +14 -12
- package/_data/icons.yml +3 -3
- package/layout/_partial/comments/artalk/script.ejs +1 -2
- package/layout/_partial/comments/layout.ejs +1 -1
- package/layout/_partial/head.ejs +15 -3
- package/layout/_partial/scripts/theme.ejs +3 -3
- package/layout/_partial/sidebar/index_leftbar.ejs +9 -9
- package/layout/index.ejs +3 -1
- package/layout/layout.ejs +3 -2
- package/package.json +4 -2
- package/scripts/events/index.js +39 -2
- package/scripts/events/lib/fix_image_tags.js +44 -0
- package/scripts/events/lib/get_image_ratios.js +88 -0
- package/scripts/events/lib/version-check.js +2 -0
- package/scripts/helpers/json_ld.js +5 -1
- package/scripts/tags/lib/image.js +16 -6
- package/scripts/tags/lib/timeline.js +1 -1
- package/scripts/tags/lib/video.js +2 -2
- package/source/css/_common/base.styl +1 -2
- package/source/css/_common/canonical.styl +1 -1
- package/source/css/_common/highlight.styl +1 -1
- package/source/css/_components/layout.styl +11 -10
- package/source/css/_components/list.styl +3 -0
- package/source/css/_components/main.styl +1 -1
- package/source/css/_components/md.styl +4 -2
- package/source/css/_components/pages/archives.styl +2 -2
- package/source/css/_components/pages/article-story.styl +6 -0
- package/source/css/_components/pages/article-tech.styl +1 -1
- package/source/css/_components/pages/notebook.styl +1 -1
- package/source/css/_components/partial/article-banner.styl +4 -1
- package/source/css/_components/partial/footer.styl +1 -1
- package/source/css/_components/partial/navbar.styl +2 -1
- package/source/css/_components/sidebar/nav-area.styl +1 -1
- package/source/css/_components/sidebar/search.styl +44 -21
- package/source/css/_components/sidebar/sidebar.styl +9 -5
- package/source/css/_components/tag-plugins/banner.styl +1 -1
- package/source/css/_components/tag-plugins/button.styl +3 -4
- package/source/css/_components/tag-plugins/copy.styl +1 -1
- package/source/css/_components/tag-plugins/friends.styl +1 -1
- package/source/css/_components/tag-plugins/gallery.styl +6 -0
- package/source/css/_components/tag-plugins/image.styl +10 -0
- package/source/css/_components/tag-plugins/note.styl +1 -1
- package/source/css/_components/tag-plugins/override.styl +1 -1
- package/source/css/_components/tag-plugins/quot.styl +2 -2
- package/source/css/_components/tag-plugins/tabs.styl +4 -3
- package/source/css/_components/tag-plugins/timeline.styl +2 -2
- package/source/css/_components/tag-plugins/toc.styl +1 -1
- package/source/css/_components/widgets/markdown.styl +0 -7
- package/source/css/_components/widgets/toc.styl +6 -4
- package/source/css/_components/widgets/widgets.styl +0 -5
- package/source/css/_custom.styl +5 -7
- package/source/css/_defines/const.styl +1 -1
- package/source/css/_defines/func.styl +9 -5
- package/source/css/_defines/theme.styl +4 -15
- package/source/css/_plugins/comments/artalk.styl +114 -2
- package/source/css/_plugins/comments/twikoo.styl +3 -3
- package/source/css/_plugins/index.styl +5 -5
- package/source/css/_plugins/lazyload.styl +49 -2
- package/source/js/search/local-search.js +163 -151
- package/source/js/services/artalk_latest_comment.js +1 -1
- package/layout/_partial/widgets/search.ejs +0 -0
package/_config.yml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
######## Stellar info ########
|
|
2
2
|
stellar:
|
|
3
|
-
version: '1.
|
|
3
|
+
version: '1.32.0'
|
|
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
|
|
@@ -180,8 +180,6 @@ article:
|
|
|
180
180
|
type: tech # tech: 默认技术类文章, story: 图文类文章,文字和段落间增距大
|
|
181
181
|
# 缩进两个文字宽度,适合文字类博客,可以在 front-matter/topic/wiki 中覆盖此参数
|
|
182
182
|
indent: # true / false
|
|
183
|
-
# 如果没有指定封面,是否根据 tags 作为关键词搜索封面图片?
|
|
184
|
-
auto_cover: false # search from https://source.unsplash.com/
|
|
185
183
|
# 封面图宽高比
|
|
186
184
|
cover_ratio: 2
|
|
187
185
|
# 文章内横幅宽高比
|
|
@@ -222,6 +220,7 @@ comments:
|
|
|
222
220
|
service: # beaudar, utterances, giscus, twikoo, waline, artalk
|
|
223
221
|
comment_title: 快来参与讨论吧~
|
|
224
222
|
lazyload: false # true / false
|
|
223
|
+
custom_css: # artalk,twikoo,... 可以为没有全局启用的评论加载自定义样式
|
|
225
224
|
# beaudar
|
|
226
225
|
# https://beaudar.lipk.org/
|
|
227
226
|
beaudar:
|
|
@@ -312,10 +311,10 @@ comments:
|
|
|
312
311
|
# Artalk
|
|
313
312
|
# https://artalk.js.org/
|
|
314
313
|
artalk:
|
|
315
|
-
css: https://unpkg.com/artalk@2.
|
|
316
|
-
js: https://unpkg.com/artalk@2.
|
|
314
|
+
css: https://unpkg.com/artalk@2.9/dist/Artalk.css
|
|
315
|
+
js: https://unpkg.com/artalk@2.9/dist/Artalk.js
|
|
317
316
|
server: # 后端服务地址
|
|
318
|
-
|
|
317
|
+
site: '' # 站点名称
|
|
319
318
|
darkMode: auto
|
|
320
319
|
|
|
321
320
|
|
|
@@ -334,9 +333,6 @@ footer:
|
|
|
334
333
|
# comments:
|
|
335
334
|
# icon: '<img src="https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.12/social/942ebbf1a4b91.svg"/>'
|
|
336
335
|
# url: /about/#comments
|
|
337
|
-
# theme:
|
|
338
|
-
# icon: default:theme
|
|
339
|
-
# onclick: 'switchTheme()'
|
|
340
336
|
sitemap:
|
|
341
337
|
# '博客':
|
|
342
338
|
# - '[近期](/)'
|
|
@@ -488,7 +484,7 @@ data_services:
|
|
|
488
484
|
|
|
489
485
|
|
|
490
486
|
# 扩展插件接入方法:(插件名下面用 #plugin# 代替)
|
|
491
|
-
# 1. 在这里增加 #plugin#
|
|
487
|
+
# 1. 在这里增加 #plugin# 配置,至少应含有 enable 字段,默认为空(不启用)
|
|
492
488
|
# 2. 新建文件 layout/_plugins/#plugin#.ejs 文件中设置编写加载代码。
|
|
493
489
|
# 2.1. 在该文件中可以直接使用 conf 来读取用户在【步骤 1】填写的配置字段内容
|
|
494
490
|
# 2.2. 如果需要引入 css 或 js,可以使用 utils.css(xxx)、utils.js(xxx),具体可参考 layout/_plugins/fancybox.ejs
|
|
@@ -508,6 +504,10 @@ plugins:
|
|
|
508
504
|
enable: true # [hexo clean && hexo s] is required after changing this value.
|
|
509
505
|
js: https://gcore.jsdelivr.net/npm/vanilla-lazyload@19.1/dist/lazyload.min.js
|
|
510
506
|
transition: fade # blur, fade
|
|
507
|
+
fix_ratio: true # true / false # 是否固定宽高比,true 时会在图片上添加 style="aspect-ratio: 16/9;",false 时则不添加,开启此功能会导致增加首次 hexo s 的耗时
|
|
508
|
+
loading_image:
|
|
509
|
+
src: # https://github.githubassets.com/images/mona-loading-dark.gif
|
|
510
|
+
size: 2rem # 图片宽度
|
|
511
511
|
|
|
512
512
|
# https://fancyapps.com/docs/ui/fancybox/
|
|
513
513
|
# available for {% image xxx %}
|
|
@@ -627,7 +627,9 @@ style:
|
|
|
627
627
|
card: 16px # 文章内大部分卡片的圆角
|
|
628
628
|
card-s: 12px # 文章内小型卡片的圆角
|
|
629
629
|
bar: 8px # 横条类元素的圆角
|
|
630
|
-
image:
|
|
630
|
+
image-l: 24px # 非技术类文章插图圆角
|
|
631
|
+
image: 16px # 技术类文章插图圆角
|
|
632
|
+
image-s: 8px # 评论区图片圆角(部分评论支持)
|
|
631
633
|
color:
|
|
632
634
|
# 动态颜色(会根据明暗主题重设明度值,只用关心色相和饱和度即可)
|
|
633
635
|
background: 'hsl(212 16% 98%)' # 浅色背景颜色
|
|
@@ -680,7 +682,7 @@ default:
|
|
|
680
682
|
project: https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.12/image/2779789.png
|
|
681
683
|
banner: https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.12/banner/books.jpg
|
|
682
684
|
topic: https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.12/image/10433048.png
|
|
683
|
-
|
|
685
|
+
image_onerror: "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1em' height='1em' viewBox='0 0 24 24'%3E%3C!-- Icon from Solar by 480 Design - https://creativecommons.org/licenses/by/4.0/ --%3E%3Cpath fill='%23F44336' d='M22 12.698c-.002 1.47-.013 2.718-.096 3.743c-.097 1.19-.296 2.184-.74 3.009a4.2 4.2 0 0 1-.73.983c-.833.833-1.893 1.21-3.237 1.39C15.884 22 14.2 22 12.053 22h-.106c-2.148 0-3.83 0-5.144-.177c-1.343-.18-2.404-.557-3.236-1.39c-.738-.738-1.12-1.656-1.322-2.795c-.2-1.12-.236-2.512-.243-4.241Q1.999 12.737 2 12v-.054c0-2.148 0-3.83.177-5.144c.18-1.343.557-2.404 1.39-3.236s1.893-1.21 3.236-1.39c1.168-.157 2.67-.175 4.499-.177a.697.697 0 1 1 0 1.396c-1.855.002-3.234.018-4.313.163c-1.189.16-1.906.464-2.436.994S3.72 5.8 3.56 6.99C3.397 8.2 3.395 9.788 3.395 12v.784l.932-.814a2.14 2.14 0 0 1 2.922.097l3.99 3.99a1.86 1.86 0 0 0 2.385.207l.278-.195a2.79 2.79 0 0 1 3.471.209l2.633 2.37c.265-.557.423-1.288.507-2.32c.079-.972.09-2.152.091-3.63a.698.698 0 0 1 1.396 0' opacity='.5'/%3E%3Cpath fill='%23F44336' fill-rule='evenodd' d='M17.5 11c-2.121 0-3.182 0-3.841-.659S13 8.621 13 6.5s0-3.182.659-3.841S15.379 2 17.5 2s3.182 0 3.841.659S22 4.379 22 6.5s0 3.182-.659 3.841S19.621 11 17.5 11m-1.47-7.03a.75.75 0 1 0-1.06 1.06l1.47 1.47l-1.47 1.47a.75.75 0 0 0 1.06 1.06l1.47-1.47l1.47 1.47a.75.75 0 1 0 1.06-1.06L18.56 6.5l1.47-1.47a.75.75 0 0 0-1.06-1.06L17.5 5.44z' clip-rule='evenodd'/%3E%3C/svg%3E"
|
|
684
686
|
|
|
685
687
|
api_host:
|
|
686
688
|
ghapi: api.github.com
|
package/_data/icons.yml
CHANGED
|
@@ -30,9 +30,9 @@ default:calendar: <svg style="margin-bottom:2px" xmlns="http://www.w3.org/2000/s
|
|
|
30
30
|
default:category: <svg style="margin-bottom:1px" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="M2 6.95c0-.883 0-1.324.07-1.692A4 4 0 0 1 5.257 2.07C5.626 2 6.068 2 6.95 2c.386 0 .58 0 .766.017a4 4 0 0 1 2.18.904c.144.119.28.255.554.529L11 4c.816.816 1.224 1.224 1.712 1.495a4 4 0 0 0 .848.352C14.098 6 14.675 6 15.828 6h.374c2.632 0 3.949 0 4.804.77c.079.07.154.145.224.224c.77.855.77 2.172.77 4.804V14c0 3.771 0 5.657-1.172 6.828C19.657 22 17.771 22 14 22h-4c-3.771 0-5.657 0-6.828-1.172C2 19.657 2 17.771 2 14z" opacity=".5"/><path fill="currentColor" d="M20 6.238c0-.298-.005-.475-.025-.63a3 3 0 0 0-2.583-2.582C17.197 3 16.965 3 16.5 3H9.988c.116.104.247.234.462.45L11 4c.816.816 1.224 1.224 1.712 1.495a4 4 0 0 0 .849.352C14.098 6 14.675 6 15.829 6h.373c1.78 0 2.957 0 3.798.238"/><path fill="currentColor" fill-rule="evenodd" d="M12.25 10a.75.75 0 0 1 .75-.75h5a.75.75 0 0 1 0 1.5h-5a.75.75 0 0 1-.75-.75" clip-rule="evenodd"/></svg>
|
|
31
31
|
|
|
32
32
|
# 编辑本文
|
|
33
|
-
default:edit: <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><path
|
|
34
|
-
default:upup: <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"
|
|
35
|
-
default:tocomment: <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"
|
|
33
|
+
default:edit: <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"><path stroke="currentColor" stroke-linecap="round" stroke-width="1.5" d="m16.652 3.455l.649-.649A2.753 2.753 0 0 1 21.194 6.7l-.65.649m-3.892-3.893s.081 1.379 1.298 2.595c1.216 1.217 2.595 1.298 2.595 1.298m-3.893-3.893L10.687 9.42c-.404.404-.606.606-.78.829q-.308.395-.524.848c-.121.255-.211.526-.392 1.068L8.412 13.9m12.133-6.552l-2.983 2.982m-2.982 2.983c-.404.404-.606.606-.829.78a4.6 4.6 0 0 1-.848.524c-.255.121-.526.211-1.068.392l-1.735.579m0 0l-1.123.374a.742.742 0 0 1-.939-.94l.374-1.122m1.688 1.688L8.412 13.9"/><path fill="currentColor" d="M22.75 12a.75.75 0 0 0-1.5 0zM12 2.75a.75.75 0 0 0 0-1.5zM7.376 20.013a.75.75 0 1 0-.752 1.298zm-4.687-2.638a.75.75 0 1 0 1.298-.75zM21.25 12A9.25 9.25 0 0 1 12 21.25v1.5c5.937 0 10.75-4.813 10.75-10.75zM12 1.25C6.063 1.25 1.25 6.063 1.25 12h1.5A9.25 9.25 0 0 1 12 2.75zM6.624 21.311A10.7 10.7 0 0 0 12 22.75v-1.5a9.2 9.2 0 0 1-4.624-1.237zM1.25 12a10.7 10.7 0 0 0 1.439 5.375l1.298-.75A9.2 9.2 0 0 1 2.75 12z"/></g></svg>
|
|
34
|
+
default:upup: <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 stroke-linejoin="round" d="m9 15.5l3-3l3 3m-6-4l3-3l3 3"/><path d="M7 3.338A9.95 9.95 0 0 1 12 2c5.523 0 10 4.477 10 10s-4.477 10-10 10S2 17.523 2 12c0-1.821.487-3.53 1.338-5"/></g></svg>
|
|
35
|
+
default:tocomment: <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="none" stroke="currentColor" stroke-linecap="round" stroke-width="1.5" d="M8 10.5h8M8 14h5.5M17 3.338A9.95 9.95 0 0 0 12 2C6.477 2 2 6.477 2 12c0 1.6.376 3.112 1.043 4.453c.178.356.237.763.134 1.148l-.595 2.226a1.3 1.3 0 0 0 1.591 1.592l2.226-.596a1.63 1.63 0 0 1 1.149.133A9.96 9.96 0 0 0 12 22c5.523 0 10-4.477 10-10c0-1.821-.487-3.53-1.338-5"/></svg>
|
|
36
36
|
default:theme: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path fill="currentColor" fill-rule="evenodd" d="M582.4 326.4c-140.8 0-256 115.2-256 256s115.2 256 256 256 256-115.2 256-256-115.2-256-256-256z m0 448c-70.4 0-131.2-36.8-164.8-92.8 12.8 3.2 27.2 4.8 40 4.8 121.6 0 219.2-99.2 219.2-219.2 0-17.6-1.6-35.2-6.4-52.8 60.8 32 102.4 96 102.4 169.6 1.6 104-84.8 190.4-190.4 190.4zM582.4 262.4c17.6 0 32-14.4 32-32v-128c0-17.6-14.4-32-32-32s-32 14.4-32 32v128c0 17.6 14.4 32 32 32zM262.4 582.4c0-17.6-14.4-32-32-32h-128c-17.6 0-32 14.4-32 32s14.4 32 32 32h128c17.6 0 32-14.4 32-32zM310.4 356.8c6.4 6.4 14.4 9.6 22.4 9.6 8 0 16-3.2 22.4-9.6 12.8-12.8 12.8-32 0-44.8l-91.2-91.2c-12.8-12.8-32-12.8-44.8 0-12.8 12.8-12.8 32 0 44.8l91.2 91.2zM944 220.8c-12.8-12.8-32-12.8-44.8 0l-91.2 91.2c-12.8 12.8-12.8 32 0 44.8 6.4 6.4 14.4 9.6 22.4 9.6 8 0 16-3.2 22.4-9.6l91.2-91.2c12.8-12.8 12.8-33.6 0-44.8zM310.4 808l-91.2 91.2c-12.8 12.8-12.8 32 0 44.8 6.4 6.4 14.4 9.6 22.4 9.6 8 0 16-3.2 22.4-9.6l91.2-91.2c12.8-12.8 12.8-32 0-44.8-11.2-11.2-32-11.2-44.8 0z"></path></svg>
|
|
37
37
|
|
|
38
38
|
github:logo: <svg aria-hidden="true" role="img" class="color-icon-primary" viewBox="0 0 16 16" width="1em" height="1em" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible"><path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"></path></svg>
|
|
@@ -12,8 +12,7 @@
|
|
|
12
12
|
pageKey: path,
|
|
13
13
|
pageTitle: '<%= page.title %>',
|
|
14
14
|
server: '<%= theme.comments.artalk.server %>',
|
|
15
|
-
|
|
16
|
-
site: "<%- config.title %>",
|
|
15
|
+
site: '<%= theme.comments.artalk.site %>',
|
|
17
16
|
darkMode: '<%= theme.comments.artalk.darkMode %>'
|
|
18
17
|
});
|
|
19
18
|
});
|
package/layout/_partial/head.ejs
CHANGED
|
@@ -92,11 +92,25 @@ function custom_inject() {
|
|
|
92
92
|
return el;
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
+
function generate_canonical() {
|
|
96
|
+
const originalHost = theme.canonical.originalHost || '';
|
|
97
|
+
if (originalHost.length > 0) {
|
|
98
|
+
if (is_home()) {
|
|
99
|
+
return `<link rel="canonical" href="https://${originalHost}/">`;
|
|
100
|
+
} else if (page.path?.length > 0) {
|
|
101
|
+
const path = page.path.replace(/index\.html$/, '') || '/';
|
|
102
|
+
return `<link rel="canonical" href="https://${originalHost}/${path}">`;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return '';
|
|
106
|
+
}
|
|
107
|
+
|
|
95
108
|
%>
|
|
96
109
|
|
|
97
110
|
<head>
|
|
98
111
|
<meta charset="utf-8">
|
|
99
112
|
<meta name="hexo-theme" content="<%- stellar_info('tree') %>" theme-name="<%- stellar_info('name') %>" theme-version="<%- stellar_info('version') %>">
|
|
113
|
+
<%- generate_canonical() %>
|
|
100
114
|
<%- generate_robots() %>
|
|
101
115
|
<%- meta_generator() %>
|
|
102
116
|
<meta http-equiv='x-dns-prefetch-control' content='on' />
|
|
@@ -109,9 +123,6 @@ function custom_inject() {
|
|
|
109
123
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
|
110
124
|
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="#000">
|
|
111
125
|
<meta name="theme-color" content="#f9fafb">
|
|
112
|
-
<% if (theme.canonical.originalHost) { %>
|
|
113
|
-
<link rel="canonical" href="https://<%= theme.canonical.originalHost + "/" + page.path %>">
|
|
114
|
-
<% } %>
|
|
115
126
|
<title><%- generate_title() %></title>
|
|
116
127
|
|
|
117
128
|
<% if (theme.open_graph && theme.open_graph.enable) { %>
|
|
@@ -137,5 +148,6 @@ function custom_inject() {
|
|
|
137
148
|
<%- css(theme.style.codeblock.highlightjs_theme) %>
|
|
138
149
|
<% } %>
|
|
139
150
|
|
|
151
|
+
<%- json_ld() %>
|
|
140
152
|
<%- custom_inject() %>
|
|
141
153
|
</head>
|
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
document.documentElement.setAttribute('data-theme', theme)
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
applyThemeToGiscus(theme)
|
|
9
|
+
// applyThemeToGiscus(theme)
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
// FIXME: 这会导致无法使用 preferred_color_scheme 以外的主题
|
|
12
13
|
const applyThemeToGiscus = (theme) => {
|
|
13
|
-
theme = theme === 'auto' ? 'preferred_color_scheme' : theme
|
|
14
|
-
|
|
14
|
+
// theme = theme === 'auto' ? 'preferred_color_scheme' : theme
|
|
15
15
|
const cmt = document.getElementById('giscus')
|
|
16
16
|
if (cmt) {
|
|
17
17
|
// This works before giscus load.
|
|
@@ -79,6 +79,15 @@ function layoutWidgets() {
|
|
|
79
79
|
var el = '';
|
|
80
80
|
el += '<div class="widgets">';
|
|
81
81
|
if (page.leftbar) {
|
|
82
|
+
var search = {}
|
|
83
|
+
if (page.search) {
|
|
84
|
+
search = page.search
|
|
85
|
+
} else if (wiki?.search) {
|
|
86
|
+
search = wiki.search
|
|
87
|
+
} else if (topic?.search) {
|
|
88
|
+
search = topic.search
|
|
89
|
+
}
|
|
90
|
+
el += partial('search', {item: search})
|
|
82
91
|
page.leftbar.forEach((w, i) => {
|
|
83
92
|
let name = ''
|
|
84
93
|
let widget = {}
|
|
@@ -141,17 +150,8 @@ function layoutLogo() {
|
|
|
141
150
|
}
|
|
142
151
|
|
|
143
152
|
function layoutNavArea() {
|
|
144
|
-
var search = {}
|
|
145
|
-
if (page.search) {
|
|
146
|
-
search = page.search
|
|
147
|
-
} else if (wiki?.search) {
|
|
148
|
-
search = wiki.search
|
|
149
|
-
} else if (topic?.search) {
|
|
150
|
-
search = topic.search
|
|
151
|
-
}
|
|
152
153
|
var el = ''
|
|
153
154
|
el += `<div class="nav-area">`
|
|
154
|
-
el += partial('search', {item: search})
|
|
155
155
|
el += partial('menu', {where: 'sidebar'})
|
|
156
156
|
el += `</div>`
|
|
157
157
|
return el
|
package/layout/index.ejs
CHANGED
|
@@ -22,7 +22,9 @@ function layout_post_list(partial) {
|
|
|
22
22
|
var el = '';
|
|
23
23
|
el += '<div class="post-list post">';
|
|
24
24
|
page.posts.each(function(post){
|
|
25
|
-
|
|
25
|
+
if (post.indexing != false) {
|
|
26
|
+
el += layout_post_card('post', post, partial(post));
|
|
27
|
+
}
|
|
26
28
|
})
|
|
27
29
|
el += '</div>';
|
|
28
30
|
return el;
|
package/layout/layout.ejs
CHANGED
|
@@ -8,7 +8,9 @@ if (['post', 'page', 'wiki', null].includes(page.layout)) {
|
|
|
8
8
|
}
|
|
9
9
|
// 文章类型:技术类文章/文学类文章
|
|
10
10
|
var article_type = theme.article.type
|
|
11
|
-
if (
|
|
11
|
+
if (page_type == 'index') {
|
|
12
|
+
article_type = undefined
|
|
13
|
+
} else if (page.type?.length > 0) {
|
|
12
14
|
article_type = page.type
|
|
13
15
|
} else if (theme.topic.tree[page.topic]?.type != null) {
|
|
14
16
|
article_type = theme.topic.tree[page.topic]?.type
|
|
@@ -65,7 +67,6 @@ if (theme.style.prefers_theme === 'auto') {
|
|
|
65
67
|
html += partial('_partial/menubtn')
|
|
66
68
|
html += `</div>`
|
|
67
69
|
html += `<div class="scripts">`
|
|
68
|
-
html += json_ld()
|
|
69
70
|
html += partial('_partial/scripts')
|
|
70
71
|
html += `</div>`
|
|
71
72
|
html += `</body>`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hexo-theme-stellar",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.32.0",
|
|
4
4
|
"description": "Elegant and powerful theme for Hexo.",
|
|
5
5
|
"main": "package.json",
|
|
6
6
|
"scripts": {
|
|
@@ -21,8 +21,10 @@
|
|
|
21
21
|
"url": "https://github.com/xaoxuu/hexo-theme-stellar/issues/"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
+
"cheerio": "^1.1.0",
|
|
24
25
|
"hexo-renderer-ejs": "^2.0.0",
|
|
25
|
-
"hexo-renderer-stylus": "^3.0.1"
|
|
26
|
+
"hexo-renderer-stylus": "^3.0.1",
|
|
27
|
+
"probe-image-size": "^7.2.3"
|
|
26
28
|
},
|
|
27
29
|
"homepage": "https://xaoxuu.com/wiki/stellar/",
|
|
28
30
|
"devDependencies": {
|
package/scripts/events/index.js
CHANGED
|
@@ -20,12 +20,49 @@ hexo.on('generateAfter', () => {
|
|
|
20
20
|
hexo.on('ready', () => {
|
|
21
21
|
if (process.env.HEXO_READY === '1') return;
|
|
22
22
|
process.env.HEXO_READY = '1';
|
|
23
|
+
const isClean = ['cl', 'clean'].some(arg => process.argv.includes(arg));
|
|
24
|
+
if (isClean) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
23
27
|
const { version, homepage, repository } = require('../../package.json');
|
|
28
|
+
console.log(``);
|
|
29
|
+
|
|
30
|
+
const line = '------------------------------------------------';
|
|
31
|
+
hexo.log.info(line);
|
|
24
32
|
hexo.log.info(`Welcome to \x1b[33mStellar ${version}\x1b[0m
|
|
25
33
|
\x1b[32mDOCS\x1b[0m ${homepage}
|
|
26
|
-
\x1b[32mREPO\x1b[0m ${repository.url}
|
|
27
|
-
|
|
34
|
+
\x1b[32mREPO\x1b[0m ${repository.url}`);
|
|
35
|
+
hexo.log.info(line);
|
|
36
|
+
console.log(``);
|
|
28
37
|
// version check
|
|
29
38
|
const checkVersion = require('./lib/version-check');
|
|
30
39
|
checkVersion(hexo, { useCache: true });
|
|
31
40
|
});
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
// 防止重复注册
|
|
44
|
+
let hasRun = false;
|
|
45
|
+
|
|
46
|
+
hexo.extend.filter.register('before_generate', async () => {
|
|
47
|
+
const isDev = ['s', 'server', 'serve'].some(arg => process.argv.includes(arg));
|
|
48
|
+
if (!isDev) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (hasRun) return;
|
|
53
|
+
hasRun = true;
|
|
54
|
+
|
|
55
|
+
// 读取主题配置开关
|
|
56
|
+
const enabled = hexo.theme.config.plugins?.lazyload?.fix_ratio === true;
|
|
57
|
+
|
|
58
|
+
const generateImageRatios = require('./lib/get_image_ratios');
|
|
59
|
+
const fixMarkdownImages = require('./lib/fix_image_tags');
|
|
60
|
+
|
|
61
|
+
if (enabled) {
|
|
62
|
+
// 构建前:生成缓存 + 写回 Markdown
|
|
63
|
+
await generateImageRatios(hexo);
|
|
64
|
+
fixMarkdownImages(hexo); // 不用 await,因为是同步的
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const glob = require('glob');
|
|
4
|
+
|
|
5
|
+
module.exports = (ctx, options) => {
|
|
6
|
+
const mdFiles = glob.sync('source/**/*.md');
|
|
7
|
+
|
|
8
|
+
const ratioMapPath = path.join(__dirname, '../../.cache/image-ratios.json');
|
|
9
|
+
if (!fs.existsSync(ratioMapPath)) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const ratioMap = JSON.parse(fs.readFileSync(ratioMapPath));
|
|
13
|
+
|
|
14
|
+
mdFiles.forEach(file => {
|
|
15
|
+
let content = fs.readFileSync(file, 'utf8');
|
|
16
|
+
let modified = false;
|
|
17
|
+
const relativePath = path.relative(process.cwd(), file);
|
|
18
|
+
const fileRatios = ratioMap[relativePath];
|
|
19
|
+
if (!fileRatios) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
content = content.replace(
|
|
23
|
+
/{%\s+image\s+([^\n%]*?)\b(https?:\/\/[^\s%]+)\b([^\n%]*?)%}/g,
|
|
24
|
+
(match, before, url, after) => {
|
|
25
|
+
if (match.includes('ratio:')) return match;
|
|
26
|
+
|
|
27
|
+
const ratio = fileRatios?.[url];
|
|
28
|
+
if (!ratio) return match;
|
|
29
|
+
modified = true;
|
|
30
|
+
const beforeTrim = before ? before.trim() : '';
|
|
31
|
+
if (beforeTrim.length > 0) {
|
|
32
|
+
return `{% image ${before.trim()} ${url} ${after.trim()} ratio:${ratio} %}`;
|
|
33
|
+
} else {
|
|
34
|
+
return `{% image ${url} ${after.trim()} ratio:${ratio} %}`;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
if (modified) {
|
|
40
|
+
fs.writeFileSync(file, content, 'utf8');
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
ctx.log.info('{% image %} 标签的图片长宽比已固定!');
|
|
44
|
+
};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const glob = require('glob');
|
|
4
|
+
const probe = require('probe-image-size');
|
|
5
|
+
|
|
6
|
+
const outputPath = path.join(__dirname, '../../.cache/image-ratios.json');
|
|
7
|
+
|
|
8
|
+
// 读取已有缓存
|
|
9
|
+
let cache = fs.existsSync(outputPath)
|
|
10
|
+
? JSON.parse(fs.readFileSync(outputPath))
|
|
11
|
+
: {};
|
|
12
|
+
|
|
13
|
+
// 提取 Markdown 中的图片链接
|
|
14
|
+
function extractImageUrls(content) {
|
|
15
|
+
const urls = [];
|
|
16
|
+
const tagImgRegex = /{%\s+image\s+[^%]*?\b(https?:\/\/[^\s%]+)[^%]*?%}/g;
|
|
17
|
+
|
|
18
|
+
let match;
|
|
19
|
+
while ((match = tagImgRegex.exec(content)) !== null) {
|
|
20
|
+
urls.push(match[1]);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return urls;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
// 远程图片尺寸探测
|
|
28
|
+
async function getImageRatio(ctx, url) {
|
|
29
|
+
if (!url.startsWith('http')) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
const result = await probe(url);
|
|
34
|
+
return `${result.width}/${result.height}`;
|
|
35
|
+
} catch (e) {
|
|
36
|
+
ctx.log.warn(`❌ 获取失败: ${url}`, e.message);
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
// 主逻辑
|
|
43
|
+
module.exports = async (ctx, options) => {
|
|
44
|
+
const cacheExists = fs.existsSync(outputPath);
|
|
45
|
+
if (cacheExists) {
|
|
46
|
+
ctx.log.info('正在获取图片长宽比。缓存已存在,开始增量更新...');
|
|
47
|
+
} else {
|
|
48
|
+
ctx.log.info('正在获取图片长宽比。首次可能耗时较久,请耐心等待...');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const mdFiles = glob.sync('source/**/*.md');
|
|
52
|
+
|
|
53
|
+
for (const file of mdFiles) {
|
|
54
|
+
const relative = path.relative(process.cwd(), file);
|
|
55
|
+
const content = fs.readFileSync(file, 'utf8');
|
|
56
|
+
const imageUrls = extractImageUrls(content);
|
|
57
|
+
const currentUrls = new Set(imageUrls);
|
|
58
|
+
|
|
59
|
+
// 初始化或清理旧数据
|
|
60
|
+
if (!cache[relative]) {
|
|
61
|
+
cache[relative] = {};
|
|
62
|
+
} else {
|
|
63
|
+
for (const oldUrl of Object.keys(cache[relative])) {
|
|
64
|
+
if (!currentUrls.has(oldUrl)) {
|
|
65
|
+
delete cache[relative][oldUrl];
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// 探测新图片
|
|
71
|
+
for (const url of imageUrls) {
|
|
72
|
+
if (cache[relative][url]) {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
const ratio = await getImageRatio(ctx, url);
|
|
76
|
+
if (ratio) {
|
|
77
|
+
cache[relative][url] = ratio;
|
|
78
|
+
ctx.log.info(`已添加: ${url} → ${ratio}`);
|
|
79
|
+
|
|
80
|
+
// 🧠 实时写入(增量更新,支持中断恢复)
|
|
81
|
+
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
|
|
82
|
+
fs.writeFileSync(outputPath, JSON.stringify(cache, null, 2));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
ctx.log.info('[image-ratios.json] 生成完成');
|
|
88
|
+
};
|
|
@@ -69,6 +69,7 @@ module.exports = (ctx, options = { useCache: true }) => {
|
|
|
69
69
|
fetchLatestVersion((err, latest) => {
|
|
70
70
|
if (err) return;
|
|
71
71
|
if (localVersion !== latest) {
|
|
72
|
+
console.log(``);
|
|
72
73
|
const line = '------------------------------------------------';
|
|
73
74
|
ctx.log.warn(`\x1b[33m${line}\x1b[0m`);
|
|
74
75
|
ctx.log.warn(``);
|
|
@@ -77,6 +78,7 @@ module.exports = (ctx, options = { useCache: true }) => {
|
|
|
77
78
|
ctx.log.warn(` 请尽快升级: npm i ${packageName}@latest`);
|
|
78
79
|
ctx.log.warn(``);
|
|
79
80
|
ctx.log.warn(`\x1b[33m${line}\x1b[0m`);
|
|
81
|
+
console.log(``);
|
|
80
82
|
}
|
|
81
83
|
if (options.useCache) writeCache(latest);
|
|
82
84
|
});
|
|
@@ -83,7 +83,11 @@ hexo.extend.helper.register('json_ld', function(args) {
|
|
|
83
83
|
};
|
|
84
84
|
|
|
85
85
|
if (config.keywords && config.keywords.length) {
|
|
86
|
-
|
|
86
|
+
if (Array.isArray(args)) {
|
|
87
|
+
schema.keywords = config.keywords.join(', ');
|
|
88
|
+
} else {
|
|
89
|
+
schema.keywords = config.keywords;
|
|
90
|
+
}
|
|
87
91
|
}
|
|
88
92
|
if (!this.is_home()) {
|
|
89
93
|
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
* image.js v1 | https://github.com/xaoxuu/hexo-theme-stellar/
|
|
3
3
|
* 格式与官方标签插件一致使用空格分隔,中括号内的是可选参数(中括号不需要写出来)
|
|
4
4
|
*
|
|
5
|
-
* {% image src [alt] [width:400px] [bg:#eee] [download:true/false/url] [fancybox:true/false/url] %}
|
|
5
|
+
* {% image src [alt] [width:400px] [bg:#eee] [download:true/false/url] [fancybox:true/false/url] [ratio] %}
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
'use strict'
|
|
9
9
|
|
|
10
10
|
module.exports = ctx => function(args) {
|
|
11
|
-
args = ctx.args.map(args, ['width', 'height', 'bg', 'download', 'padding', 'fancybox'], ['src', 'alt'])
|
|
11
|
+
args = ctx.args.map(args, ['width', 'height', 'bg', 'download', 'padding', 'fancybox', 'ratio'], ['src', 'alt'])
|
|
12
12
|
var style = ''
|
|
13
13
|
if (args.width) {
|
|
14
14
|
style += 'width:' + args.width + ';'
|
|
@@ -39,7 +39,7 @@ module.exports = ctx => function(args) {
|
|
|
39
39
|
|
|
40
40
|
function img(src, alt, style) {
|
|
41
41
|
let img = ''
|
|
42
|
-
img +=
|
|
42
|
+
img += `<img src="${src}" data-src="${src}"`
|
|
43
43
|
let a = '<a data-fancybox'
|
|
44
44
|
if (alt) {
|
|
45
45
|
img += ' alt="' + alt + '"'
|
|
@@ -48,9 +48,10 @@ module.exports = ctx => function(args) {
|
|
|
48
48
|
if (fancybox && !fancyboxHref) {
|
|
49
49
|
img += ` data-fancybox="${fancybox}"`
|
|
50
50
|
}
|
|
51
|
-
if (style.length > 0) {
|
|
51
|
+
if (style.length > 0 && !args.ratio) {
|
|
52
52
|
img += ' style="' + style + '"'
|
|
53
53
|
}
|
|
54
|
+
img += `onerror="this.src="${ctx.theme.config.default.image_onerror}""`
|
|
54
55
|
img += '/>'
|
|
55
56
|
|
|
56
57
|
if (fancyboxHref) {
|
|
@@ -65,8 +66,8 @@ module.exports = ctx => function(args) {
|
|
|
65
66
|
// wrap
|
|
66
67
|
el += '<div class="tag-plugin image">'
|
|
67
68
|
// bg
|
|
68
|
-
el +=
|
|
69
|
-
if (args.bg || args.padding) {
|
|
69
|
+
el += `<div class="image-bg"`
|
|
70
|
+
if (args.bg || args.padding || args.ratio || style) {
|
|
70
71
|
el += ' style="'
|
|
71
72
|
if (args.bg && args.bg.length > 0) {
|
|
72
73
|
el += 'background:' + args.bg + ';'
|
|
@@ -74,6 +75,15 @@ module.exports = ctx => function(args) {
|
|
|
74
75
|
if (args.padding) {
|
|
75
76
|
el += 'padding:' + args.padding + ';'
|
|
76
77
|
}
|
|
78
|
+
if (args.ratio) {
|
|
79
|
+
el += 'aspect-ratio:' + args.ratio + ';'
|
|
80
|
+
if (style) {
|
|
81
|
+
el += style
|
|
82
|
+
}
|
|
83
|
+
} else if (style) {
|
|
84
|
+
// 如果设置了图片宽度,但没有长宽比,那背景区就要铺满宽度
|
|
85
|
+
el += 'width:100%;'
|
|
86
|
+
}
|
|
77
87
|
el += '"'
|
|
78
88
|
}
|
|
79
89
|
el += '>'
|
|
@@ -14,7 +14,7 @@ module.exports = ctx => function (args) {
|
|
|
14
14
|
args.width = '100%'
|
|
15
15
|
}
|
|
16
16
|
if (args.bilibili) {
|
|
17
|
-
return `<div class="tag-plugin video" style="aspect-ratio:${args.ratio || 16 / 9};max-width:${args.width};">
|
|
17
|
+
return `<div class="tag-plugin video-player" style="aspect-ratio:${args.ratio || 16 / 9};max-width:${args.width};">
|
|
18
18
|
<iframe src="https://player.bilibili.com/player.html?bvid=${args.bilibili}&autoplay=${args.autoplay || 'false'}" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true">
|
|
19
19
|
</iframe>
|
|
20
20
|
</div>
|
|
@@ -26,7 +26,7 @@ module.exports = ctx => function (args) {
|
|
|
26
26
|
} else {
|
|
27
27
|
args.autoplay = '0'
|
|
28
28
|
}
|
|
29
|
-
return `<div class="tag-plugin video" style="aspect-ratio:${args.ratio || 16 / 9};max-width:${args.width};">
|
|
29
|
+
return `<div class="tag-plugin video-player" style="aspect-ratio:${args.ratio || 16 / 9};max-width:${args.width};">
|
|
30
30
|
<iframe style="border:none" src="https://www.youtube.com/embed/${args.youtube}?rel=0&disablekb=1&playsinline=1&autoplay=${args.autoplay}" picture-in-picture="true" allowfullscreen="true" >
|
|
31
31
|
</iframe>
|
|
32
32
|
</div>
|
|
@@ -23,7 +23,6 @@ hr
|
|
|
23
23
|
img
|
|
24
24
|
max-width: 100%
|
|
25
25
|
|
|
26
|
-
|
|
27
26
|
li
|
|
28
27
|
font-size: 'calc(%s - 1px)' % var(--fsp)
|
|
29
28
|
|
|
@@ -46,7 +45,7 @@ table:not([class])
|
|
|
46
45
|
background: var(--block)
|
|
47
46
|
td,th
|
|
48
47
|
padding: 0.5em 1em
|
|
49
|
-
border: 1px solid var(--block-
|
|
48
|
+
border: 1px solid var(--block-border)
|
|
50
49
|
line-height: 1.5
|
|
51
50
|
tr
|
|
52
51
|
word-break: keep-all
|
|
@@ -36,7 +36,7 @@ p>code:not([class]),li>code:not([class])
|
|
|
36
36
|
display: block
|
|
37
37
|
border-bottom-left-radius: $border-button
|
|
38
38
|
border-bottom-right-radius: $border-button
|
|
39
|
-
background: var(--block-
|
|
39
|
+
background: var(--block-border)
|
|
40
40
|
>table
|
|
41
41
|
overflow: auto
|
|
42
42
|
display: block
|