hexo-theme-solitude 2.1.5 → 2.1.7
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 +18 -19
- package/languages/default.yml +173 -173
- package/layout/archive.pug +3 -1
- package/layout/category.pug +3 -1
- package/layout/includes/head/page_config.pug +3 -1
- package/layout/includes/loading.pug +1 -1
- package/layout/includes/rightmenu.pug +6 -5
- package/layout/includes/widgets/aside/aside.pug +1 -1
- package/layout/includes/widgets/page/links/banner.pug +15 -12
- package/layout/includes/widgets/rightside/show.pug +1 -1
- package/layout/includes/widgets/third-party/hot/artalk.pug +56 -0
- package/layout/includes/widgets/third-party/hot/twikoo.pug +57 -0
- package/layout/includes/widgets/third-party/pjax.pug +2 -1
- package/layout/index.pug +1 -1
- package/layout/tag.pug +2 -0
- package/package.json +1 -1
- package/scripts/event/cdn.js +1 -1
- package/scripts/event/init.js +0 -1
- package/scripts/event/merge_config.js +14 -39
- package/scripts/filter/default.js +20 -21
- package/scripts/filter/lazyload.js +2 -4
- package/scripts/helper/getArchiveLength.js +9 -11
- package/scripts/helper/related_post.js +56 -56
- package/scripts/tags/article.js +1 -1
- package/scripts/tags/tabs.js +28 -46
- package/source/css/_comments/twikoo.styl +3 -3
- package/source/css/_highlight/highlight/diff.styl +13 -1
- package/source/css/_highlight/index.styl +9 -0
- package/source/css/_highlight/prismjs/diff.styl +13 -1
- package/source/css/_layout/article-container.styl +1 -1
- package/source/css/_layout/recent-post.styl +2 -2
- package/source/img/error_load.avif +0 -0
- package/source/js/covercolor/api.js +29 -14
- package/source/js/covercolor/ave.js +38 -24
- package/source/js/covercolor/local.js +52 -52
- package/source/js/main.js +238 -240
- package/source/js/music.js +21 -39
- package/source/js/right_menu.js +67 -132
- package/source/js/third_party/barrage.min.js +93 -1
- package/source/js/third_party/envelope.min.js +1 -1
- package/source/js/third_party/post_ai.min.js +184 -1
- package/source/js/tw_cn.js +19 -18
- package/source/js/utils.js +50 -57
- package/layout/includes/widgets/home/hot/artalk.pug +0 -45
- package/layout/includes/widgets/home/hot/twikoo.pug +0 -46
- package/source/img/loading.avif +0 -0
- /package/layout/includes/widgets/{home → third-party}/hot/index.pug +0 -0
@@ -0,0 +1,56 @@
|
|
1
|
+
- const { server, site } = theme.artalk
|
2
|
+
|
3
|
+
script.
|
4
|
+
function updatePostsBasedOnComments() {
|
5
|
+
const location = window.location;
|
6
|
+
const posts = Array.from(document.querySelectorAll('.recent-post-item[onclick] .post_cover a'))
|
7
|
+
.map(item => item.href.replace(location, ''));
|
8
|
+
|
9
|
+
fetchCommentsData(posts)
|
10
|
+
.then(data => updatePostElements(posts, data))
|
11
|
+
.catch(error => console.error("Error fetching comments:", error));
|
12
|
+
}
|
13
|
+
|
14
|
+
function fetchCommentsData(posts) {
|
15
|
+
const url = `!{server}/api/v2/stats/page_comment?page_keys=${posts.join(',')}&site_name=!{site}`;
|
16
|
+
return fetch(url)
|
17
|
+
.then(res => res.json())
|
18
|
+
.then(data => data.data);
|
19
|
+
}
|
20
|
+
|
21
|
+
function updatePostElements(posts, data) {
|
22
|
+
posts.forEach(post => {
|
23
|
+
const commentCount = data[post];
|
24
|
+
if (commentCount > !{count}) {
|
25
|
+
const postElement = document.querySelector(`.recent-post-item[onclick*="${post}"]`);
|
26
|
+
if (postElement) {
|
27
|
+
addHotTipIfNeeded(postElement);
|
28
|
+
}
|
29
|
+
}
|
30
|
+
});
|
31
|
+
}
|
32
|
+
|
33
|
+
function addHotTipIfNeeded(postElement) {
|
34
|
+
const infoTopTips = postElement.querySelector(".recent-post-info-top-tips");
|
35
|
+
const originalSpan = infoTopTips?.querySelector(".original");
|
36
|
+
const existingHotTip = infoTopTips?.querySelector(".hot-tip");
|
37
|
+
|
38
|
+
if (!existingHotTip && originalSpan) {
|
39
|
+
const hotTip = createHotTipElement();
|
40
|
+
infoTopTips.insertBefore(hotTip, originalSpan);
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
function createHotTipElement() {
|
45
|
+
const hotTip = document.createElement("span");
|
46
|
+
hotTip.classList.add("hot-tip");
|
47
|
+
|
48
|
+
const icon = document.createElement("i");
|
49
|
+
icon.classList.add("solitude", "fas", "fa-fire-flame-curved");
|
50
|
+
hotTip.appendChild(icon);
|
51
|
+
|
52
|
+
const commentCount = document.createTextNode("!{_p('hot-tip')}");
|
53
|
+
hotTip.appendChild(commentCount);
|
54
|
+
|
55
|
+
return hotTip;
|
56
|
+
}
|
@@ -0,0 +1,57 @@
|
|
1
|
+
script.
|
2
|
+
function updatePostsBasedOnComments() {
|
3
|
+
const location = window.location.origin;
|
4
|
+
const posts = Array.from(document.querySelectorAll('.recent-post-item[onclick] .post_cover a'))
|
5
|
+
.map(item => item.href.replace(location, ''));
|
6
|
+
|
7
|
+
const fetchCommentsCount = () => {
|
8
|
+
twikoo.getCommentsCount({
|
9
|
+
envId: "!{theme.twikoo.envId}",
|
10
|
+
urls: posts,
|
11
|
+
includeReply: true
|
12
|
+
}).then(handleCommentsResponse)
|
13
|
+
.catch(error => console.error("Error fetching comments:", error));
|
14
|
+
};
|
15
|
+
|
16
|
+
const handleCommentsResponse = (response) => {
|
17
|
+
response.forEach(comment => {
|
18
|
+
if (comment.count > !{count}) {
|
19
|
+
const postElement = document.querySelector(`.recent-post-item[onclick*="${comment.url}"]`);
|
20
|
+
if (postElement) {
|
21
|
+
updatePostElement(postElement);
|
22
|
+
}
|
23
|
+
}
|
24
|
+
});
|
25
|
+
};
|
26
|
+
|
27
|
+
const updatePostElement = (postElement) => {
|
28
|
+
const infoTopTips = postElement.querySelector(".recent-post-info-top-tips");
|
29
|
+
const originalSpan = infoTopTips?.querySelector(".original");
|
30
|
+
const existingHotTip = infoTopTips?.querySelector(".hot-tip");
|
31
|
+
|
32
|
+
if (!existingHotTip && originalSpan) {
|
33
|
+
const hotTip = createHotTipElement();
|
34
|
+
infoTopTips.insertBefore(hotTip, originalSpan);
|
35
|
+
}
|
36
|
+
};
|
37
|
+
|
38
|
+
const createHotTipElement = () => {
|
39
|
+
const hotTip = document.createElement("span");
|
40
|
+
hotTip.classList.add("hot-tip");
|
41
|
+
|
42
|
+
const icon = document.createElement("i");
|
43
|
+
icon.classList.add("solitude", "fas", "fa-fire-flame-curved");
|
44
|
+
hotTip.appendChild(icon);
|
45
|
+
|
46
|
+
const commentCount = document.createTextNode("!{_p('hot-tip')}");
|
47
|
+
hotTip.appendChild(commentCount);
|
48
|
+
|
49
|
+
return hotTip;
|
50
|
+
};
|
51
|
+
|
52
|
+
if (typeof twikoo === 'object') {
|
53
|
+
fetchCommentsCount();
|
54
|
+
} else {
|
55
|
+
utils.getScript('!{url_for(theme.cdn.twikoo)}').then(fetchCommentsCount);
|
56
|
+
}
|
57
|
+
}
|
@@ -1,9 +1,10 @@
|
|
1
1
|
- const google_adsense = theme.google_adsense.enable
|
2
|
+
- const select = ['title','#body-wrap','#site-config','meta[name="description"]','.js-pjax','meta[property^="og:"]','#config-diff', '.rs_show', '.rs_hide']
|
2
3
|
|
3
4
|
script.
|
4
5
|
const pjax = new Pjax({
|
5
6
|
elements: 'a:not([target="_blank"])',
|
6
|
-
selectors:
|
7
|
+
selectors: !{JSON.stringify(select)},
|
7
8
|
cacheBust: false,
|
8
9
|
analytics: !{google_adsense},
|
9
10
|
scrollRestoration: false
|
package/layout/index.pug
CHANGED
@@ -13,7 +13,7 @@ block content
|
|
13
13
|
include ./includes/widgets/home/categoryBar
|
14
14
|
.recent-posts#recent-posts
|
15
15
|
if theme.comment.hot_tip.enable
|
16
|
-
include ./includes/widgets/
|
16
|
+
include ./includes/widgets/third-party/hot/index.pug
|
17
17
|
if theme.carousel && is_home_first_page()
|
18
18
|
include ./includes/widgets/home/carousel.pug
|
19
19
|
for post, index in page.posts.sort("-sticky" || "-date").data
|
package/layout/tag.pug
CHANGED
@@ -14,4 +14,6 @@ block content
|
|
14
14
|
each post,index in page.posts.find({ parent: { $exists: false } }).data
|
15
15
|
include includes/widgets/home/postList
|
16
16
|
include includes/mixins/pagination
|
17
|
+
if theme.comment.hot_tip.enable
|
18
|
+
include ./includes/widgets/third-party/hot/index.pug
|
17
19
|
include includes/widgets/aside/aside
|
package/package.json
CHANGED
package/scripts/event/cdn.js
CHANGED
@@ -142,6 +142,6 @@ hexo.extend.filter.register('before_generate', () => {
|
|
142
142
|
themeConfig.cdn = Object.assign(
|
143
143
|
createCDNLink(internalSrc, CDN.internal, 'internal'),
|
144
144
|
createCDNLink(thirdPartySrc, CDN.third_party),
|
145
|
-
deleteNullValue(CDN.
|
145
|
+
deleteNullValue(CDN.options)
|
146
146
|
)
|
147
147
|
})
|
package/scripts/event/init.js
CHANGED
@@ -3,7 +3,6 @@ hexo.extend.filter.register('before_generate', () => {
|
|
3
3
|
const nodeVer = process.version.replace(/^v/, '');
|
4
4
|
const [majorVer] = nodeVer.split('.');
|
5
5
|
const logger = hexo.log;
|
6
|
-
const config = hexo.config;
|
7
6
|
|
8
7
|
if (hexoVer < 7.0) {
|
9
8
|
logger.error('请把 Hexo 升级到 V7.0.0 或更高的版本!');
|
@@ -33,18 +33,9 @@ hexo.extend.filter.register('before_generate', () => {
|
|
33
33
|
}
|
34
34
|
},
|
35
35
|
aside: {
|
36
|
-
home: {
|
37
|
-
|
38
|
-
|
39
|
-
},
|
40
|
-
post: {
|
41
|
-
noSticky: 'about',
|
42
|
-
Sticky: 'allInfo'
|
43
|
-
},
|
44
|
-
page: {
|
45
|
-
noSticky: 'about',
|
46
|
-
Sticky: 'allInfo'
|
47
|
-
},
|
36
|
+
home: { noSticky: 'about', Sticky: 'allInfo' },
|
37
|
+
post: { noSticky: 'about', Sticky: 'allInfo' },
|
38
|
+
page: { noSticky: 'about', Sticky: 'allInfo' },
|
48
39
|
card: {
|
49
40
|
style: 0,
|
50
41
|
author: {
|
@@ -73,24 +64,12 @@ hexo.extend.filter.register('before_generate', () => {
|
|
73
64
|
},
|
74
65
|
newest_comment: {
|
75
66
|
enable: false,
|
76
|
-
storage: .5,
|
67
|
+
storage: 0.5,
|
77
68
|
limit: 5
|
78
69
|
},
|
79
|
-
toc: {
|
80
|
-
|
81
|
-
|
82
|
-
vague: true,
|
83
|
-
},
|
84
|
-
tags: {
|
85
|
-
enable: true,
|
86
|
-
limit: 20,
|
87
|
-
highlight: false,
|
88
|
-
list: [],
|
89
|
-
},
|
90
|
-
archive: {
|
91
|
-
enable: true,
|
92
|
-
type: 'month'
|
93
|
-
},
|
70
|
+
toc: { post: true, page: false, vague: true },
|
71
|
+
tags: { enable: true, limit: 20, highlight: false, list: [] },
|
72
|
+
archive: { enable: true, type: 'month' },
|
94
73
|
siteinfo: {
|
95
74
|
postcount: true,
|
96
75
|
wordcount: false,
|
@@ -111,9 +90,7 @@ hexo.extend.filter.register('before_generate', () => {
|
|
111
90
|
tags: true,
|
112
91
|
categories: true,
|
113
92
|
archives: 0,
|
114
|
-
default: {
|
115
|
-
cover: ['/img/default.avif'],
|
116
|
-
}
|
93
|
+
default: { cover: ['/img/default.avif'] },
|
117
94
|
},
|
118
95
|
post: {
|
119
96
|
default: {
|
@@ -150,10 +127,7 @@ hexo.extend.filter.register('before_generate', () => {
|
|
150
127
|
api: 'https://api.qjqq.cn/api/Imgcolor?img=',
|
151
128
|
time: 43200000,
|
152
129
|
},
|
153
|
-
share: {
|
154
|
-
enable: false,
|
155
|
-
list: []
|
156
|
-
},
|
130
|
+
share: { enable: false, list: [] },
|
157
131
|
footer: {
|
158
132
|
enable: true,
|
159
133
|
desc: "The article from Solitude",
|
@@ -341,7 +315,7 @@ hexo.extend.filter.register('before_generate', () => {
|
|
341
315
|
enable: false,
|
342
316
|
recentComment: {
|
343
317
|
enable: false,
|
344
|
-
storage: .2,
|
318
|
+
storage: 0.2,
|
345
319
|
},
|
346
320
|
card: {
|
347
321
|
tags: true,
|
@@ -404,7 +378,7 @@ hexo.extend.filter.register('before_generate', () => {
|
|
404
378
|
enable: false,
|
405
379
|
dark: 'https://bu.dusays.com/2023/09/29/651685ce667d1.jpg',
|
406
380
|
light: 'https://bu.dusays.com/2023/09/29/651685cc18d39.jpg',
|
407
|
-
opacity: .2,
|
381
|
+
opacity: 0.2,
|
408
382
|
},
|
409
383
|
translate: {
|
410
384
|
enable: false,
|
@@ -427,6 +401,7 @@ hexo.extend.filter.register('before_generate', () => {
|
|
427
401
|
custom_format: '//open.lightxi.com/cdnjs/ajax/libs/${cdnjs_name}/${version}/${min_cdnjs_file}',
|
428
402
|
option: {}
|
429
403
|
}
|
430
|
-
}
|
431
|
-
|
404
|
+
};
|
405
|
+
|
406
|
+
hexo.theme.config = { ...defaultConfig, ...hexo.theme.config };
|
432
407
|
}, 1)
|
@@ -2,32 +2,31 @@
|
|
2
2
|
|
3
3
|
hexo.extend.filter.register('after_post_render', function (data) {
|
4
4
|
data.title = data.title || 'Untitled';
|
5
|
-
const {config} = hexo.theme;
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
data.
|
11
|
-
data.
|
12
|
-
data.
|
13
|
-
data.
|
14
|
-
data.
|
15
|
-
data.aside = data.aside || true;
|
5
|
+
const { config } = hexo.theme;
|
6
|
+
const defaultCover = ['/img/default.avif'];
|
7
|
+
|
8
|
+
const setCoverAndExcerpt = (layout) => {
|
9
|
+
const { copyright, locate, cover } = hexo.theme.config[layout].default;
|
10
|
+
data.locate = data.locate || locate;
|
11
|
+
data.cc = data.cc || copyright;
|
12
|
+
data.cover = data.cover || (cover?.length ? cover[getRandomInt(0, cover.length)] : defaultCover[0]);
|
13
|
+
data.excerpt = layout === 'post' ? data.description || data.excerpt : data.title;
|
14
|
+
data.toc = !!(config.aside.toc[layout] && data.toc !== false);
|
15
|
+
data.aside = layout === 'post' ? (data.aside || true) : (data.aside || false);
|
16
|
+
};
|
17
|
+
|
18
|
+
if (data.layout === 'post' || data.layout === 'page') {
|
19
|
+
setCoverAndExcerpt(data.layout);
|
16
20
|
}
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
data.cover = data.cover || cover[getRandomInt(0, cover?.length)]
|
21
|
-
data.excerpt = data.title
|
22
|
-
data.toc = !!(config.aside.toc.page && data.toc !== false && data.aside);
|
23
|
-
data.aside = data.aside || false;
|
21
|
+
|
22
|
+
if (data.layout === 'post') {
|
23
|
+
data.ai = data.ai || true;
|
24
24
|
}
|
25
|
+
|
25
26
|
data.comment = !!(config.comment.use && data.comment !== false);
|
26
27
|
return data;
|
27
28
|
});
|
28
29
|
|
29
30
|
function getRandomInt(min, max) {
|
30
|
-
min
|
31
|
-
max = Math.floor(max);
|
32
|
-
return Math.floor(Math.random() * (max - min)) + min;
|
31
|
+
return Math.floor(Math.random() * (max - min)) + Math.ceil(min);
|
33
32
|
}
|
@@ -1,7 +1,5 @@
|
|
1
1
|
'use strict'
|
2
2
|
|
3
|
-
const urlFor = require('hexo-util').url_for.bind(hexo)
|
4
|
-
|
5
3
|
const lazyload = (content, img) => {
|
6
4
|
return content.replace(/(<img(?!.*?class[\t]*=[\t]*['"].*?nolazyload.*?['"]).*? src=)/gi, `$1 "${img}" data-lazy-src=`)
|
7
5
|
}
|
@@ -9,12 +7,12 @@ const lazyload = (content, img) => {
|
|
9
7
|
hexo.extend.filter.register('after_render:html', function (data) {
|
10
8
|
const { enable, placeholder ,field } = hexo.theme.config.lazyload
|
11
9
|
if (!enable || field !== 'site') return;
|
12
|
-
return lazyload(data,
|
10
|
+
return lazyload(data, placeholder)
|
13
11
|
})
|
14
12
|
|
15
13
|
hexo.extend.filter.register('after_post_render', data => {
|
16
14
|
const { enable, placeholder, field } = hexo.theme.config.lazyload
|
17
15
|
if (!enable || field !== 'post') return
|
18
|
-
data.content = lazyload(data.content,
|
16
|
+
data.content = lazyload(data.content, placeholder)
|
19
17
|
return data
|
20
18
|
})
|
@@ -1,14 +1,12 @@
|
|
1
|
-
const moment = require('moment')
|
1
|
+
const moment = require('moment');
|
2
2
|
|
3
|
-
hexo.extend.helper.register('getArchiveLength', function (type) {
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
for (const post of posts) {
|
10
|
-
const postdate = type === 'year' ? moment(post.date).format('YYYY') : moment(post.date).format('YYYY/MM');
|
3
|
+
hexo.extend.helper.register('getArchiveLength', function (type = 'year') {
|
4
|
+
const validTypes = ['year', 'month'];
|
5
|
+
type = validTypes.includes(type) ? type : 'year';
|
6
|
+
|
7
|
+
return this.site.posts.sort('-date').data.reduce((archive, post) => {
|
8
|
+
const postdate = moment(post.date).format(type === 'year' ? 'YYYY' : 'YYYY/MM');
|
11
9
|
archive[postdate] = (archive[postdate] || 0) + 1;
|
12
|
-
|
13
|
-
|
10
|
+
return archive;
|
11
|
+
}, {});
|
14
12
|
});
|
@@ -6,80 +6,80 @@
|
|
6
6
|
'use strict'
|
7
7
|
|
8
8
|
hexo.extend.helper.register('related_posts', function (currentPost, allPosts) {
|
9
|
-
const
|
10
|
-
const
|
11
|
-
const
|
12
|
-
const
|
13
|
-
const headlineLang = this._p('star')
|
9
|
+
const config = hexo.theme.config;
|
10
|
+
const limitNum = config.related_post.limit || 6;
|
11
|
+
const dateType = config.related_post.date_type || 'created';
|
12
|
+
const headlineLang = this._p('star');
|
14
13
|
|
15
|
-
|
16
|
-
|
14
|
+
const relatedPostsMap = new Map();
|
15
|
+
|
16
|
+
currentPost.tags.forEach(tag => {
|
17
|
+
allPosts.forEach(post => {
|
17
18
|
if (isTagRelated(tag.name, post.tags) && currentPost.path !== post.path) {
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
const index = findItem(relatedPosts, 'path', post.path)
|
28
|
-
if (index !== -1) {
|
29
|
-
relatedPosts[index].weight += 1
|
19
|
+
if (!relatedPostsMap.has(post.path)) {
|
20
|
+
relatedPostsMap.set(post.path, {
|
21
|
+
title: post.title,
|
22
|
+
path: post.path,
|
23
|
+
cover: post.cover || 'var(--default-bg-color)',
|
24
|
+
weight: 1,
|
25
|
+
updated: post.updated,
|
26
|
+
created: post.date
|
27
|
+
});
|
30
28
|
} else {
|
31
|
-
|
29
|
+
relatedPostsMap.get(post.path).weight += 1;
|
32
30
|
}
|
33
31
|
}
|
34
|
-
})
|
35
|
-
})
|
32
|
+
});
|
33
|
+
});
|
36
34
|
|
35
|
+
const relatedPosts = Array.from(relatedPostsMap.values());
|
37
36
|
if (relatedPosts.length === 0) {
|
38
|
-
return ''
|
37
|
+
return '';
|
39
38
|
}
|
40
39
|
|
41
|
-
relatedPosts.sort(compare('weight', dateType))
|
40
|
+
relatedPosts.sort(compare('weight', dateType));
|
42
41
|
|
43
|
-
let result =
|
44
|
-
|
45
|
-
|
42
|
+
let result = `
|
43
|
+
<div class="relatedPosts">
|
44
|
+
<div class="headline">
|
45
|
+
<i class="solitude fa-solid fa-star"></i>
|
46
|
+
<span>${headlineLang}</span>
|
47
|
+
<div class="relatedPosts-link">
|
48
|
+
<a onclick="event.preventDefault(); toRandomPost();" href="javascript:void(0);" rel="external nofollow" data-pjax-state="">${this._p('random')}</a>
|
49
|
+
</div>
|
50
|
+
</div>
|
51
|
+
<div class="relatedPosts-list">`;
|
46
52
|
|
47
53
|
for (let i = 0; i < Math.min(relatedPosts.length, limitNum); i++) {
|
48
|
-
const cover = relatedPosts[i]
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
+
const { cover, title, path } = relatedPosts[i];
|
55
|
+
result += `
|
56
|
+
<div>
|
57
|
+
<a href="${this.url_for(path)}" title="${this.escape_html(title)}">
|
58
|
+
<img class="cover" src="${this.url_for(cover)}" alt="cover">
|
59
|
+
<div class="content is-center">
|
60
|
+
<div class="title">${this.escape_html(title)}</div>
|
61
|
+
</div>
|
62
|
+
</a>
|
63
|
+
</div>`;
|
54
64
|
}
|
55
65
|
|
56
|
-
result +=
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
return TBDtags.some(function (tag) {
|
62
|
-
return tagName === tag.name
|
63
|
-
})
|
64
|
-
}
|
66
|
+
result += `
|
67
|
+
</div>
|
68
|
+
</div>`;
|
69
|
+
return result;
|
70
|
+
});
|
65
71
|
|
66
|
-
function
|
67
|
-
return
|
68
|
-
return item[attr] === val
|
69
|
-
})
|
72
|
+
function isTagRelated(tagName, tags) {
|
73
|
+
return tags.some(tag => tagName === tag.name);
|
70
74
|
}
|
71
75
|
|
72
76
|
function compare(attr, dateType) {
|
73
|
-
return
|
74
|
-
const val1 = a[attr]
|
75
|
-
const val2 = b[attr]
|
77
|
+
return (a, b) => {
|
78
|
+
const val1 = a[attr];
|
79
|
+
const val2 = b[attr];
|
76
80
|
if (val1 === val2) {
|
77
|
-
|
78
|
-
return b.created - a.created
|
79
|
-
} else if (dateType === 'updated') {
|
80
|
-
return b.updated - a.updated
|
81
|
-
}
|
81
|
+
return dateType === 'created' ? b.created - a.created : b.updated - a.updated;
|
82
82
|
}
|
83
|
-
return val2 - val1
|
84
|
-
}
|
83
|
+
return val2 - val1;
|
84
|
+
};
|
85
85
|
}
|
package/scripts/tags/article.js
CHANGED
package/scripts/tags/tabs.js
CHANGED
@@ -5,51 +5,33 @@
|
|
5
5
|
|
6
6
|
'use strict'
|
7
7
|
|
8
|
-
function postTabs
|
9
|
-
const tabBlock = /<!--\s*tab (.*?)\s*-->\n([\w\W\s\S]*?)<!--\s*endtab\s*-->/g
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
((tabCaption.length === 0) && (tabIcon.length === 0)) && (tabCaption = name + ' ' + tabId)
|
35
|
-
|
36
|
-
const isOnlyicon = tabIcon.length > 0 && tabCaption.length === 0 ? ' style="text-align: center;"' : ''
|
37
|
-
const icon = tabIcon.trim()
|
38
|
-
tabIcon.length > 0 && (tabIcon = `<i ${isOnlyicon} class="tab solitude ${icon}"></i>`)
|
39
|
-
|
40
|
-
const toTop = '<button type="button" class="tab-to-top" aria-label="scroll to top"><i class="solitude fas fa-arrow-up"></i></button>'
|
41
|
-
const isActive = active === tabId ? ' active' : ''
|
42
|
-
tabNav += `<li class="tab${isActive}"><button type="button" data-href="#${tabHref}">${tabIcon + tabCaption.trim()}</button></li>`
|
43
|
-
tabContent += `<div class="tab-item-content${isActive}" id="${tabHref}">${postContent + toTop}</div>`
|
44
|
-
tabId += 1
|
45
|
-
}
|
46
|
-
|
47
|
-
tabNav = `<ul class="nav-tabs">${tabNav}</ul>`
|
48
|
-
tabContent = `<div class="tab-contents">${tabContent}</div>`
|
49
|
-
|
50
|
-
return `<div class="tabs" id="${name.toLowerCase().split(' ').join('-')}">${tabNav + tabContent}</div>`
|
8
|
+
function postTabs([name, active], content) {
|
9
|
+
const tabBlock = /<!--\s*tab (.*?)\s*-->\n([\w\W\s\S]*?)<!--\s*endtab\s*-->/g;
|
10
|
+
const matches = [...content.matchAll(tabBlock)];
|
11
|
+
|
12
|
+
active = Number(active) || 0;
|
13
|
+
|
14
|
+
const tabItems = matches.map((match, tabId) => {
|
15
|
+
const [tabCaption = '', tabIcon = ''] = match[1].split('@');
|
16
|
+
const postContent = hexo.render.renderSync({ text: match[2], engine: 'markdown' }).trim();
|
17
|
+
const tabHref = `${name.toLowerCase().replace(/\s+/g, '-')}-${tabId}`;
|
18
|
+
|
19
|
+
const iconHtml = tabIcon ? `<i class="${tabIcon.trim()} tab solitude"></i>` : '';
|
20
|
+
const isActive = active === tabId ? ' active' : '';
|
21
|
+
const toTopButton = '<button type="button" class="tab-to-top" aria-label="scroll to top"><i class="solitude fas fa-arrow-up"></i></button>';
|
22
|
+
|
23
|
+
return {
|
24
|
+
nav: `<li class="tab${isActive}"><button type="button" data-href="#${tabHref}">${iconHtml}${tabCaption.trim() || `${name} ${tabId}`}</button></li>`,
|
25
|
+
content: `<div class="tab-item-content${isActive}" id="${tabHref}">${postContent}${toTopButton}</div>`
|
26
|
+
};
|
27
|
+
});
|
28
|
+
|
29
|
+
const tabNav = `<ul class="nav-tabs">${tabItems.map(item => item.nav).join('')}</ul>`;
|
30
|
+
const tabContent = `<div class="tab-contents">${tabItems.map(item => item.content).join('')}</div>`;
|
31
|
+
|
32
|
+
return `<div class="tabs" id="${name.toLowerCase().replace(/\s+/g, '-')}">${tabNav}${tabContent}</div>`;
|
51
33
|
}
|
52
34
|
|
53
|
-
hexo.extend.tag.register('tabs', postTabs, { ends: true })
|
54
|
-
hexo.extend.tag.register('subtabs', postTabs, { ends: true })
|
55
|
-
hexo.extend.tag.register('subsubtabs', postTabs, { ends: true })
|
35
|
+
hexo.extend.tag.register('tabs', postTabs, { ends: true });
|
36
|
+
hexo.extend.tag.register('subtabs', postTabs, { ends: true });
|
37
|
+
hexo.extend.tag.register('subsubtabs', postTabs, { ends: true });
|
@@ -350,13 +350,13 @@ img.tk-avatar-img
|
|
350
350
|
border var(--style-border-always)
|
351
351
|
|
352
352
|
.el-input-group__append, .el-input-group__prepend
|
353
|
-
background-color var(--efu-card-bg)
|
353
|
+
background-color var(--efu-card-bg)
|
354
354
|
color var(--efu-fontcolor) !important
|
355
355
|
border 0 !important
|
356
356
|
font-weight 700
|
357
357
|
|
358
358
|
.el-input__inner
|
359
|
-
background var(--efu-secondbg) !important
|
359
|
+
background-color: var(--efu-secondbg) !important
|
360
360
|
border 0 !important
|
361
361
|
color var(--efu-fontcolor) !important
|
362
362
|
padding-left 8px
|
@@ -372,7 +372,7 @@ img.tk-avatar-img
|
|
372
372
|
border none
|
373
373
|
|
374
374
|
.el-textarea__inner
|
375
|
-
background var(--efu-secondbg)
|
375
|
+
background-color var(--efu-secondbg)
|
376
376
|
color var(--efu-fontcolor) !important
|
377
377
|
border-radius 12px !important
|
378
378
|
min-height 100px !important
|
@@ -27,6 +27,12 @@ figure.highlight
|
|
27
27
|
|
28
28
|
.emphasis
|
29
29
|
color $highlight-emphasis-light
|
30
|
+
|
31
|
+
.addition
|
32
|
+
color $highlight-inserted
|
33
|
+
|
34
|
+
.deletion
|
35
|
+
color $highlight-deleted
|
30
36
|
|
31
37
|
[data-theme=dark] &
|
32
38
|
.keyword
|
@@ -48,4 +54,10 @@ figure.highlight
|
|
48
54
|
color $highlight-title-dark
|
49
55
|
|
50
56
|
.emphasis
|
51
|
-
color $highlight-emphasis-dark
|
57
|
+
color $highlight-emphasis-dark
|
58
|
+
|
59
|
+
.addition
|
60
|
+
color $highlight-inserted
|
61
|
+
|
62
|
+
.deletion
|
63
|
+
color $highlight-deleted
|