hexo-theme-stellar 1.29.0 → 1.30.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 +29 -9
- package/_data/chat_users.yml +0 -0
- package/_data/widgets.yml +7 -0
- package/languages/zh-TW.yml +2 -2
- package/layout/_partial/head.ejs +2 -1
- package/layout/_partial/main/navbar/nav_tabs_blog.ejs +10 -10
- package/layout/_partial/scripts/defines.ejs +3 -0
- package/layout/_partial/scripts/services.ejs +91 -0
- package/layout/_partial/scripts/theme.ejs +5 -0
- package/layout/_partial/scripts/utils.ejs +67 -7
- package/layout/_partial/scripts.ejs +1 -1
- package/layout/_plugins/mermaid.ejs +1 -1
- package/layout/_plugins/scrollreveal.ejs +1 -0
- package/layout/_plugins/search/algolia_search.ejs +11 -12
- package/layout/layout.ejs +1 -1
- package/package.json +1 -1
- package/scripts/events/lib/config.js +3 -0
- package/scripts/events/lib/doc_tree.js +1 -6
- package/scripts/filters/index.js +26 -0
- package/scripts/generators/notebooks.js +1 -1
- package/scripts/generators/search.js +21 -2
- package/scripts/helpers/dynamic_color.js +138 -0
- package/scripts/tags/index.js +1 -0
- package/scripts/tags/lib/box.js +1 -1
- package/scripts/tags/lib/chat.js +515 -0
- package/scripts/tags/lib/folders.js +1 -1
- package/scripts/tags/lib/folding.js +2 -2
- package/scripts/tags/lib/sites.js +1 -1
- package/scripts/tags/lib/video.js +7 -2
- package/source/css/_components/tag-plugins/chat.styl +621 -0
- package/source/css/_components/tag-plugins/friends.styl +10 -0
- package/source/css/_components/tag-plugins/sites.styl +12 -0
- package/source/css/_components/tag-plugins/tabs.styl +5 -2
- package/source/css/_custom.styl +1 -0
- package/source/css/_defines/func.styl +7 -6
- package/source/css/_defines/theme.styl +38 -0
- package/source/css/_plugins/katex.styl +0 -1
- package/source/js/plugins/download-file.js +198 -0
- package/source/js/plugins/video.js +65 -0
- package/source/js/plugins/voice.js +438 -0
- package/source/js/search/algolia-search.js +63 -61
- package/source/js/services/artalk_latest_comment.js +33 -0
- package/source/js/services/friends.js +4 -0
- package/source/js/services/giscus_latest_comment.js +36 -0
- package/source/js/services/memos.js +91 -69
- package/source/js/services/sites.js +4 -0
- package/source/js/services/twikoo_latest_comment.js +47 -0
- package/source/js/services/waline_latest_comment.js +32 -0
package/_config.yml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
######## Stellar info ########
|
|
2
2
|
stellar:
|
|
3
|
-
version: '1.
|
|
3
|
+
version: '1.30.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
|
|
@@ -10,8 +10,8 @@ stellar:
|
|
|
10
10
|
######## head tags ########
|
|
11
11
|
preconnect:
|
|
12
12
|
# - https://gcore.jsdelivr.net
|
|
13
|
+
# - https://cdn.jsdelivr.net
|
|
13
14
|
# - https://unpkg.com
|
|
14
|
-
# - https://cdn.bootcdn.net
|
|
15
15
|
|
|
16
16
|
open_graph:
|
|
17
17
|
enable: true
|
|
@@ -197,10 +197,12 @@ search:
|
|
|
197
197
|
field: all # post, page, all
|
|
198
198
|
path: /search.json # 搜索文件存放位置
|
|
199
199
|
content: true # 是否搜索内容
|
|
200
|
+
skip_search: # 指定 path 中的内容不被搜索。
|
|
200
201
|
algolia_search: # Docsearch https://docsearch.algolia.com/apply/ 申请
|
|
201
202
|
appId:
|
|
202
203
|
apiKey:
|
|
203
204
|
indexName:
|
|
205
|
+
js: https://gcore.jsdelivr.net/algoliasearch/3/algoliasearch.min.js
|
|
204
206
|
|
|
205
207
|
|
|
206
208
|
######## Comments ########
|
|
@@ -416,12 +418,14 @@ tag_plugins:
|
|
|
416
418
|
layout: grid # grid / flow
|
|
417
419
|
size: mix # s / m / l / xl / mix
|
|
418
420
|
ratio: square # origin / square
|
|
421
|
+
chat:
|
|
422
|
+
api: https://siteinfo.listentothewind.cn/api/v1
|
|
419
423
|
|
|
420
424
|
|
|
421
425
|
# 基础依赖
|
|
422
426
|
dependencies:
|
|
423
|
-
jquery: https://cdn.
|
|
424
|
-
marked: https://cdn.
|
|
427
|
+
jquery: https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js
|
|
428
|
+
marked: https://cdn.jsdelivr.net/npm/marked@13.0.1/lib/marked.umd.min.js
|
|
425
429
|
|
|
426
430
|
|
|
427
431
|
# 内置服务,按需加载(页面内用到了就会加载,没有用到就不会加载)
|
|
@@ -451,6 +455,22 @@ data_services:
|
|
|
451
455
|
js: /js/services/weibo.js
|
|
452
456
|
memos:
|
|
453
457
|
js: /js/services/memos.js
|
|
458
|
+
# chat
|
|
459
|
+
voice:
|
|
460
|
+
js: /js/plugins/voice.js
|
|
461
|
+
video:
|
|
462
|
+
js: /js/plugins/video.js
|
|
463
|
+
download-file:
|
|
464
|
+
js: /js/plugins/download-file.js
|
|
465
|
+
# 最新评论获取类
|
|
466
|
+
twikoo:
|
|
467
|
+
js: /js/services/twikoo_latest_comment.js
|
|
468
|
+
waline:
|
|
469
|
+
js: /js/services/waline_latest_comment.js
|
|
470
|
+
artalk:
|
|
471
|
+
js: /js/services/artalk_latest_comment.js
|
|
472
|
+
giscus:
|
|
473
|
+
js: /js/services/giscus_latest_comment.js
|
|
454
474
|
|
|
455
475
|
|
|
456
476
|
# 扩展插件接入方法:(插件名下面用 #plugin# 代替)
|
|
@@ -466,13 +486,13 @@ plugins:
|
|
|
466
486
|
preload:
|
|
467
487
|
enable: true
|
|
468
488
|
service: flying_pages # flying_pages
|
|
469
|
-
flying_pages: https://cdn.
|
|
489
|
+
flying_pages: https://cdn.jsdelivr.net/npm/flying-pages@2/flying-pages.min.js
|
|
470
490
|
|
|
471
491
|
# lazyload
|
|
472
492
|
# https://www.npmjs.com/package/vanilla-lazyload
|
|
473
493
|
lazyload:
|
|
474
494
|
enable: true # [hexo clean && hexo s] is required after changing this value.
|
|
475
|
-
js: https://cdn.
|
|
495
|
+
js: https://cdn.jsdelivr.net/npm/vanilla-lazyload@19.1.3/dist/lazyload.min.js
|
|
476
496
|
transition: fade # blur, fade
|
|
477
497
|
|
|
478
498
|
# https://fancyapps.com/docs/ui/fancybox/
|
|
@@ -480,8 +500,8 @@ plugins:
|
|
|
480
500
|
fancybox:
|
|
481
501
|
enable: true
|
|
482
502
|
loader: /js/plugins/fancybox-loader.js
|
|
483
|
-
js: https://cdn.
|
|
484
|
-
css: https://cdn.
|
|
503
|
+
js: https://cdn.jsdelivr.net/npm/@fancyapps/ui@5.0/dist/fancybox/fancybox.umd.js
|
|
504
|
+
css: https://cdn.jsdelivr.net/npm/@fancyapps/ui@5.0/dist/fancybox/fancybox.css
|
|
485
505
|
# 让 md 语法图片支持放大可以这样写: .md-text img:not([class]), .md-text .image img
|
|
486
506
|
# 可以处理评论区的图片(不支持 iframe 类评论系统)例如:
|
|
487
507
|
# 使用 twikoo 评论可以写: .tk-content img:not([class*="emo"])
|
|
@@ -497,7 +517,7 @@ plugins:
|
|
|
497
517
|
# https://scrollrevealjs.org/api/reveal.html
|
|
498
518
|
scrollreveal:
|
|
499
519
|
enable: #true
|
|
500
|
-
js: https://cdn.
|
|
520
|
+
js: https://cdn.jsdelivr.net/npm/scrollreveal@4.0.9/dist/scrollreveal.min.js
|
|
501
521
|
distance: 16px
|
|
502
522
|
duration: 800 # ms
|
|
503
523
|
interval: 100 # ms
|
|
File without changes
|
package/_data/widgets.yml
CHANGED
|
@@ -71,6 +71,13 @@ timeline:
|
|
|
71
71
|
type: # 默认不用写,如果是友链朋友圈数据请写 fcircle
|
|
72
72
|
limit: # 默认通过 api 上增加 per_page 来设置,如果是友链朋友圈,可通过这个设置数量
|
|
73
73
|
|
|
74
|
+
latest_comment:
|
|
75
|
+
layout: timeline
|
|
76
|
+
title: 最新评论
|
|
77
|
+
api: # 参照文档获取服务对应的api
|
|
78
|
+
type: # 选择评论服务
|
|
79
|
+
limit: 16 # 限制获取数量
|
|
80
|
+
|
|
74
81
|
tagtree:
|
|
75
82
|
layout: tagtree
|
|
76
83
|
expand_all: false # 是否展开所有节点
|
package/languages/zh-TW.yml
CHANGED
package/layout/_partial/head.ejs
CHANGED
|
@@ -119,7 +119,8 @@ function custom_inject() {
|
|
|
119
119
|
<%- feed_tag(config.feed.path, {title: config.title}) %>
|
|
120
120
|
<% } %>
|
|
121
121
|
|
|
122
|
-
<link rel="stylesheet" href="<%- `${theme.stellar.main_css}?v=${stellar_info('version')}` %>">
|
|
122
|
+
<link rel="stylesheet" href="<%- url_for(`${theme.stellar.main_css}?v=${stellar_info('version')}`) %>">
|
|
123
|
+
|
|
123
124
|
|
|
124
125
|
<% if (config.favicon) { %>
|
|
125
126
|
<%- favicon_tag(config.favicon) %>
|
|
@@ -11,37 +11,37 @@ function layoutDiv() {
|
|
|
11
11
|
|
|
12
12
|
if (site.categories && site.categories.length > 0) {
|
|
13
13
|
if (page.category) {
|
|
14
|
-
el += '<a class="active" href="' + url_for(config.category_dir) + '">' + __("btn.category") + __("symbol.colon") + page.category + '</a>';
|
|
14
|
+
el += '<a class="active" href="' + url_for(config.category_dir) + '/">' + __("btn.category") + __("symbol.colon") + page.category + '</a>';
|
|
15
15
|
} else if (page.layout == "categories") {
|
|
16
|
-
el += '<a class="active" href="' + url_for(config.category_dir) + '">' + __("btn.categories") + '</a>';
|
|
16
|
+
el += '<a class="active" href="' + url_for(config.category_dir) + '/">' + __("btn.categories") + '</a>';
|
|
17
17
|
} else {
|
|
18
|
-
el += '<a href="' + url_for(config.category_dir) + '">' + __("btn.categories") + '</a>';
|
|
18
|
+
el += '<a href="' + url_for(config.category_dir) + '/">' + __("btn.categories") + '</a>';
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
if (site.tags && site.tags.length > 0) {
|
|
23
23
|
if (page.tag) {
|
|
24
|
-
el += '<a class="active" href="' + url_for(config.tag_dir) + '">' + __("btn.tag") + __("symbol.colon") + page.tag + '</a>';
|
|
24
|
+
el += '<a class="active" href="' + url_for(config.tag_dir) + '/">' + __("btn.tag") + __("symbol.colon") + page.tag + '</a>';
|
|
25
25
|
} else if (page.layout == "tags") {
|
|
26
|
-
el += '<a class="active" href="' + url_for(config.tag_dir) + '">' + __("btn.tags") + '</a>';
|
|
26
|
+
el += '<a class="active" href="' + url_for(config.tag_dir) + '/">' + __("btn.tags") + '</a>';
|
|
27
27
|
} else {
|
|
28
|
-
el += '<a href="' + url_for(config.tag_dir) + '">' + __("btn.tags") + '</a>';
|
|
28
|
+
el += '<a href="' + url_for(config.tag_dir) + '/">' + __("btn.tags") + '</a>';
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
if (theme.topic?.publish_list?.length > 0) {
|
|
33
33
|
if (page.layout == 'index_topic') {
|
|
34
|
-
el += '<a class="active" href="' + url_for(theme.site_tree.index_topic.base_dir) + '">' + __("btn.topic") + '</a>';
|
|
34
|
+
el += '<a class="active" href="' + url_for(theme.site_tree.index_topic.base_dir) + '/">' + __("btn.topic") + '</a>';
|
|
35
35
|
} else {
|
|
36
|
-
el += '<a href="' + url_for(theme.site_tree.index_topic.base_dir) + '">' + __("btn.topic") + '</a>';
|
|
36
|
+
el += '<a href="' + url_for(theme.site_tree.index_topic.base_dir) + '/">' + __("btn.topic") + '</a>';
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
if (site.posts && site.posts.length > 0) {
|
|
41
41
|
if (is_archive()) {
|
|
42
|
-
el += '<a class="active" href="' + url_for(config.archive_dir) + '">' + __("btn.archives") + '</a>';
|
|
42
|
+
el += '<a class="active" href="' + url_for(config.archive_dir) + '/">' + __("btn.archives") + '</a>';
|
|
43
43
|
} else {
|
|
44
|
-
el += '<a href="' + url_for(config.archive_dir) + '">' + __("btn.archives") + '</a>';
|
|
44
|
+
el += '<a href="' + url_for(config.archive_dir) + '/">' + __("btn.archives") + '</a>';
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
|
|
@@ -10,6 +10,27 @@
|
|
|
10
10
|
setCardLink(ctx.cardlinks);
|
|
11
11
|
});
|
|
12
12
|
}
|
|
13
|
+
} else if (id == 'voice') {
|
|
14
|
+
ctx.voiceAudios = document.querySelectorAll('.voice>audio');
|
|
15
|
+
if (ctx.voiceAudios?.length > 0) {
|
|
16
|
+
utils.js(js, { defer: true }).then(function () {
|
|
17
|
+
createVoiceDom(ctx.voiceAudios);
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
} else if (id == 'video') {
|
|
21
|
+
ctx.videos = document.querySelectorAll('.video>video');
|
|
22
|
+
if (ctx.videos?.length > 0) {
|
|
23
|
+
utils.js(js, { defer: true }).then(function () {
|
|
24
|
+
videoEvents(ctx.videos);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
} else if (id == 'download-file') {
|
|
28
|
+
ctx.files = document.querySelectorAll('.file');
|
|
29
|
+
if (ctx.files?.length > 0) {
|
|
30
|
+
utils.js(js, { defer: true }).then(function () {
|
|
31
|
+
downloadFileEvent(ctx.files);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
13
34
|
} else {
|
|
14
35
|
const els = document.getElementsByClassName(`ds-${id}`);
|
|
15
36
|
if (els?.length > 0) {
|
|
@@ -25,5 +46,75 @@
|
|
|
25
46
|
}
|
|
26
47
|
}
|
|
27
48
|
}
|
|
49
|
+
|
|
50
|
+
// chat iphone time
|
|
51
|
+
let phoneTimes = document.querySelectorAll('.chat .status-bar .time');
|
|
52
|
+
|
|
53
|
+
if (phoneTimes.length > 0) {
|
|
54
|
+
NowTime();
|
|
55
|
+
var date = new Date();
|
|
56
|
+
var sec = date.getSeconds();
|
|
57
|
+
var firstAdjustInterval = setInterval(firstAdjustTime, 1000 * (60 - sec));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function firstAdjustTime() {
|
|
61
|
+
NowTime();
|
|
62
|
+
clearInterval(firstAdjustInterval);
|
|
63
|
+
setInterval(NowTime, 1000 * 60);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function NowTime() {
|
|
67
|
+
for (let i = 0; i < phoneTimes.length; ++i) {
|
|
68
|
+
var timeSpan = phoneTimes[i];
|
|
69
|
+
var date = new Date();
|
|
70
|
+
var hour = date.getHours();
|
|
71
|
+
var min = date.getMinutes();
|
|
72
|
+
timeSpan.innerHTML = check(hour) + ":" + check(min);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
function check(val) {
|
|
77
|
+
if (val < 10) {
|
|
78
|
+
return ("0" + val);
|
|
79
|
+
}
|
|
80
|
+
return (val);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// chat quote
|
|
84
|
+
const chat_quote_obverser = new IntersectionObserver((entries, observer) => {
|
|
85
|
+
entries.filter((entry) => { return entry.isIntersecting }).sort((a, b) => a.intersectionRect.y !== b.intersectionRect.y ? a.intersectionRect.y - b.intersectionRect.y : a.intersectionRect.x - b.intersectionRect.x).forEach((entry, index) => {
|
|
86
|
+
observer.unobserve(entry.target);
|
|
87
|
+
setTimeout(() => {
|
|
88
|
+
entry.target.classList.add('quote-blink');
|
|
89
|
+
setTimeout(() => {
|
|
90
|
+
entry.target.classList.remove('quote-blink');
|
|
91
|
+
}, 1000);
|
|
92
|
+
}, Math.max(100, 16) * (index + 1));
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
var chatQuotes = document.querySelectorAll(".chat .talk .quote");
|
|
97
|
+
chatQuotes.forEach((quote) => {
|
|
98
|
+
quote.addEventListener('click', function () {
|
|
99
|
+
var chatCellDom = document.getElementById("quote-" + quote.getAttribute("quotedCellTag"));
|
|
100
|
+
if (chatCellDom) {
|
|
101
|
+
var chatDiv = chatCellDom.parentElement;
|
|
102
|
+
var mid = chatDiv.clientHeight / 2;
|
|
103
|
+
var offsetTop = chatCellDom.offsetTop;
|
|
104
|
+
if (offsetTop > mid - chatCellDom.clientHeight / 2) {
|
|
105
|
+
chatDiv.scrollTo({
|
|
106
|
+
top: chatCellDom.offsetTop - mid + chatCellDom.clientHeight / 2,
|
|
107
|
+
behavior: "smooth"
|
|
108
|
+
});
|
|
109
|
+
} else {
|
|
110
|
+
chatDiv.scrollTo({
|
|
111
|
+
top: 0,
|
|
112
|
+
behavior: "smooth"
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
chat_quote_obverser.observe(chatCellDom);
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
});
|
|
28
119
|
});
|
|
29
120
|
</script>
|
|
@@ -43,6 +43,8 @@
|
|
|
43
43
|
}
|
|
44
44
|
applyTheme(newTheme)
|
|
45
45
|
window.localStorage.setItem('Stellar.theme', newTheme)
|
|
46
|
+
utils.dark.mode = newTheme === 'auto' ? (window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light") : newTheme;
|
|
47
|
+
utils.dark.method.toggle.start();
|
|
46
48
|
|
|
47
49
|
const messages = {
|
|
48
50
|
light: `<%- __('message.theme_switched.light') %>`,
|
|
@@ -57,6 +59,9 @@
|
|
|
57
59
|
const theme = window.localStorage.getItem('Stellar.theme')
|
|
58
60
|
if (theme !== null) {
|
|
59
61
|
applyTheme(theme)
|
|
62
|
+
} else {
|
|
63
|
+
utils.dark.mode = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
60
64
|
}
|
|
65
|
+
utils.dark.method.toggle.start();
|
|
61
66
|
})()
|
|
62
67
|
</script>
|
|
@@ -1,4 +1,44 @@
|
|
|
1
1
|
<script type="text/javascript">
|
|
2
|
+
function RunItem() {
|
|
3
|
+
this.list = []; // 存放回调函数
|
|
4
|
+
this.start = () => {
|
|
5
|
+
for (var i = 0; i < this.list.length; i++) {
|
|
6
|
+
this.list[i].run();
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
this.push = (fn, name, setRequestAnimationFrame = true) => {
|
|
10
|
+
let myfn = fn
|
|
11
|
+
if (setRequestAnimationFrame) {
|
|
12
|
+
myfn = () => {
|
|
13
|
+
utils.requestAnimationFrame(fn)
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
var f = new Item(myfn, name);
|
|
17
|
+
this.list.push(f);
|
|
18
|
+
};
|
|
19
|
+
this.remove = (name) => {
|
|
20
|
+
for (let index = 0; index < this.list.length; index++) {
|
|
21
|
+
const e = this.list[index];
|
|
22
|
+
if (e.name == name) {
|
|
23
|
+
this.list.splice(index, 1);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
// 构造一个可以run的对象
|
|
28
|
+
function Item(fn, name) {
|
|
29
|
+
// 函数名称
|
|
30
|
+
this.name = name || fn.name;
|
|
31
|
+
// run方法
|
|
32
|
+
this.run = () => {
|
|
33
|
+
try {
|
|
34
|
+
fn()
|
|
35
|
+
} catch (error) {
|
|
36
|
+
console.log(error);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
2
42
|
const utils = {
|
|
3
43
|
// 懒加载 css https://github.com/filamentgroup/loadCSS
|
|
4
44
|
css: (href, before, media, attributes) => {
|
|
@@ -61,7 +101,7 @@
|
|
|
61
101
|
|
|
62
102
|
js: (src, opt) => new Promise((resolve, reject) => {
|
|
63
103
|
var script = document.createElement('script');
|
|
64
|
-
if (src.startsWith('/')){
|
|
104
|
+
if (src.startsWith('/')) {
|
|
65
105
|
src = ctx.root + src.substring(1);
|
|
66
106
|
}
|
|
67
107
|
script.src = src;
|
|
@@ -74,7 +114,7 @@
|
|
|
74
114
|
script.async = true
|
|
75
115
|
}
|
|
76
116
|
script.onerror = reject
|
|
77
|
-
script.onload = script.onreadystatechange = function() {
|
|
117
|
+
script.onload = script.onreadystatechange = function () {
|
|
78
118
|
const loadState = this.readyState
|
|
79
119
|
if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
|
|
80
120
|
script.onload = script.onreadystatechange = null
|
|
@@ -90,7 +130,7 @@
|
|
|
90
130
|
fn()
|
|
91
131
|
}
|
|
92
132
|
},
|
|
93
|
-
|
|
133
|
+
|
|
94
134
|
onLoading: (el) => {
|
|
95
135
|
if (el) {
|
|
96
136
|
$(el).append('<div class="loading-wrap"><svg xmlns="http://www.w3.org/2000/svg" width="2em" height="2em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-width="2"><path stroke-dasharray="60" stroke-dashoffset="60" stroke-opacity=".3" d="M12 3C16.9706 3 21 7.02944 21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3Z"><animate fill="freeze" attributeName="stroke-dashoffset" dur="1.3s" values="60;0"/></path><path stroke-dasharray="15" stroke-dashoffset="15" d="M12 3C16.9706 3 21 7.02944 21 12"><animate fill="freeze" attributeName="stroke-dashoffset" dur="0.3s" values="15;0"/><animateTransform attributeName="transform" dur="1.5s" repeatCount="indefinite" type="rotate" values="0 12 12;360 12 12"/></path></g></svg></div>');
|
|
@@ -124,7 +164,7 @@
|
|
|
124
164
|
}
|
|
125
165
|
}
|
|
126
166
|
}, 5000);
|
|
127
|
-
fetch(url).then(function(response) {
|
|
167
|
+
fetch(url).then(function (response) {
|
|
128
168
|
if (status !== 2) {
|
|
129
169
|
clearTimeout(timer);
|
|
130
170
|
resolve(response);
|
|
@@ -135,11 +175,11 @@
|
|
|
135
175
|
return response.json();
|
|
136
176
|
}
|
|
137
177
|
throw new Error('Network response was not ok.');
|
|
138
|
-
}).then(function(data) {
|
|
178
|
+
}).then(function (data) {
|
|
139
179
|
retryTimes = 0;
|
|
140
180
|
utils.onLoadSuccess(el);
|
|
141
181
|
callback(data);
|
|
142
|
-
}).catch(function(error) {
|
|
182
|
+
}).catch(function (error) {
|
|
143
183
|
if (retryTimes > 0) {
|
|
144
184
|
retryTimes -= 1;
|
|
145
185
|
setTimeout(() => {
|
|
@@ -154,5 +194,25 @@
|
|
|
154
194
|
}
|
|
155
195
|
req();
|
|
156
196
|
},
|
|
197
|
+
/********************** requestAnimationFrame ********************************/
|
|
198
|
+
// 1、requestAnimationFrame 会把每一帧中的所有 DOM 操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率,一般来说,这个频率为每秒60帧。
|
|
199
|
+
// 2、在隐藏或不可见的元素中,requestAnimationFrame 将不会进行重绘或回流,这当然就意味着更少的的 cpu,gpu 和内存使用量。
|
|
200
|
+
requestAnimationFrame: (fn) => {
|
|
201
|
+
if (!window.requestAnimationFrame) {
|
|
202
|
+
window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame;
|
|
203
|
+
}
|
|
204
|
+
window.requestAnimationFrame(fn)
|
|
205
|
+
},
|
|
206
|
+
dark: {},
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
// utils.dark.mode 当前模式 dark or light
|
|
210
|
+
// utils.dark.toggle() 暗黑模式触发器
|
|
211
|
+
// utils.dark.push(callBack[,"callBackName"]) 传入触发器回调函数
|
|
212
|
+
utils.dark.method = {
|
|
213
|
+
toggle: new RunItem(),
|
|
157
214
|
};
|
|
158
|
-
|
|
215
|
+
utils.dark = Object.assign(utils.dark, {
|
|
216
|
+
push: utils.dark.method.toggle.push,
|
|
217
|
+
});
|
|
218
|
+
</script>
|
|
@@ -21,7 +21,7 @@ function custom_inject() {
|
|
|
21
21
|
<%- partial('scripts/tagtree') %>
|
|
22
22
|
|
|
23
23
|
<!-- required -->
|
|
24
|
-
<script src="<%- `${theme.stellar.main_js}?v=${stellar_info('version')}` %>" defer></script>
|
|
24
|
+
<script src="<%- url_for(`${theme.stellar.main_js}?v=${stellar_info('version')}`) %>" defer></script>
|
|
25
25
|
|
|
26
26
|
<%- partial('scripts/theme') %>
|
|
27
27
|
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
2
|
+
window.addEventListener('DOMContentLoaded', (event) => {
|
|
3
|
+
window.searchConfig = {
|
|
4
|
+
appId: '<%- conf.appId %>',
|
|
5
|
+
apiKey: '<%- conf.apiKey %>',
|
|
6
|
+
indexName: '<%- conf.indexName %>',
|
|
7
|
+
js: '<%- conf.js %>',
|
|
8
|
+
hitsPerPage: 100,
|
|
9
|
+
};
|
|
10
|
+
utils.js('/js/search/algolia-search.js', { defer: true });
|
|
11
|
+
});
|
|
12
|
+
</script>
|
package/layout/layout.ejs
CHANGED
|
@@ -46,7 +46,7 @@ if (theme.style.prefers_theme === 'auto') {
|
|
|
46
46
|
html += `<body>`
|
|
47
47
|
html += site_background
|
|
48
48
|
html += partial('_partial/cover/index')
|
|
49
|
-
html += `<div class="l_body
|
|
49
|
+
html += `<div class="l_body ${page_type} ${article_type}" id="start" layout="${page.layout}" ${indent ? 'text-indent' : ''}>`
|
|
50
50
|
html += `<aside class="l_left">`
|
|
51
51
|
html += `<div class="leftbar-container${theme.style.leftbar?.blur ? ' leftbar-blur' : ''}">`
|
|
52
52
|
html += partial('_partial/sidebar/index_leftbar')
|
package/package.json
CHANGED
|
@@ -63,7 +63,7 @@ module.exports = ctx => {
|
|
|
63
63
|
const pages = ctx.locals.get('pages')
|
|
64
64
|
// wiki 所有页面
|
|
65
65
|
const wiki_pages = pages.filter(p => (p.wiki != null)).map(p => new WikiPage(p))
|
|
66
|
-
const wiki_list = Object.keys(wiki.tree)
|
|
66
|
+
const wiki_list = Object.keys(wiki.tree).filter(id => wiki_pages.some(p => p.wiki === id))
|
|
67
67
|
// 上架的项目列表
|
|
68
68
|
wiki.shelf = ctx.locals.get('data').wiki || []
|
|
69
69
|
|
|
@@ -99,11 +99,6 @@ module.exports = ctx => {
|
|
|
99
99
|
let id = wiki_list[i];
|
|
100
100
|
let item = wiki.tree[id]
|
|
101
101
|
let sub_pages = wiki_pages.filter(p => p.wiki === id)
|
|
102
|
-
if (!sub_pages || sub_pages.length == 0) {
|
|
103
|
-
wiki_list.splice(i, 1)
|
|
104
|
-
delete wiki.tree[id]
|
|
105
|
-
continue
|
|
106
|
-
}
|
|
107
102
|
|
|
108
103
|
// 首页
|
|
109
104
|
// 未特别指定首页时,获取TOC第一页作为首页
|
package/scripts/filters/index.js
CHANGED
|
@@ -2,3 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
hexo.extend.filter.register('after_render:html', require('./lib/img_lazyload').processSite);
|
|
4
4
|
hexo.extend.filter.register('after_render:html', require('./lib/img_onerror').processSite);
|
|
5
|
+
|
|
6
|
+
function change_image(data) {
|
|
7
|
+
if (this.theme.config.tag_plugins.image.parse_markdown) {
|
|
8
|
+
// data.content = data.content.replace(
|
|
9
|
+
// /!\[(.*?)\]\((.*?)\s*(?:"(.*?)")?\)/g,
|
|
10
|
+
// '{% image $2 $3 %}'
|
|
11
|
+
// );
|
|
12
|
+
let splited_content = data.content.split(/(```[\s\S]*?```|{%\s*gallery\s*%}[\s\S]*?{%\s*endgallery\s*%})/g);
|
|
13
|
+
splited_content = splited_content.map((s) => {
|
|
14
|
+
let matches_no = s.match(/(```[\s\S]*?```|{%\s*gallery\s*%}[\s\S]*?{%\s*endgallery\s*%})/i);
|
|
15
|
+
let matches_img = s.match(/!\[(.*?)\]\((.*?)\s*(?:"(.*?)")?\)/i);
|
|
16
|
+
if (!matches_no && matches_img) {
|
|
17
|
+
s = s.replace(
|
|
18
|
+
/!\[(.*?)\]\((.*?)\s*(?:"(.*?)")?\)/g,
|
|
19
|
+
`{% image $2 $3 %}`
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
return s;
|
|
23
|
+
});
|
|
24
|
+
data.content = splited_content.join('');
|
|
25
|
+
}
|
|
26
|
+
return data;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
hexo.extend.filter.register('before_post_render', change_image, 9);
|
|
30
|
+
|
|
@@ -30,7 +30,7 @@ function paginationWithEmpty(base, posts, options={}) {
|
|
|
30
30
|
|
|
31
31
|
hexo.extend.generator.register('notebooks', function (locals) {
|
|
32
32
|
const { site_tree, notebooks } = hexo.theme.config
|
|
33
|
-
if (notebooks.tree.length === 0) {
|
|
33
|
+
if (!notebooks?.tree || Object.keys(notebooks.tree).length === 0) {
|
|
34
34
|
return []
|
|
35
35
|
}
|
|
36
36
|
|
|
@@ -31,11 +31,13 @@ hexo.extend.generator.register('search_json_generator', function (locals) {
|
|
|
31
31
|
temp_post.path = root + post.path
|
|
32
32
|
}
|
|
33
33
|
if (cfg.content != false && post.content) {
|
|
34
|
-
var content = stripHTML(post.content).trim()
|
|
34
|
+
var content = stripHTML(post.content.replace(/<span class="line">\d+<\/span>/g, '')).trim()
|
|
35
35
|
// 部分HTML标签
|
|
36
36
|
content = content.replace(/<iframe[\s|\S]+iframe>/g, '')
|
|
37
37
|
content = content.replace(/<hr>/g, '')
|
|
38
38
|
content = content.replace(/<br>/g, '')
|
|
39
|
+
// 去除HTML实体
|
|
40
|
+
content = content.replace(/&[^\s;]+;/g, "")
|
|
39
41
|
// 换行符换成空格
|
|
40
42
|
content = content.replace(/\\n/g, ' ')
|
|
41
43
|
content = content.replace(/\n/g, ' ')
|
|
@@ -60,8 +62,22 @@ hexo.extend.generator.register('search_json_generator', function (locals) {
|
|
|
60
62
|
return temp_post
|
|
61
63
|
}
|
|
62
64
|
|
|
65
|
+
function matchAndExit(path, patterns) {
|
|
66
|
+
for (let pattern of patterns) {
|
|
67
|
+
const regexPattern = new RegExp('^' + pattern.replace(/\*/g, '.*') + '$');
|
|
68
|
+
if (path.match(regexPattern)) {
|
|
69
|
+
// console.log("Matched pattern:", pattern);
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
|
|
63
76
|
if (posts) {
|
|
64
77
|
posts.each(function(post) {
|
|
78
|
+
var layout_list = ["post"]
|
|
79
|
+
if (!layout_list.includes(post.layout)) return
|
|
80
|
+
if (cfg.skip_search && matchAndExit(post.path, cfg.skip_search)) return
|
|
65
81
|
if (post.indexing == false) return
|
|
66
82
|
let temp_post = generateJson(post)
|
|
67
83
|
res.push(temp_post)
|
|
@@ -69,6 +85,9 @@ hexo.extend.generator.register('search_json_generator', function (locals) {
|
|
|
69
85
|
}
|
|
70
86
|
if (pages) {
|
|
71
87
|
pages.each(function(page) {
|
|
88
|
+
var layout_list = ["page", "wiki"]
|
|
89
|
+
if (!layout_list.includes(page.layout)) return
|
|
90
|
+
if (cfg.skip_search && matchAndExit(page.path, cfg.skip_search)) return
|
|
72
91
|
if (page.indexing == false) return
|
|
73
92
|
let temp_post = generateJson(page)
|
|
74
93
|
res.push(temp_post)
|
|
@@ -78,4 +97,4 @@ hexo.extend.generator.register('search_json_generator', function (locals) {
|
|
|
78
97
|
path: cfg.path,
|
|
79
98
|
data: JSON.stringify(res)
|
|
80
99
|
}
|
|
81
|
-
})
|
|
100
|
+
})
|