hexo-theme-stellar 1.32.2 → 1.32.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.
- package/README.md +22 -4
- package/_config.yml +16 -3
- package/_data/icons.yml +1 -1
- package/languages/en.yml +1 -0
- package/languages/zh-CN.yml +1 -0
- package/languages/zh-TW.yml +1 -0
- package/layout/_partial/comments/artalk/layout.ejs +1 -1
- package/layout/_partial/comments/artalk/script.ejs +22 -1
- package/layout/_partial/head.ejs +2 -6
- package/layout/_partial/main/article/article_footer.ejs +8 -0
- package/layout/_partial/main/article/contributors.ejs +34 -0
- package/layout/_partial/main/navbar/article_banner.ejs +2 -2
- package/layout/_partial/scripts/lazyload.ejs +1 -1
- package/layout/_partial/scripts/utils.ejs +4 -2
- package/layout/_partial/sidebar/logo.ejs +1 -1
- package/layout/_partial/widgets/toc.ejs +1 -3
- package/layout/_plugins/fancybox.ejs +7 -3
- package/package.json +1 -1
- package/scripts/generators/notebooks.js +27 -26
- package/scripts/tags/lib/friends.js +4 -1
- package/scripts/tags/lib/posters.js +1 -1
- package/scripts/tags/lib/sites.js +2 -2
- package/source/css/_common/loading.styl +1 -0
- package/source/css/_components/main.styl +2 -2
- package/source/css/_components/pages/article-story.styl +1 -1
- package/source/css/_components/partial/article-footer.styl +48 -0
- package/source/css/_components/partial/paginator.styl +1 -1
- package/source/css/_components/tag-plugins/friends.styl +1 -1
- package/source/css/_components/tag-plugins/quot.styl +1 -0
- package/source/css/_components/tag-plugins/timeline.styl +3 -0
- package/source/css/_components/widgets/toc.styl +6 -1
- package/source/css/_custom.styl +1 -1
- package/source/css/_defines/theme_base.styl +2 -2
- package/source/css/_defines/theme_colorful.styl +8 -8
- package/source/css/_plugins/comments/artalk.styl +7 -1
- package/source/css/_plugins/lazyload.styl +3 -2
- package/source/js/services/contributors.js +56 -0
- package/layout/_partial/widgets/components/edit.ejs +0 -24
package/README.md
CHANGED
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
# Stellar - 每个人的独立博客
|
|
2
2
|
|
|
3
|
-
Stellar
|
|
3
|
+
Stellar 是一个极为强大的综合型 Hexo 主题,包含博客系统、知识库系统、专栏系统、笔记系统,内置海量的标签和动态数据组件。
|
|
4
|
+
|
|
5
|
+
## 亮点
|
|
6
|
+
|
|
7
|
+
- 支持技术/生活文章布局风格,为不同类型的文章使用不同的风格。
|
|
8
|
+
- 内置 wiki 系统,可以展示多个项目文档,或个人知识库。
|
|
9
|
+
- 内置专栏系统,可以沉浸式阅读专栏系列文章。
|
|
10
|
+
- 内置笔记系统,更方便梳理笔记。
|
|
11
|
+
- 内置海量的灵活而强大的标签组件,互相之间还可以混搭嵌套。
|
|
12
|
+
- 内置多种动态数据组件,静态博客更新不再依赖于重新部署。
|
|
13
|
+
- 动态时间线(像发朋友圈一样发布短文,也可以订阅他人的时间线)
|
|
14
|
+
- 自动化的动态友链(自动检测友链状态、打标签、友链文章订阅)
|
|
15
|
+
- 渲染远程 markdown 文件(例如渲染项目仓库的 README 以减少重复工作)
|
|
16
|
+
- 模块化设计,内置多种复用性极强的小组件,自由搭配布局。
|
|
17
|
+
- 图片懒加载占位固定原图长宽比,不会发生高度跳变,体验更佳。
|
|
18
|
+
- 支持一站多作者,可以为不同文章指定不同的作者,每位作者都有专属主页。
|
|
19
|
+
- 社区文化:可订阅「探索号」时间线数据源获取社区用户的宝贵经验分享。
|
|
20
|
+
|
|
21
|
+
上述亮点都可以在 [文档](https://xaoxuu.com/wiki/stellar/) 中找到详细使用方法。
|
|
4
22
|
|
|
5
23
|
[](https://starchart.cc/xaoxuu/hexo-theme-stellar)
|
|
6
24
|
|
|
@@ -10,10 +28,10 @@ Stellar 是一个内置文档系统的简约商务风 Hexo 主题,支持丰富
|
|
|
10
28
|
Check your environment:
|
|
11
29
|
|
|
12
30
|
```yaml
|
|
13
|
-
Hexo: 6.3.0 ~
|
|
31
|
+
Hexo: 6.3.0 ~ latest
|
|
14
32
|
hexo-cli: 4.3.0 ~ latest
|
|
15
|
-
node: 14.17.3 ~
|
|
16
|
-
npm: 6.14.13 ~
|
|
33
|
+
node: 14.17.3 ~ latest LTS # 建议选择 LTS 版本,过高的版本 hexo 还没有进行兼容。
|
|
34
|
+
npm: 6.14.13 ~ latest
|
|
17
35
|
```
|
|
18
36
|
|
|
19
37
|
Edit your `_config.yml`:
|
package/_config.yml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
######## Stellar info ########
|
|
2
2
|
stellar:
|
|
3
|
-
version: '1.32.
|
|
3
|
+
version: '1.32.4'
|
|
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
|
|
@@ -315,7 +315,15 @@ comments:
|
|
|
315
315
|
js: https://unpkg.com/artalk@2.9/dist/Artalk.js
|
|
316
316
|
server: # 后端服务地址
|
|
317
317
|
site: '' # 站点名称
|
|
318
|
-
darkMode: auto
|
|
318
|
+
darkMode: auto # 其它模式都有问题,慎用,否则后果自负
|
|
319
|
+
fancybox: true # 是否为评论区启用 fancybox
|
|
320
|
+
# artalk 有三类图片:1.上传至服务端 2.上传至服务端后利用upgit上传至图床 3.前端上传至图床(本配置为此类)
|
|
321
|
+
# 配置此项时将覆盖服务端上传能力
|
|
322
|
+
imageUploader:
|
|
323
|
+
# 以兰空图床为例,下列填写内容为:
|
|
324
|
+
# api: 'https://xxxxxx/api/v1/upload' # 图床上传地址
|
|
325
|
+
# token: 'Bearer xxxxxxxxxxxxxx' # 图床验证
|
|
326
|
+
# resp: 'data.links.url' # 图片地址返回值的字段
|
|
319
327
|
|
|
320
328
|
|
|
321
329
|
######## Footer ########
|
|
@@ -495,6 +503,11 @@ data_services:
|
|
|
495
503
|
js: /js/services/artalk_latest_comment.js
|
|
496
504
|
giscus:
|
|
497
505
|
js: /js/services/giscus_latest_comment.js
|
|
506
|
+
contributors:
|
|
507
|
+
edit_this_page: # 从开头开始匹配替换
|
|
508
|
+
'_posts/': # https://github.com/xaoxuu/xaoxuu.com/blob/main/source/_posts/
|
|
509
|
+
'wiki/stellar/': https://github.com/xaoxuu/hexo-theme-stellar-docs/blob/main/
|
|
510
|
+
js: /js/services/contributors.js
|
|
498
511
|
|
|
499
512
|
|
|
500
513
|
# 扩展插件接入方法:(插件名下面用 #plugin# 代替)
|
|
@@ -666,7 +679,7 @@ style:
|
|
|
666
679
|
next: https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.12/arrow/064b95430caf4.svg
|
|
667
680
|
error_page: https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.12/404/1c830bfcd517d.svg
|
|
668
681
|
site: # 使用 background-image 后,blur 设置才有效
|
|
669
|
-
# background-image:
|
|
682
|
+
# background-image: url(https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.14/image/site-bg1@small.webp)
|
|
670
683
|
blur-px: 100px
|
|
671
684
|
blur-bg: var(--bg-a75)
|
|
672
685
|
blur-sat: 300%
|
package/_data/icons.yml
CHANGED
|
@@ -30,7 +30,7 @@ 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"><!-- Icon from Solar by 480 Design - https://creativecommons.org/licenses/by/4.0/ --><
|
|
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/ --><circle cx="12" cy="12" r="10" fill="currentColor" opacity=".5"/><path fill="currentColor" d="M13.926 14.302c.245-.191.467-.413.912-.858l5.54-5.54c.134-.134.073-.365-.106-.427a6.1 6.1 0 0 1-2.3-1.449a6.1 6.1 0 0 1-1.45-2.3c-.061-.18-.292-.24-.426-.106l-5.54 5.54c-.445.444-.667.667-.858.912a5 5 0 0 0-.577.932c-.133.28-.233.579-.431 1.175l-.257.77l-.409 1.226l-.382 1.148a.817.817 0 0 0 1.032 1.033l1.15-.383l1.224-.408l.77-.257c.597-.199.895-.298 1.175-.432q.498-.237.933-.576m8.187-8.132a3.028 3.028 0 0 0-4.282-4.283l-.179.178a.73.73 0 0 0-.206.651c.027.15.077.37.168.633a4.9 4.9 0 0 0 1.174 1.863a4.9 4.9 0 0 0 1.862 1.174c.263.09.483.141.633.168c.24.043.48-.035.652-.207z"/></svg>
|
|
34
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
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>
|
package/languages/en.yml
CHANGED
package/languages/zh-CN.yml
CHANGED
package/languages/zh-TW.yml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<%
|
|
2
2
|
function layoutDiv() {
|
|
3
3
|
var el = '';
|
|
4
|
-
el +=
|
|
4
|
+
el += `<div class="artalk ${theme.comments.artalk?.fancybox ? 'with-fancybox' : ''}" id="artalk_container"`;
|
|
5
5
|
let cfg = {};
|
|
6
6
|
if (page.comment_id) {
|
|
7
7
|
cfg['comment_id'] = page.comment_id;
|
|
@@ -6,6 +6,10 @@
|
|
|
6
6
|
if (!el) return;
|
|
7
7
|
utils.css('<%- theme.comments.artalk.css %>');
|
|
8
8
|
utils.js('<%- theme.comments.artalk.js %>', {defer: true}).then(function () {
|
|
9
|
+
// 监听 Artalk 事件
|
|
10
|
+
Artalk.use((ctx) => {
|
|
11
|
+
ctx.on('list-loaded', () => window.lazyLoadInstance?.update())
|
|
12
|
+
})
|
|
9
13
|
const path = el.getAttribute('comment_id') ?? decodeURI(window.location.pathname);
|
|
10
14
|
const artalk = Artalk.init({
|
|
11
15
|
el: '#artalk_container',
|
|
@@ -13,7 +17,24 @@
|
|
|
13
17
|
pageTitle: '<%= page.title %>',
|
|
14
18
|
server: '<%= theme.comments.artalk.server %>',
|
|
15
19
|
site: '<%= theme.comments.artalk.site %>',
|
|
16
|
-
darkMode: '<%= theme.comments.artalk.darkMode %>'
|
|
20
|
+
darkMode: '<%= theme.comments.artalk.darkMode %>',
|
|
21
|
+
<% if (theme.comments.artalk.imageUploader?.api) { %>
|
|
22
|
+
imgUploader: function(file) {
|
|
23
|
+
let headers = new Headers();
|
|
24
|
+
headers.set('Accept', 'application/json');
|
|
25
|
+
<% if (theme.comments.artalk.imageUploader?.token) { %>
|
|
26
|
+
headers.set('Authorization', '<%= theme.comments.artalk.imageUploader?.token %>')
|
|
27
|
+
<% } %>
|
|
28
|
+
let formData = new FormData();
|
|
29
|
+
formData.append('file', file);
|
|
30
|
+
return fetch('<%= theme.comments.artalk.imageUploader?.api %>',{
|
|
31
|
+
method: 'POST',
|
|
32
|
+
body: formData,
|
|
33
|
+
headers: headers
|
|
34
|
+
}).then((resp) => resp.json())
|
|
35
|
+
.then((resp) => resp.<%= theme.comments.artalk.imageUploader?.resp %>)
|
|
36
|
+
},
|
|
37
|
+
<% } %>
|
|
17
38
|
});
|
|
18
39
|
});
|
|
19
40
|
}
|
package/layout/_partial/head.ejs
CHANGED
|
@@ -95,12 +95,8 @@ function custom_inject() {
|
|
|
95
95
|
function generate_canonical() {
|
|
96
96
|
const originalHost = theme.canonical.originalHost || '';
|
|
97
97
|
if (originalHost.length > 0) {
|
|
98
|
-
|
|
99
|
-
|
|
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
|
-
}
|
|
98
|
+
const path = url_for(page.path).replace(/index\.html$/, '') || '/';
|
|
99
|
+
return `<link rel="canonical" href="https://${originalHost}${path}">`;
|
|
104
100
|
}
|
|
105
101
|
return '';
|
|
106
102
|
}
|
|
@@ -11,6 +11,10 @@ function layoutDiv() {
|
|
|
11
11
|
if (theme.article.share?.length > 0) {
|
|
12
12
|
item.push('share');
|
|
13
13
|
}
|
|
14
|
+
var contributors = partial('contributors', {map: theme.data_services.contributors.edit_this_page})
|
|
15
|
+
if (contributors?.trim().length > 0) {
|
|
16
|
+
item.push('contributors')
|
|
17
|
+
}
|
|
14
18
|
if (item.length === 0) {
|
|
15
19
|
return el;
|
|
16
20
|
}
|
|
@@ -76,6 +80,10 @@ function layoutDiv() {
|
|
|
76
80
|
`
|
|
77
81
|
}
|
|
78
82
|
|
|
83
|
+
if (contributors) {
|
|
84
|
+
el += contributors
|
|
85
|
+
}
|
|
86
|
+
|
|
79
87
|
var showSharePlugin = false
|
|
80
88
|
if (page.wiki) {
|
|
81
89
|
const proj = theme.wiki.tree[page.wiki]
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<%
|
|
2
|
+
function parseURL() {
|
|
3
|
+
const source = page.source || ''
|
|
4
|
+
for (let id of Object.keys(map)) {
|
|
5
|
+
if (source.startsWith(id) && map[id]) {
|
|
6
|
+
return source.replace(id, map[id])
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
function layoutDiv() {
|
|
11
|
+
const url = parseURL()
|
|
12
|
+
if (url == null) {
|
|
13
|
+
return ''
|
|
14
|
+
}
|
|
15
|
+
const commits = url.replace('/github.com/', `/${theme.api_host.ghapi}/repos/`).replace('/blob/main/', '/commits?path=');
|
|
16
|
+
var el = `
|
|
17
|
+
<section id="contributors">
|
|
18
|
+
<div class="header">
|
|
19
|
+
<span>${__('meta.contributors')}</span>
|
|
20
|
+
<span class="spacer"></span>
|
|
21
|
+
<a class="edit" href="${url_for(url)}">
|
|
22
|
+
${icon('default:edit')}
|
|
23
|
+
<span>${__('btn.edit')}</span>
|
|
24
|
+
</a>
|
|
25
|
+
</div>
|
|
26
|
+
<div class="body">
|
|
27
|
+
<div class="ds-contributors users-wrap" api-type="commits" api="${commits}"><div class="grid-box"></div></div>
|
|
28
|
+
</div>
|
|
29
|
+
</section>
|
|
30
|
+
`
|
|
31
|
+
return el
|
|
32
|
+
}
|
|
33
|
+
%>
|
|
34
|
+
<%- layoutDiv() %>
|
|
@@ -70,7 +70,7 @@ function layoutSubtitle() {
|
|
|
70
70
|
|
|
71
71
|
function layoutIcon() {
|
|
72
72
|
if (banner.avatar?.length > 0 || banner.icon?.length > 0) {
|
|
73
|
-
return `<img class="avatar" src="${banner.avatar || banner.icon}">`
|
|
73
|
+
return `<img class="lazy avatar" data-src="${banner.avatar || banner.icon}">`
|
|
74
74
|
} else {
|
|
75
75
|
return ''
|
|
76
76
|
}
|
|
@@ -109,7 +109,7 @@ function layoutDiv() {
|
|
|
109
109
|
var el = ``
|
|
110
110
|
el += `<div class="article banner${scrollreveal(' ')} top">`
|
|
111
111
|
if (banner.url?.length > 0) {
|
|
112
|
-
el += `<img class="bg" src="${banner.url}">`
|
|
112
|
+
el += `<img class="lazy bg" data-src="${banner.url}">`
|
|
113
113
|
if (banner.color) {
|
|
114
114
|
style += ' style="--text-banner:' + banner.color + '"'
|
|
115
115
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// Set the options globally
|
|
5
5
|
// to make LazyLoad self-initialize
|
|
6
6
|
window.lazyLoadOptions = {
|
|
7
|
-
elements_selector: ".lazy",
|
|
7
|
+
elements_selector: ".lazy, .lazyload",
|
|
8
8
|
callback_loaded: (el) => {
|
|
9
9
|
el.classList.add('loaded');
|
|
10
10
|
const wrapper = el.closest('.lazy-box');
|
|
@@ -160,7 +160,7 @@
|
|
|
160
160
|
status = 2;
|
|
161
161
|
timer = null;
|
|
162
162
|
reject('请求超时');
|
|
163
|
-
if (retryTimes == 0) {
|
|
163
|
+
if (retryTimes == 0 && onFailure) {
|
|
164
164
|
onFailure();
|
|
165
165
|
}
|
|
166
166
|
}
|
|
@@ -188,7 +188,9 @@
|
|
|
188
188
|
}, 5000);
|
|
189
189
|
} else {
|
|
190
190
|
utils.onLoadFailure(el);
|
|
191
|
-
onFailure
|
|
191
|
+
if (onFailure) {
|
|
192
|
+
onFailure();
|
|
193
|
+
}
|
|
192
194
|
}
|
|
193
195
|
});
|
|
194
196
|
});
|
|
@@ -22,7 +22,7 @@ if (page.logo) {
|
|
|
22
22
|
// logo.icon, logo.title, logo.subtitle, logo.url
|
|
23
23
|
function layoutTitle(main, url, sub) {
|
|
24
24
|
var el = ''
|
|
25
|
-
el += `<a class="title" href="${
|
|
25
|
+
el += `<a class="title" href="${url || "/"}">`
|
|
26
26
|
el += `<div class="main">${main}</div>`
|
|
27
27
|
if (sub) {
|
|
28
28
|
const arr = sub.split('|')
|
|
@@ -36,9 +36,8 @@ function layoutToc(fallback) {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
function layoutDiv(fallback) {
|
|
39
|
-
const editBtn = partial('components/edit', {map: item.edit_this_page})
|
|
40
39
|
const tocBody = layoutTocBody()
|
|
41
|
-
if (tocBody.trim().length == 0
|
|
40
|
+
if (tocBody.trim().length == 0) {
|
|
42
41
|
return ''
|
|
43
42
|
}
|
|
44
43
|
var el = ''
|
|
@@ -50,7 +49,6 @@ function layoutDiv(fallback) {
|
|
|
50
49
|
el += `</div>`
|
|
51
50
|
}
|
|
52
51
|
el += `<div class="widget-footer">`
|
|
53
|
-
el += editBtn
|
|
54
52
|
el += `<a class="top" onclick="util.scrollTop()">`
|
|
55
53
|
el += icon('default:upup')
|
|
56
54
|
el += `<span>${__('btn.top')}</span>`
|
|
@@ -4,14 +4,18 @@
|
|
|
4
4
|
css: `<%- conf.css %>`,
|
|
5
5
|
js: `<%- conf.js %>`
|
|
6
6
|
};
|
|
7
|
-
var selector = '[data-fancybox]:not(.error)';
|
|
7
|
+
var selector = '[data-fancybox]:not(.error), .with-fancybox .atk-content img:not([atk-emoticon])';
|
|
8
8
|
if (ctx.fancybox.selector) {
|
|
9
9
|
selector += `, ${ctx.fancybox.selector}`
|
|
10
10
|
}
|
|
11
11
|
var needFancybox = document.querySelectorAll(selector).length !== 0;
|
|
12
12
|
if (!needFancybox) {
|
|
13
|
-
const
|
|
14
|
-
if (
|
|
13
|
+
const memos = document.getElementsByClassName('ds-memos');
|
|
14
|
+
if (memos != undefined && memos.length > 0) {
|
|
15
|
+
needFancybox = true;
|
|
16
|
+
}
|
|
17
|
+
const fancybox = document.getElementsByClassName('with-fancybox');
|
|
18
|
+
if (fancybox != undefined && fancybox.length > 0) {
|
|
15
19
|
needFancybox = true;
|
|
16
20
|
}
|
|
17
21
|
}
|
package/package.json
CHANGED
|
@@ -1,38 +1,39 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* notebooks v1
|
|
3
3
|
*/
|
|
4
|
-
const pagination = require('hexo-pagination')
|
|
5
|
-
|
|
6
|
-
function paginationWithEmpty(base, posts, options={}) {
|
|
7
|
-
const { layout, data = {} } = options
|
|
8
|
-
if (posts.length === 0) {
|
|
9
|
-
base = `${base}/`
|
|
10
|
-
return [{
|
|
11
|
-
path: base,
|
|
12
|
-
layout: layout,
|
|
13
|
-
data: {
|
|
14
|
-
...data,
|
|
15
|
-
base: base,
|
|
16
|
-
total: 1,
|
|
17
|
-
current: 1,
|
|
18
|
-
current_url: base,
|
|
19
|
-
posts: posts,
|
|
20
|
-
prev: 0,
|
|
21
|
-
prev_link: '',
|
|
22
|
-
next: 0,
|
|
23
|
-
next_link: '',
|
|
24
|
-
}
|
|
25
|
-
}]
|
|
26
|
-
} else {
|
|
27
|
-
return pagination(base, posts, options)
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
4
|
|
|
31
5
|
hexo.extend.generator.register('notebooks', function (locals) {
|
|
32
6
|
const { site_tree, notebooks } = hexo.theme.config
|
|
33
7
|
if (!notebooks?.tree || Object.keys(notebooks.tree).length === 0) {
|
|
34
8
|
return []
|
|
35
9
|
}
|
|
10
|
+
// 不用 blog 和 notebooks 时不必依赖 hexo-pagination
|
|
11
|
+
const pagination = require('hexo-pagination')
|
|
12
|
+
|
|
13
|
+
function paginationWithEmpty(base, posts, options={}) {
|
|
14
|
+
const { layout, data = {} } = options
|
|
15
|
+
if (posts.length === 0) {
|
|
16
|
+
base = `${base}/`
|
|
17
|
+
return [{
|
|
18
|
+
path: base,
|
|
19
|
+
layout: layout,
|
|
20
|
+
data: {
|
|
21
|
+
...data,
|
|
22
|
+
base: base,
|
|
23
|
+
total: 1,
|
|
24
|
+
current: 1,
|
|
25
|
+
current_url: base,
|
|
26
|
+
posts: posts,
|
|
27
|
+
prev: 0,
|
|
28
|
+
prev_link: '',
|
|
29
|
+
next: 0,
|
|
30
|
+
next_link: '',
|
|
31
|
+
}
|
|
32
|
+
}]
|
|
33
|
+
} else {
|
|
34
|
+
return pagination(base, posts, options)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
36
37
|
|
|
37
38
|
const routes = []
|
|
38
39
|
|
|
@@ -27,7 +27,10 @@ module.exports = ctx => function(args) {
|
|
|
27
27
|
if (item?.url && item?.title) {
|
|
28
28
|
el += `<div class="grid-cell user-card">`
|
|
29
29
|
el += `<a class="card-link" target="_blank" rel="external nofollow noopener noreferrer" href="${item.url}">`
|
|
30
|
-
el += `<
|
|
30
|
+
el += `<div class="lazy-box icon">`
|
|
31
|
+
el += `<img class="lazy" data-src="${item.icon || item.avatar || ctx.theme.config.default.avatar}" onerror="javascript:this.removeAttribute("data-src");this.src="${ctx.theme.config.default.avatar}";"/>`
|
|
32
|
+
el += `<div class="lazy-icon" style="background-image:url("${ctx.theme.config.default.loading}");"></div>`
|
|
33
|
+
el += `</div>`
|
|
31
34
|
el += `<div class="name">`
|
|
32
35
|
el += `<span>${item.title}</span>`
|
|
33
36
|
el += `</div>`
|
|
@@ -32,12 +32,12 @@ module.exports = ctx => function(args) {
|
|
|
32
32
|
el += `<div class="grid-cell site-card">`
|
|
33
33
|
el += `<a class="card-link" target="_blank" rel="external nofollow noopener noreferrer" href="${item.url}">`
|
|
34
34
|
el += `<div class="lazy-box snapshot">`
|
|
35
|
-
el += `<img src="${item.cover || item.snapshot || item.screenshot || ('https://image.thum.io/get/width/1280/crop/720/' + item.url)}" onerror="javascript:this.removeAttribute("data-src");this.src="${ctx.theme.config.default.cover}";"/>`
|
|
35
|
+
el += `<img class="lazy" data-src="${item.cover || item.snapshot || item.screenshot || ('https://image.thum.io/get/width/1280/crop/720/' + item.url)}" onerror="javascript:this.removeAttribute("data-src");this.src="${ctx.theme.config.default.cover}";"/>`
|
|
36
36
|
el += `<div class="lazy-icon" style="background-image:url("${ctx.theme.config.default.loading}");"></div>`
|
|
37
37
|
el += `</div>`
|
|
38
38
|
el += `<div class="info">`
|
|
39
39
|
el += `<div class="lazy-box icon">`
|
|
40
|
-
el += `<img src="${item.icon || item.avatar || ctx.theme.config.default.link}" onerror="javascript:this.removeAttribute("data-src");this.src="${item.icon || item.avatar || ctx.theme.config.default.link}";"/>`
|
|
40
|
+
el += `<img class="lazy" data-src="${item.icon || item.avatar || ctx.theme.config.default.link}" onerror="javascript:this.removeAttribute("data-src");this.src="${item.icon || item.avatar || ctx.theme.config.default.link}";"/>`
|
|
41
41
|
el += `<div class="lazy-icon" style="background-image:url("${ctx.theme.config.default.loading}");"></div>`
|
|
42
42
|
el += `</div>`
|
|
43
43
|
el += `<span class="title">${item.title}</span>`
|
|
@@ -20,8 +20,8 @@ body>.sitebg
|
|
|
20
20
|
right: 0
|
|
21
21
|
bottom: 0
|
|
22
22
|
background-size: cover
|
|
23
|
-
if $site-background
|
|
24
|
-
background-image: convert($site-background)
|
|
23
|
+
if $site-background-image
|
|
24
|
+
background-image: convert($site-background-image)
|
|
25
25
|
.siteblur
|
|
26
26
|
width: 100%
|
|
27
27
|
height: 100%
|
|
@@ -40,6 +40,54 @@
|
|
|
40
40
|
padding-top: 1rem
|
|
41
41
|
border-top: 1px solid var(--block-border)
|
|
42
42
|
|
|
43
|
+
.article-footer #contributors
|
|
44
|
+
.header
|
|
45
|
+
display: flex
|
|
46
|
+
justify-content: space-between
|
|
47
|
+
a.edit
|
|
48
|
+
font-size: $fs-14
|
|
49
|
+
display: flex
|
|
50
|
+
align-items: center
|
|
51
|
+
color: inherit
|
|
52
|
+
background: var(--block)
|
|
53
|
+
padding: 0 .5rem
|
|
54
|
+
border-radius: $border-button
|
|
55
|
+
svg
|
|
56
|
+
width 1.2em
|
|
57
|
+
height: 1.2em
|
|
58
|
+
margin-right: 4px
|
|
59
|
+
color: var(--text-p4)
|
|
60
|
+
trans1 color
|
|
61
|
+
span
|
|
62
|
+
line-height: 1.5
|
|
63
|
+
trans1 color
|
|
64
|
+
trans1 background
|
|
65
|
+
&:hover
|
|
66
|
+
color: var(--theme)
|
|
67
|
+
background: var(--theme-a20)
|
|
68
|
+
svg
|
|
69
|
+
color: var(--theme)
|
|
70
|
+
.body
|
|
71
|
+
.loading-wrap
|
|
72
|
+
margin-top: 4px
|
|
73
|
+
padding: 0
|
|
74
|
+
height: 84px
|
|
75
|
+
.users-wrap .grid-box
|
|
76
|
+
margin-top: 4px
|
|
77
|
+
grid-template-columns: repeat(auto-fill, minmax(72px, 1fr))
|
|
78
|
+
grid-gap: 4px
|
|
79
|
+
&:empty
|
|
80
|
+
display: none
|
|
81
|
+
.users-wrap .user-card .card-link
|
|
82
|
+
background: var(--block)
|
|
83
|
+
trans1 all
|
|
84
|
+
&:hover
|
|
85
|
+
background: var(--theme-a20)
|
|
86
|
+
color: var(--theme)
|
|
87
|
+
img
|
|
88
|
+
width 32px
|
|
89
|
+
height: 32px
|
|
90
|
+
|
|
43
91
|
.article-footer .social-wrap
|
|
44
92
|
grid-gap: 0.5rem 2rem
|
|
45
93
|
margin: 1rem 0 0.5rem
|
|
@@ -11,6 +11,11 @@
|
|
|
11
11
|
width: 4px
|
|
12
12
|
background: var(--block)
|
|
13
13
|
border-radius: 4px
|
|
14
|
+
|
|
15
|
+
if !$site-background-image
|
|
16
|
+
@media screen and (min-width: $device-laptop)
|
|
17
|
+
background: var(--background)
|
|
18
|
+
|
|
14
19
|
|
|
15
20
|
// 目录基本样式
|
|
16
21
|
.widget-wrapper.toc .toc
|
|
@@ -178,6 +183,6 @@
|
|
|
178
183
|
color: var(--text-p2)
|
|
179
184
|
.widget-wrapper.toc .widget-footer
|
|
180
185
|
a
|
|
181
|
-
background: var(--
|
|
186
|
+
background: var(--block)
|
|
182
187
|
a+a
|
|
183
188
|
margin-top: 4px
|
package/source/css/_custom.styl
CHANGED
|
@@ -29,7 +29,7 @@ $fsp2 = 'calc(%s - 2px)' % $fs-body
|
|
|
29
29
|
$fsp3 = 'calc(%s - 3px)' % $fs-body
|
|
30
30
|
|
|
31
31
|
// site main
|
|
32
|
-
$site-background = hexo-config('style.site.background-image')
|
|
32
|
+
$site-background-image = hexo-config('style.site.background-image')
|
|
33
33
|
$leftbar-background-image = hexo-config('style.leftbar.background-image')
|
|
34
34
|
$leftbar-background-color = hexo-config('style.leftbar.background-color')
|
|
35
35
|
|
|
@@ -66,7 +66,7 @@ x-set-text-colors($scheme, $p0 = 1, $p1 = 0.8, $p2 = 0.7, $p3 = 0.5, $p4 = 0.4)
|
|
|
66
66
|
dynamic-theme-light()
|
|
67
67
|
$hue = $c-base-hue
|
|
68
68
|
--background: x-hsla($hue, 20%, 98%, 1)
|
|
69
|
-
--card: $site-background ? hsla(white, 0.5) : white
|
|
69
|
+
--card: $site-background-image ? hsla(white, 0.5) : white
|
|
70
70
|
|
|
71
71
|
x-set-bg-colors('light')
|
|
72
72
|
x-set-text-colors('light')
|
|
@@ -77,7 +77,7 @@ dynamic-theme-dark()
|
|
|
77
77
|
--background: x-hsla($hue, 8%, 12%, 1)
|
|
78
78
|
@media screen and (max-width: $device-mobile-max)
|
|
79
79
|
--background: black
|
|
80
|
-
--card: $site-background ? hsla(white, 0.25) : x-hsla($hue, 10%, 24%, 1)
|
|
80
|
+
--card: $site-background-image ? hsla(white, 0.25) : x-hsla($hue, 10%, 24%, 1)
|
|
81
81
|
|
|
82
82
|
x-set-bg-colors('dark')
|
|
83
83
|
x-set-text-colors('dark')
|
|
@@ -4,15 +4,15 @@ x-set-theme-colorful($scheme = 'light', $color, $text = true)
|
|
|
4
4
|
x-set-theme-with-color($color)
|
|
5
5
|
x-set-link-with-color($color)
|
|
6
6
|
if $scheme == 'dark'
|
|
7
|
-
--theme-border: x-hsla($hue,
|
|
7
|
+
--theme-border: x-hsla($hue, 40%, 24%)
|
|
8
8
|
--theme-block: x-hsla($hue, 24%, 24%)
|
|
9
9
|
--theme-mark: x-hsla($hue, 24%, 24%)
|
|
10
|
-
--theme-codeblock: x-hsla($hue, 12%,
|
|
10
|
+
--theme-codeblock: x-hsla($hue, 12%, 24%)
|
|
11
11
|
if text
|
|
12
12
|
--text: x-hsla($hue, 50%, 75%, 1)
|
|
13
|
-
--text-p1: x-hsla($hue,
|
|
14
|
-
--text-p2: x-hsla($hue, 80%, 80%, 0.
|
|
15
|
-
--text-p3: x-hsla($hue, 80%, 80%, 0.
|
|
13
|
+
--text-p1: x-hsla($hue, 80%, 80%, 1)
|
|
14
|
+
--text-p2: x-hsla($hue, 80%, 80%, 0.8)
|
|
15
|
+
--text-p3: x-hsla($hue, 80%, 80%, 0.6)
|
|
16
16
|
--text-p4: x-hsla($hue, 80%, 80%, 0.4)
|
|
17
17
|
--link: x-hsla($hue, 80%, 60%, 1)
|
|
18
18
|
--link-a20: x-hsla($hue, 80%, 60%, 0.2)
|
|
@@ -23,9 +23,9 @@ x-set-theme-colorful($scheme = 'light', $color, $text = true)
|
|
|
23
23
|
--theme-codeblock: x-hsla($hue, 50%, 95%)
|
|
24
24
|
if text
|
|
25
25
|
--text: x-hsla($hue, 55%, 16%, 1)
|
|
26
|
-
--text-p1: x-hsla($hue,
|
|
27
|
-
--text-p2: x-hsla($hue, 90%, 20%, 0.
|
|
28
|
-
--text-p3: x-hsla($hue, 90%, 20%, 0.
|
|
26
|
+
--text-p1: x-hsla($hue, 90%, 20%, 1)
|
|
27
|
+
--text-p2: x-hsla($hue, 90%, 20%, 0.8)
|
|
28
|
+
--text-p3: x-hsla($hue, 90%, 20%, 0.6)
|
|
29
29
|
--text-p4: x-hsla($hue, 90%, 20%, 0.4)
|
|
30
30
|
--link: x-hsla($hue, 95%, 32%, 1)
|
|
31
31
|
--link-a20: x-hsla($hue, 95%, 32%, 0.2)
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
border-bottom: 1px dashed var(--block-border)
|
|
9
9
|
padding: 0.5rem 1rem
|
|
10
10
|
margin: 0
|
|
11
|
+
.atk-editor-user
|
|
12
|
+
padding: 0
|
|
11
13
|
.atk-editor-user-wrap:empty
|
|
12
14
|
visibility: hidden
|
|
13
15
|
padding: 0
|
|
@@ -70,6 +72,9 @@
|
|
|
70
72
|
.atk-error-layer
|
|
71
73
|
background: none
|
|
72
74
|
|
|
75
|
+
.with-fancybox .atk-content img:not([atk-emoticon])
|
|
76
|
+
cursor: zoom-in
|
|
77
|
+
|
|
73
78
|
.cmt-body
|
|
74
79
|
.artalk, .atk-layer-wrap, .artalk.atk-dark-mode, .atk-layer-wrap.atk-dark-mode
|
|
75
80
|
--at-color-font: var(--text-p1)
|
|
@@ -77,7 +82,7 @@
|
|
|
77
82
|
--at-color-sub: var(--text-p3)
|
|
78
83
|
--at-color-grey: var(--text-p4)
|
|
79
84
|
--at-color-meta: var(--text-p4)
|
|
80
|
-
if $site-background
|
|
85
|
+
if $site-background-image
|
|
81
86
|
--at-color-border: transparent
|
|
82
87
|
else
|
|
83
88
|
--at-color-border: var(--block-border)
|
|
@@ -98,6 +103,7 @@
|
|
|
98
103
|
background: none
|
|
99
104
|
.md-text .atk-main-editor>.atk-textarea-wrap>.atk-textarea
|
|
100
105
|
background: none
|
|
106
|
+
padding: 0.5rem 1rem
|
|
101
107
|
|
|
102
108
|
.md-text .atk-notify-wrap .atk-notify
|
|
103
109
|
border-radius: $border-bar
|
|
@@ -4,6 +4,7 @@ $loadingImageSize = 2rem
|
|
|
4
4
|
.lazy-box
|
|
5
5
|
position: relative
|
|
6
6
|
overflow: hidden
|
|
7
|
+
line-height: 0
|
|
7
8
|
&.async // 通过 data-service 异步创建的懒加载元素,没办法知道宽高
|
|
8
9
|
background: var(--block)
|
|
9
10
|
min-height: 4rem
|
|
@@ -47,7 +48,7 @@ img[data-ll-status].loaded
|
|
|
47
48
|
|
|
48
49
|
// 加载失败
|
|
49
50
|
img[data-ll-status].error
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
width: $loadingImageSize
|
|
52
|
+
height: $loadingImageSize
|
|
52
53
|
&+.lazy-icon
|
|
53
54
|
display: none
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
utils.jq(() => {
|
|
2
|
+
$(function () {
|
|
3
|
+
function parseGithubFileContributors(data) {
|
|
4
|
+
// 去重贡献者(按 login)
|
|
5
|
+
const contributorsMap = new Map();
|
|
6
|
+
|
|
7
|
+
for (const commit of data) {
|
|
8
|
+
const author = commit.author;
|
|
9
|
+
if (author) {
|
|
10
|
+
const login = author.login;
|
|
11
|
+
if (!contributorsMap.has(login)) {
|
|
12
|
+
contributorsMap.set(login, {
|
|
13
|
+
login: login,
|
|
14
|
+
avatar_url: author.avatar_url,
|
|
15
|
+
html_url: author.html_url,
|
|
16
|
+
count: 1
|
|
17
|
+
});
|
|
18
|
+
} else {
|
|
19
|
+
contributorsMap.get(login).count++;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
// 转为数组并按提交次数排序(降序)
|
|
24
|
+
const sortedContributors = Array.from(contributorsMap.values())
|
|
25
|
+
.sort((a, b) => b.count - a.count);
|
|
26
|
+
return sortedContributors;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const els = document.getElementsByClassName('ds-contributors');
|
|
30
|
+
for (var i = 0; i < els.length; i++) {
|
|
31
|
+
const el = els[i];
|
|
32
|
+
const api = el.getAttribute('api');
|
|
33
|
+
if (api == null) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
const default_avatar = def.avatar;
|
|
37
|
+
// layout
|
|
38
|
+
utils.request(el, api, async resp => {
|
|
39
|
+
const data = await resp.json();
|
|
40
|
+
const list = parseGithubFileContributors(data);
|
|
41
|
+
for (let item of list) {
|
|
42
|
+
var cell = `<div class="grid-cell user-card">`;
|
|
43
|
+
cell += `<a class="card-link" target="_blank" rel="external nofollow noopener noreferrer" href="${item.html_url || item.url}">`;;
|
|
44
|
+
cell += `<img src="${item.avatar_url || item.avatar || item.icon || default_avatar}" onerror="javascript:this.removeAttribute(\'data-src\');this.src=\'${default_avatar}\';"/>`;
|
|
45
|
+
cell += `<div class="name image-meta">`;
|
|
46
|
+
cell += `<span class="image-caption">${item.title || item.login}</span>`;
|
|
47
|
+
cell += `</div>`;
|
|
48
|
+
cell += `</a>`;
|
|
49
|
+
cell += `</div>`;
|
|
50
|
+
$(el).find('.grid-box').append(cell);
|
|
51
|
+
}
|
|
52
|
+
window.wrapLazyloadImages(el);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
});
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
<%
|
|
2
|
-
function parseURL() {
|
|
3
|
-
const source = page.source || ''
|
|
4
|
-
var url
|
|
5
|
-
for (let id of Object.keys(map)) {
|
|
6
|
-
if (source.startsWith(id) && map[id]) {
|
|
7
|
-
return source.replace(id, map[id])
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
function layoutDiv() {
|
|
12
|
-
const url = parseURL()
|
|
13
|
-
if (url == null) {
|
|
14
|
-
return ''
|
|
15
|
-
}
|
|
16
|
-
var el = ''
|
|
17
|
-
el += `<a class="edit" href="${url_for(url)}">`
|
|
18
|
-
el += icon('default:edit')
|
|
19
|
-
el += `<span>${__('btn.edit')}</span>`
|
|
20
|
-
el += `</a>`
|
|
21
|
-
return el
|
|
22
|
-
}
|
|
23
|
-
%>
|
|
24
|
-
<%- layoutDiv() %>
|