hexo-theme-stellar 1.30.3 → 1.31.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 +17 -5
- package/_data/widgets.yml +0 -1
- package/layout/_partial/head.ejs +9 -2
- package/layout/_partial/main/navbar/ghinfo.ejs +1 -1
- package/layout/_partial/scripts/defines.ejs +9 -0
- package/layout/_partial/widgets/ghissues.ejs +1 -1
- package/layout/_partial/widgets/ghrepo.ejs +2 -2
- package/layout/_partial/widgets/ghuser.ejs +1 -1
- package/layout/layout.ejs +2 -0
- package/package.json +1 -1
- package/scripts/events/index.js +8 -3
- package/scripts/events/lib/version-check.js +84 -0
- package/scripts/helpers/json_ld.js +114 -0
- package/scripts/tags/index.js +1 -0
- package/scripts/tags/lib/albums.js +2 -1
- package/scripts/tags/lib/friends.js +2 -1
- package/scripts/tags/lib/ghcard.js +3 -2
- package/scripts/tags/lib/posters.js +2 -1
- package/scripts/tags/lib/quote.js +22 -0
- package/scripts/tags/lib/sites.js +2 -1
- package/scripts/tags/lib/video.js +2 -2
- package/source/css/_common/canonical.styl +32 -0
- package/source/css/_common/device.styl +8 -6
- package/source/css/_components/layout.styl +3 -3
- package/source/css/_components/pages/article-story.styl +20 -12
- package/source/css/_components/sidebar/sidebar.styl +62 -18
- package/source/css/_components/tag-plugins/media.styl +1 -1
- package/source/css/_components/tag-plugins/quote.styl +7 -0
- package/source/css/_components/widgets/list.styl +1 -3
- package/source/css/_custom.styl +3 -0
- package/source/css/_defines/const.styl +5 -1
- package/source/css/_defines/func.styl +5 -5
- package/source/css/_defines/theme.styl +2 -2
- package/source/js/main.js +50 -0
- package/source/js/plugins/download-file.js +1 -1
- package/source/js/services/mdrender.js +0 -1
package/_config.yml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
######## Stellar info ########
|
|
2
2
|
stellar:
|
|
3
|
-
version: '1.
|
|
3
|
+
version: '1.31.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
|
|
@@ -13,10 +13,20 @@ preconnect:
|
|
|
13
13
|
# - https://gcore.jsdelivr.net
|
|
14
14
|
# - https://unpkg.com
|
|
15
15
|
|
|
16
|
+
# 一旦设置源站地址,非源站地址将不会被SEO收录,并且访问时弹出提示
|
|
17
|
+
# 如果访问地址不在备用站主机列表,则警告信息为非法克隆
|
|
18
|
+
canonical:
|
|
19
|
+
originalHost: # 主站点域名主机,例如 xaoxuu.com
|
|
20
|
+
officialHosts: # 官方主机列表,每行一个,例如 xaoxuu.vercel.app
|
|
21
|
+
- localhost
|
|
22
|
+
|
|
16
23
|
open_graph:
|
|
17
24
|
enable: true
|
|
18
25
|
twitter_id: # for open_graph meta
|
|
19
26
|
|
|
27
|
+
structured_data:
|
|
28
|
+
links: [] # your social links.
|
|
29
|
+
|
|
20
30
|
|
|
21
31
|
######## Sidebar ########
|
|
22
32
|
# 左上角显示的 logo 区域,包含图标、大标题、副标题
|
|
@@ -439,7 +449,7 @@ data_services:
|
|
|
439
449
|
siteinfo:
|
|
440
450
|
js: /js/services/siteinfo.js
|
|
441
451
|
# 设置 api 可以自动提取网页标题、图标,服务部署方法:https://github.com/xaoxuu/site-info-api/
|
|
442
|
-
# 接口测试通过后,把按钮的 href 部分替换成 {href} 之后填写到下方,例如:https://api.
|
|
452
|
+
# 接口测试通过后,把按钮的 href 部分替换成 {href} 之后填写到下方,例如:https://api.xaox.cc/site_info/v1?url={href}
|
|
443
453
|
api:
|
|
444
454
|
ghinfo:
|
|
445
455
|
js: /js/services/ghinfo.js
|
|
@@ -673,6 +683,8 @@ default:
|
|
|
673
683
|
|
|
674
684
|
|
|
675
685
|
api_host:
|
|
676
|
-
ghapi:
|
|
677
|
-
ghraw:
|
|
678
|
-
gist:
|
|
686
|
+
ghapi: api.github.com
|
|
687
|
+
ghraw: raw.githubusercontent.com
|
|
688
|
+
gist: gist.github.com
|
|
689
|
+
# https://github.com/anuraghazra/github-readme-stats
|
|
690
|
+
ghcard: github-readme-stats.vercel.app
|
package/_data/widgets.yml
CHANGED
|
@@ -68,7 +68,6 @@ timeline:
|
|
|
68
68
|
title: 近期动态
|
|
69
69
|
api: # https://api.github.com/repos/xaoxuu/hexo-theme-stellar/issues
|
|
70
70
|
user: # 默认显示所有人的数据,设置名称可过滤为仅显示某人的数据,多个名称用英文逗号隔开,不要加空格
|
|
71
|
-
type: # 默认不用写,如果是友链朋友圈数据请写 fcircle
|
|
72
71
|
limit: # 默认通过 api 上增加 per_page 来设置,如果是友链朋友圈,可通过这个设置数量
|
|
73
72
|
|
|
74
73
|
latest_comment:
|
package/layout/_partial/head.ejs
CHANGED
|
@@ -47,6 +47,10 @@ function generate_keywords() {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
function generate_robots() {
|
|
50
|
+
const IS_BACKUP = process.env.IS_BACKUP === 'true';
|
|
51
|
+
if (IS_BACKUP) {
|
|
52
|
+
return '<meta name="robots" content="noindex, nofollow">';
|
|
53
|
+
}
|
|
50
54
|
if (is_home() == true) {
|
|
51
55
|
return '';
|
|
52
56
|
}
|
|
@@ -62,6 +66,7 @@ function og_args() {
|
|
|
62
66
|
if (page.layout == 'post' && page.cover) {
|
|
63
67
|
args.twitter_card = 'summary_large_image';
|
|
64
68
|
}
|
|
69
|
+
args.image = config.avatar || (config.email ? gravatar(config.email) : null);
|
|
65
70
|
return Object.assign(args, page.open_graph);
|
|
66
71
|
}
|
|
67
72
|
|
|
@@ -100,11 +105,13 @@ function custom_inject() {
|
|
|
100
105
|
<meta name="force-rendering" content="webkit">
|
|
101
106
|
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
|
|
102
107
|
<meta name="HandheldFriendly" content="True" >
|
|
103
|
-
<meta name="
|
|
108
|
+
<meta name="mobile-web-app-capable" content="yes">
|
|
104
109
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
|
105
110
|
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="#000">
|
|
106
111
|
<meta name="theme-color" content="#f9fafb">
|
|
107
|
-
|
|
112
|
+
<% if (theme.canonical.originalHost) { %>
|
|
113
|
+
<link rel="canonical" href="https://<%= theme.canonical.originalHost + "/" + page.path %>">
|
|
114
|
+
<% } %>
|
|
108
115
|
<title><%- generate_title() %></title>
|
|
109
116
|
|
|
110
117
|
<% if (theme.open_graph && theme.open_graph.enable) { %>
|
|
@@ -5,7 +5,7 @@ function layoutDiv() {
|
|
|
5
5
|
return ''
|
|
6
6
|
}
|
|
7
7
|
return `
|
|
8
|
-
<div class="right ghrepo ds-ghinfo" api="
|
|
8
|
+
<div class="right ghrepo ds-ghinfo" api="https://${theme.api_host.ghapi}/repos/${repo}">
|
|
9
9
|
<a class="repo-link bold" href="https://github.com/${repo}">
|
|
10
10
|
${icon('github:repo')}
|
|
11
11
|
<span type="text">${repo}</span>
|
|
@@ -1,4 +1,13 @@
|
|
|
1
|
+
<%
|
|
2
|
+
const canonical = theme.canonical || {}
|
|
3
|
+
const encoded = Buffer.from(canonical.originalHost || '').toString('base64');
|
|
4
|
+
const canonicalWithEncoded = Object.assign({}, canonical, {
|
|
5
|
+
encoded: encoded
|
|
6
|
+
});
|
|
7
|
+
%>
|
|
8
|
+
|
|
1
9
|
<script type="text/javascript">
|
|
10
|
+
window.canonical = <%- JSON.stringify(canonicalWithEncoded) %>;
|
|
2
11
|
const ctx = {
|
|
3
12
|
date_suffix: {
|
|
4
13
|
just: `<%- __('meta.date_suffix.just') %>`,
|
|
@@ -15,7 +15,7 @@ function layoutDiv() {
|
|
|
15
15
|
if (repo == undefined) {
|
|
16
16
|
return el;
|
|
17
17
|
}
|
|
18
|
-
item.api = theme.api_host.ghapi
|
|
18
|
+
item.api = `https://${theme.api_host.ghapi}/repos/${repo}/issues?per_page=${item.limit}`;
|
|
19
19
|
if (item.labels) {
|
|
20
20
|
item.api += '&labels=' + item.labels;
|
|
21
21
|
}
|
|
@@ -19,7 +19,7 @@ function layoutDiv() {
|
|
|
19
19
|
el += `<widget class="widget-wrapper${scrollreveal(' ')} ghrepo">`
|
|
20
20
|
// body
|
|
21
21
|
el += '<div class="widget-body">';
|
|
22
|
-
el += '<div class="items ds-ghinfo" api="' + theme.api_host.ghapi + '/repos/' + repo + '">';
|
|
22
|
+
el += '<div class="items ds-ghinfo" api="https://' + theme.api_host.ghapi + '/repos/' + repo + '">';
|
|
23
23
|
el += '<a class="repo" href="https://github.com/' + repo + '" target="_blank" rel="external nofollow noopener noreferrer">';
|
|
24
24
|
el += '<div class="repo-name flex-row">';
|
|
25
25
|
el += icon('github:repo')
|
|
@@ -35,7 +35,7 @@ function layoutDiv() {
|
|
|
35
35
|
el += icon('github:fork')
|
|
36
36
|
el += '<span type="text" id="forks_count"></span>';
|
|
37
37
|
el += '</div>';
|
|
38
|
-
el += '<div class="flex-row ds-ghinfo" index="0" api="' + theme.api_host.ghapi + '/repos/' + repo + '/tags">';
|
|
38
|
+
el += '<div class="flex-row ds-ghinfo" index="0" api="https://' + theme.api_host.ghapi + '/repos/' + repo + '/tags">';
|
|
39
39
|
el += icon('github:tag')
|
|
40
40
|
el += '<span type="text" id="latest-tag-name">0</span>';
|
|
41
41
|
el += '</div>';
|
|
@@ -24,7 +24,7 @@ function layoutDiv() {
|
|
|
24
24
|
|
|
25
25
|
el += `<widget class="widget-wrapper${scrollreveal(' ')} user-card ghuser">`
|
|
26
26
|
// body
|
|
27
|
-
el += '<div class="widget-body ds-ghinfo" api="' + theme.api_host.ghapi + '/users/' + item.username + '">';
|
|
27
|
+
el += '<div class="widget-body ds-ghinfo" api="https://' + theme.api_host.ghapi + '/users/' + item.username + '">';
|
|
28
28
|
if (item.avatar) {
|
|
29
29
|
el += '<div class="avatar" ><img no-lazy type="img" id="avatar_url" src="' + config.avatar + '"></div>';
|
|
30
30
|
}
|
package/layout/layout.ejs
CHANGED
|
@@ -48,6 +48,7 @@ if (theme.style.prefers_theme === 'auto') {
|
|
|
48
48
|
html += partial('_partial/cover/index')
|
|
49
49
|
html += `<div class="l_body ${page_type}" id="start" layout="${page.layout}" type="${article_type}" ${indent ? 'text-indent' : ''}>`
|
|
50
50
|
html += `<aside class="l_left">`
|
|
51
|
+
html += `<div class="sidebg"></div>`
|
|
51
52
|
html += `<div class="leftbar-container${theme.style.leftbar?.blur ? ' leftbar-blur' : ''}">`
|
|
52
53
|
html += partial('_partial/sidebar/index_leftbar')
|
|
53
54
|
html += `</div>`
|
|
@@ -64,6 +65,7 @@ if (theme.style.prefers_theme === 'auto') {
|
|
|
64
65
|
html += partial('_partial/menubtn')
|
|
65
66
|
html += `</div>`
|
|
66
67
|
html += `<div class="scripts">`
|
|
68
|
+
html += json_ld()
|
|
67
69
|
html += partial('_partial/scripts')
|
|
68
70
|
html += `</div>`
|
|
69
71
|
html += `</body>`
|
package/package.json
CHANGED
package/scripts/events/index.js
CHANGED
|
@@ -18,9 +18,14 @@ hexo.on('generateAfter', () => {
|
|
|
18
18
|
});
|
|
19
19
|
|
|
20
20
|
hexo.on('ready', () => {
|
|
21
|
+
if (process.env.HEXO_READY === '1') return;
|
|
22
|
+
process.env.HEXO_READY = '1';
|
|
21
23
|
const { version, homepage, repository } = require('../../package.json');
|
|
22
|
-
hexo.log.info(`Welcome to
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
hexo.log.info(`Welcome to \x1b[33mStellar ${version}\x1b[0m
|
|
25
|
+
\x1b[32mDOCS\x1b[0m ${homepage}
|
|
26
|
+
\x1b[32mREPO\x1b[0m ${repository.url}
|
|
25
27
|
`);
|
|
28
|
+
// version check
|
|
29
|
+
const checkVersion = require('./lib/version-check');
|
|
30
|
+
checkVersion(hexo, { useCache: true });
|
|
26
31
|
});
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
const https = require('https');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const packageName = 'hexo-theme-stellar';
|
|
5
|
+
const cacheFile = path.join(__dirname, '../../.cache/stellar-version.json');
|
|
6
|
+
|
|
7
|
+
function getLocalVersion() {
|
|
8
|
+
try {
|
|
9
|
+
return require(path.join(__dirname, '../../../package.json')).version;
|
|
10
|
+
} catch {
|
|
11
|
+
return '0.0.0';
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function fetchLatestVersion(callback) {
|
|
16
|
+
const options = {
|
|
17
|
+
hostname: 'registry.npmjs.org',
|
|
18
|
+
path: `/${encodeURIComponent(packageName)}`,
|
|
19
|
+
headers: {
|
|
20
|
+
'User-Agent': 'Hexo-Theme-Version-Check'
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
https.get(options, (res) => {
|
|
25
|
+
let rawData = '';
|
|
26
|
+
res.on('data', chunk => rawData += chunk);
|
|
27
|
+
res.on('end', () => {
|
|
28
|
+
try {
|
|
29
|
+
const data = JSON.parse(rawData);
|
|
30
|
+
const latest = data['dist-tags'].latest;
|
|
31
|
+
callback(null, latest);
|
|
32
|
+
} catch (err) {
|
|
33
|
+
callback(err);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}).on('error', err => callback(err));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function shouldCheck() {
|
|
40
|
+
if (!fs.existsSync(cacheFile)) return true;
|
|
41
|
+
try {
|
|
42
|
+
const cache = JSON.parse(fs.readFileSync(cacheFile, 'utf8'));
|
|
43
|
+
const time = new Date().toISOString().slice(0, 16); // 精确到分钟,例如 "2025-06-21T15:08"
|
|
44
|
+
return cache.time !== time;
|
|
45
|
+
} catch {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function writeCache(latestVersion) {
|
|
51
|
+
try {
|
|
52
|
+
fs.mkdirSync(path.dirname(cacheFile), { recursive: true });
|
|
53
|
+
fs.writeFileSync(cacheFile, JSON.stringify({
|
|
54
|
+
time: new Date().toISOString().slice(0, 16),
|
|
55
|
+
latest: latestVersion
|
|
56
|
+
}));
|
|
57
|
+
} catch {
|
|
58
|
+
// 忽略错误
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
module.exports = (ctx, options = { useCache: true }) => {
|
|
63
|
+
if (process.env.STELLAR_VERSION_CHECKED === '1') return;
|
|
64
|
+
process.env.STELLAR_VERSION_CHECKED = '1';
|
|
65
|
+
|
|
66
|
+
const localVersion = getLocalVersion();
|
|
67
|
+
if (options.useCache && !shouldCheck()) return;
|
|
68
|
+
|
|
69
|
+
fetchLatestVersion((err, latest) => {
|
|
70
|
+
if (err) return;
|
|
71
|
+
if (localVersion !== latest) {
|
|
72
|
+
const line = '------------------------------------------------';
|
|
73
|
+
ctx.log.warn(`\x1b[33m${line}\x1b[0m`);
|
|
74
|
+
ctx.log.warn(``);
|
|
75
|
+
ctx.log.warn(` 本地版本: \x1b[33m${localVersion}\x1b[0m >>>> 最新版本: \x1b[32m${latest}\x1b[0m`);
|
|
76
|
+
ctx.log.warn(``);
|
|
77
|
+
ctx.log.warn(` 请尽快升级: npm i ${packageName}@latest`);
|
|
78
|
+
ctx.log.warn(``);
|
|
79
|
+
ctx.log.warn(`\x1b[33m${line}\x1b[0m`);
|
|
80
|
+
}
|
|
81
|
+
if (options.useCache) writeCache(latest);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
};
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builds JSON-LD structured data for current page according to its type (page or post).
|
|
3
|
+
*
|
|
4
|
+
* @returns {string} - JSON-LD structured data
|
|
5
|
+
*/
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
8
|
+
const util = require('hexo-util');
|
|
9
|
+
|
|
10
|
+
hexo.extend.helper.register('json_ld', function(args) {
|
|
11
|
+
const page = this.page;
|
|
12
|
+
const config = this.config;
|
|
13
|
+
const structured_data = this.theme.structured_data;
|
|
14
|
+
const authorEmail = config.email;
|
|
15
|
+
const authorImage = config.avatar || (authorEmail ? this.gravatar(authorEmail) : null);
|
|
16
|
+
|
|
17
|
+
const author = {
|
|
18
|
+
'@type': 'Person',
|
|
19
|
+
name: config.author,
|
|
20
|
+
sameAs: structured_data.sameAs || []
|
|
21
|
+
};
|
|
22
|
+
// Google does not accept `Person` as item type for the publisher property
|
|
23
|
+
const publisher = Object.assign({}, author, {'@type': 'Organization'});
|
|
24
|
+
let schema = {};
|
|
25
|
+
|
|
26
|
+
if (authorImage) {
|
|
27
|
+
author.image = authorImage;
|
|
28
|
+
publisher.image = authorImage;
|
|
29
|
+
publisher.logo = {
|
|
30
|
+
'@type': 'ImageObject',
|
|
31
|
+
url: authorImage
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (this.is_post()) {
|
|
36
|
+
schema = {
|
|
37
|
+
'@context': 'https://schema.org',
|
|
38
|
+
'@type': 'BlogPosting',
|
|
39
|
+
author: author,
|
|
40
|
+
// articleBody: this.strip_html(page.content),
|
|
41
|
+
dateCreated: page.date.format(),
|
|
42
|
+
dateModified: page.updated.format(),
|
|
43
|
+
datePublished: page.date.format(),
|
|
44
|
+
description: this.strip_html(page.excerpt),
|
|
45
|
+
headline: page.title,
|
|
46
|
+
mainEntityOfPage: {
|
|
47
|
+
'@type': 'WebPage',
|
|
48
|
+
'@id': this.url_for(page.permalink)
|
|
49
|
+
},
|
|
50
|
+
publisher,
|
|
51
|
+
url: this.url_for(page.permalink)
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
if (page.tags && page.tags.length > 0) {
|
|
55
|
+
schema.keywords = page.tags.map((tag) => tag.name).join(', ');
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
let images = [];
|
|
59
|
+
if (page.photos && page.photos.length > 0) {
|
|
60
|
+
images = images.concat(page.photos);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (page.cover?.length > 0) {
|
|
64
|
+
images = images.unshift(page.cover);
|
|
65
|
+
} else if (page.banner?.length > 0) {
|
|
66
|
+
images = images.unshift(page.banner);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
schema.thumbnailUrl = page.cover || page.banner;
|
|
70
|
+
schema.image = images;
|
|
71
|
+
|
|
72
|
+
} else if (this.is_page() || this.is_home()) {
|
|
73
|
+
|
|
74
|
+
const url = this.is_home() ? config.url : this.url_for(page.permalink);
|
|
75
|
+
schema = {
|
|
76
|
+
'@context': 'https://schema.org',
|
|
77
|
+
'@type': 'Website',
|
|
78
|
+
'@id': url,
|
|
79
|
+
author: author,
|
|
80
|
+
name: page.title || config.title,
|
|
81
|
+
description: config.description,
|
|
82
|
+
url: url
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
if (config.keywords && config.keywords.length) {
|
|
86
|
+
schema.keywords = config.keywords.join(', ');
|
|
87
|
+
}
|
|
88
|
+
if (!this.is_home()) {
|
|
89
|
+
|
|
90
|
+
if (page.excerpt || page.description) {
|
|
91
|
+
schema.description = this.strip_html(page.description || page.excerpt);
|
|
92
|
+
} else {
|
|
93
|
+
schema.description = util.truncate(this.strip_html(page.content), {length: 200});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
} else {
|
|
99
|
+
|
|
100
|
+
// default to WebPage for other layouts
|
|
101
|
+
schema = {
|
|
102
|
+
'@context': 'https://schema.org',
|
|
103
|
+
'@type': 'Website',
|
|
104
|
+
'@id': config.url,
|
|
105
|
+
author: author,
|
|
106
|
+
name: config.title,
|
|
107
|
+
description: config.description,
|
|
108
|
+
url: config.url
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return `<script type="application/ld+json">${JSON.stringify(schema)}</script>`;
|
|
114
|
+
});
|
package/scripts/tags/index.js
CHANGED
|
@@ -40,6 +40,7 @@ hexo.extend.tag.register('navbar', require('./lib/navbar')(hexo))
|
|
|
40
40
|
hexo.extend.tag.register('note', require('./lib/note')(hexo))
|
|
41
41
|
hexo.extend.tag.register('poetry', require('./lib/poetry')(hexo), true)
|
|
42
42
|
hexo.extend.tag.register('quot', require('./lib/quot')(hexo))
|
|
43
|
+
hexo.extend.tag.register('quote', require('./lib/quote')(hexo), true)
|
|
43
44
|
hexo.extend.tag.register('hashtag', require('./lib/hashtag')(hexo))
|
|
44
45
|
hexo.extend.tag.register('okr', require('./lib/okr')(hexo), {ends: true})
|
|
45
46
|
hexo.extend.tag.register('audio', require('./lib/audio')(hexo))
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
module.exports = ctx => function(args) {
|
|
11
11
|
var args = ctx.args.map(args, ['repo', 'api', 'size'], ['group'])
|
|
12
|
+
const host = ctx.theme.config.api_host.ghraw
|
|
12
13
|
if (args.size == null) {
|
|
13
14
|
args.size = 's'
|
|
14
15
|
}
|
|
@@ -16,7 +17,7 @@ module.exports = ctx => function(args) {
|
|
|
16
17
|
if (args.api) {
|
|
17
18
|
api = args.api
|
|
18
19
|
} else if (args.repo) {
|
|
19
|
-
api =
|
|
20
|
+
api = `https://${host}/${args.repo}/output/v2/data.json`
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
var el = ''
|
|
@@ -9,11 +9,12 @@
|
|
|
9
9
|
|
|
10
10
|
module.exports = ctx => function(args) {
|
|
11
11
|
args = ctx.args.map(args, ['repo', 'api', 'posts'], ['group'])
|
|
12
|
+
const host = ctx.theme.config.api_host.ghraw
|
|
12
13
|
var api
|
|
13
14
|
if (args.api) {
|
|
14
15
|
api = args.api
|
|
15
16
|
} else if (args.repo) {
|
|
16
|
-
api =
|
|
17
|
+
api = `https://${host}/${args.repo}/output/v2/data.json`
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
var el = `<div class="tag-plugin ${args.posts ? 'users-posts-wrap' : 'users-wrap'}">`
|
|
@@ -17,6 +17,7 @@ module.exports = ctx => function(args) {
|
|
|
17
17
|
var params = ['show_owner', 'theme', 'title_color', 'text_color', 'icon_color', 'bg_color', 'hide_border', 'cache_seconds', 'locale']
|
|
18
18
|
args = ctx.args.map(args, params, ['repo'])
|
|
19
19
|
const path = args.repo
|
|
20
|
+
const host = ctx.theme.config.api_host.ghcard
|
|
20
21
|
var el = ''
|
|
21
22
|
el += '<div class="tag-plugin ghcard">'
|
|
22
23
|
el += '<a class="ghcard" rel="external nofollow noopener noreferrer" href="https://github.com/' + path + '">'
|
|
@@ -24,10 +25,10 @@ module.exports = ctx => function(args) {
|
|
|
24
25
|
if (path.includes('/')) {
|
|
25
26
|
// is repo
|
|
26
27
|
const ps = path.split('/')
|
|
27
|
-
url
|
|
28
|
+
url = `https://${host}/api/pin/?username=${ps[0]}&repo=${ps[1]}`
|
|
28
29
|
} else {
|
|
29
30
|
// is user
|
|
30
|
-
url
|
|
31
|
+
url = `https://${host}/api/?username=${path}`
|
|
31
32
|
}
|
|
32
33
|
url += '&' + ctx.args.joinURLParams(args, params)
|
|
33
34
|
if (!url.includes('&show_owner=')) {
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
module.exports = ctx => function(args) {
|
|
11
11
|
var args = ctx.args.map(args, ['repo', 'api', 'size'], ['group'])
|
|
12
|
+
const host = ctx.theme.config.api_host.ghraw
|
|
12
13
|
if (args.size == null) {
|
|
13
14
|
args.size = 'm'
|
|
14
15
|
}
|
|
@@ -16,7 +17,7 @@ module.exports = ctx => function(args) {
|
|
|
16
17
|
if (args.api) {
|
|
17
18
|
api = args.api
|
|
18
19
|
} else if (args.repo) {
|
|
19
|
-
api =
|
|
20
|
+
api = `https://${host}/${args.repo}/output/v2/data.json`
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
var el = ''
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* quote.js v1.1 | https://github.com/xaoxuu/hexo-theme-stellar/
|
|
3
|
+
* 格式与官方标签插件一致使用空格分隔,中括号内的是可选参数(中括号不需要写出来)
|
|
4
|
+
*
|
|
5
|
+
* quote:
|
|
6
|
+
* {% quote [indent:true/false] %}
|
|
7
|
+
* body
|
|
8
|
+
* {% endquote %}
|
|
9
|
+
*
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
'use strict'
|
|
13
|
+
|
|
14
|
+
module.exports = ctx => function(args, content) {
|
|
15
|
+
var el = ''
|
|
16
|
+
args = ctx.args.map(args, ['indent'], [])
|
|
17
|
+
|
|
18
|
+
el += `<div class="tag-plugin quote" indent="${args.indent}">`
|
|
19
|
+
el += ctx.render.renderSync({text: content, engine: 'markdown'}).split('\n').join('')
|
|
20
|
+
el += `</div>`
|
|
21
|
+
return el
|
|
22
|
+
}
|
|
@@ -9,11 +9,12 @@
|
|
|
9
9
|
|
|
10
10
|
module.exports = ctx => function(args) {
|
|
11
11
|
args = ctx.args.map(args, ['repo', 'api'], ['group'])
|
|
12
|
+
const host = ctx.theme.config.api_host.ghraw
|
|
12
13
|
var api
|
|
13
14
|
if (args.api) {
|
|
14
15
|
api = args.api
|
|
15
16
|
} else if (args.repo) {
|
|
16
|
-
api =
|
|
17
|
+
api = `https://${host}/${args.repo}/output/v2/data.json`
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
var el = '<div class="tag-plugin sites-wrap">'
|
|
@@ -32,8 +32,8 @@ module.exports = ctx => function (args) {
|
|
|
32
32
|
</div>
|
|
33
33
|
`
|
|
34
34
|
}
|
|
35
|
-
return `<div class="tag-plugin video" style="max-width:${args.width};">
|
|
36
|
-
<video controls preload>
|
|
35
|
+
return `<div class="tag-plugin video-player" style="max-width:${args.width};">
|
|
36
|
+
<video controls preload playsinline webkit-playsinline>
|
|
37
37
|
<source src="${args.src}" type="${args.type || 'video/mp4'}">Your browser does not support the video tag.
|
|
38
38
|
</video>
|
|
39
39
|
</div>
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
.canonical-tip
|
|
2
|
+
position: fixed
|
|
3
|
+
text-align: center
|
|
4
|
+
bottom: 4rem
|
|
5
|
+
left: 50%
|
|
6
|
+
transform: translateX(-50%)
|
|
7
|
+
max-width: 90%
|
|
8
|
+
background-color: var(--block-hover)
|
|
9
|
+
color: var(--text-p1)
|
|
10
|
+
font-size: 1rem
|
|
11
|
+
font-family: #fff8e1
|
|
12
|
+
z-index: 9999999
|
|
13
|
+
box-shadow: 0 2px 8px rgba(black, .1), 0 4px 16px rgba(black, .1), 0 8px 32px rgba(black, .1)
|
|
14
|
+
border-radius: 6px
|
|
15
|
+
.headline
|
|
16
|
+
font-size: $fsh2
|
|
17
|
+
a
|
|
18
|
+
display: block
|
|
19
|
+
color: inherit
|
|
20
|
+
padding: 1rem 2rem
|
|
21
|
+
|
|
22
|
+
.canonical-tip.unofficial
|
|
23
|
+
background-color: hsl(5, 100%, 60%)
|
|
24
|
+
color: white
|
|
25
|
+
animation: breathe 3s ease-in-out infinite
|
|
26
|
+
@keyframes breathe
|
|
27
|
+
0%
|
|
28
|
+
background-color: hsl(5, 100%, 60%)
|
|
29
|
+
50%
|
|
30
|
+
background-color: hsl(5, 100%, 30%)
|
|
31
|
+
100%
|
|
32
|
+
background-color: hsl(5, 100%, 60%)
|
|
@@ -10,14 +10,13 @@
|
|
|
10
10
|
.float-panel
|
|
11
11
|
position: sticky
|
|
12
12
|
grid-column-end: span 3
|
|
13
|
-
padding: 4px
|
|
14
13
|
--inset: 2rem
|
|
15
14
|
right: 0
|
|
16
15
|
bottom: calc(var(--inset) * 2)
|
|
17
16
|
margin-left: auto
|
|
18
17
|
margin-right: var(--inset)
|
|
19
18
|
float: right
|
|
20
|
-
z-index:
|
|
19
|
+
z-index: 999999
|
|
21
20
|
display: flex
|
|
22
21
|
justify-content: center
|
|
23
22
|
flex-direction: column
|
|
@@ -26,6 +25,9 @@
|
|
|
26
25
|
margin-right: 3rem
|
|
27
26
|
overflow: hidden
|
|
28
27
|
trans1: all
|
|
28
|
+
&:before,&:after
|
|
29
|
+
border-radius: 64px
|
|
30
|
+
|
|
29
31
|
newblur()
|
|
30
32
|
|
|
31
33
|
|
|
@@ -34,8 +36,8 @@
|
|
|
34
36
|
cursor: pointer
|
|
35
37
|
color: var(--text)
|
|
36
38
|
background: none
|
|
37
|
-
width:
|
|
38
|
-
height:
|
|
39
|
+
width: 48px
|
|
40
|
+
height: 48px
|
|
39
41
|
line-height: 0
|
|
40
42
|
font-size: 28px
|
|
41
43
|
margin: 0
|
|
@@ -49,10 +51,11 @@
|
|
|
49
51
|
// 侧边栏弹出后
|
|
50
52
|
.l_body[leftbar] .float-panel, .l_body[rightbar] .float-panel
|
|
51
53
|
box-shadow: 0 0 4px -1px $color-theme, 0 0 16px -4px $color-theme, 0 0 32px -12px $color-theme, 0 0 128px -32px $color-theme
|
|
54
|
+
&:before
|
|
55
|
+
background: var(--alpha50)
|
|
52
56
|
|
|
53
57
|
.l_body[leftbar] .float-panel button.leftbar-toggle
|
|
54
58
|
color: $color-theme
|
|
55
|
-
border-color: var(--block-border)
|
|
56
59
|
svg g
|
|
57
60
|
fill: currentColor
|
|
58
61
|
fill-opacity: 0.3
|
|
@@ -66,7 +69,6 @@
|
|
|
66
69
|
|
|
67
70
|
.l_body[rightbar] .float-panel button.rightbar-toggle
|
|
68
71
|
color: $color-theme
|
|
69
|
-
border-color: var(--block-border)
|
|
70
72
|
svg g
|
|
71
73
|
fill: currentColor
|
|
72
74
|
fill-opacity: 0.3
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
--inset: 8px
|
|
42
42
|
right: var(--inset)
|
|
43
43
|
top: var(--inset)
|
|
44
|
-
max-height: 'calc(%s -
|
|
44
|
+
max-height: 'calc(%s - %s)' % (100vh $rightbar-bottom-margin)
|
|
45
45
|
box-shadow: $boxshadow-card-float
|
|
46
46
|
z-index: 10
|
|
47
47
|
background: var(--site-bg)
|
|
@@ -71,10 +71,10 @@
|
|
|
71
71
|
--inset: 8px
|
|
72
72
|
left: var(--inset)
|
|
73
73
|
top: var(--inset)
|
|
74
|
-
max-height: 'calc(%s -
|
|
74
|
+
max-height: 'calc(%s - %s)' % (100vh $leftbar-bottom-margin)
|
|
75
75
|
.leftbar-container
|
|
76
76
|
--inset: 8px
|
|
77
|
-
height: 'calc(%s -
|
|
77
|
+
height: 'calc(%s - %s)' % (100vh $leftbar-bottom-margin)
|
|
78
78
|
box-shadow: $boxshadow-card-float
|
|
79
79
|
z-index: 10
|
|
80
80
|
.l_main
|
|
@@ -33,17 +33,23 @@
|
|
|
33
33
|
position: relative
|
|
34
34
|
|
|
35
35
|
h3:not([class])
|
|
36
|
+
position: relative
|
|
36
37
|
&:before,&:after
|
|
37
|
-
|
|
38
|
-
|
|
38
|
+
position absolute
|
|
39
|
+
font-size: 1.2em
|
|
40
|
+
background-color: hsla($color-theme, 0.5)
|
|
41
|
+
width: 1em
|
|
42
|
+
height: 1em
|
|
43
|
+
content: ''
|
|
44
|
+
opacity 1
|
|
45
|
+
display: inline-block
|
|
39
46
|
trans1 all
|
|
40
|
-
|
|
41
|
-
|
|
47
|
+
vertical-align: middle
|
|
48
|
+
&:before
|
|
49
|
+
margin-left: -1em
|
|
50
|
+
svg-mask-icon($h3Left)
|
|
42
51
|
&:after
|
|
43
|
-
|
|
44
|
-
&:hover
|
|
45
|
-
&:before,&:after
|
|
46
|
-
color: hsla($color-theme, 1)
|
|
52
|
+
svg-mask-icon($h3Right)
|
|
47
53
|
|
|
48
54
|
h4:not([class])
|
|
49
55
|
position: relative
|
|
@@ -56,12 +62,14 @@
|
|
|
56
62
|
margin-top: -12px
|
|
57
63
|
background: hsla($color-theme, 0.3)
|
|
58
64
|
border-radius: 50%
|
|
59
|
-
|
|
65
|
+
--blur-px: 8px
|
|
66
|
+
filter: blur(var(--blur-px))
|
|
60
67
|
pointer-events: none
|
|
61
68
|
z-index: -1
|
|
62
|
-
trans1 all
|
|
69
|
+
trans1 all 0.5s
|
|
63
70
|
&:hover:before
|
|
64
|
-
|
|
71
|
+
--blur-px: 24px
|
|
72
|
+
background: hsla($color-theme, 1)
|
|
65
73
|
|
|
66
74
|
ol,ul
|
|
67
75
|
margin-left: 'calc(%s * 2)' % var(--fsp)
|
|
@@ -71,7 +79,7 @@
|
|
|
71
79
|
>a:first-child
|
|
72
80
|
display: none
|
|
73
81
|
// 修正缩进效果
|
|
74
|
-
>blockquote
|
|
82
|
+
>blockquote,.tag-plugin.quote
|
|
75
83
|
text-align: center
|
|
76
84
|
--inset: calc(var(--fsp) * 2)
|
|
77
85
|
margin-left: var(--inset)
|
|
@@ -2,9 +2,6 @@
|
|
|
2
2
|
margin: 8px
|
|
3
3
|
max-height: 'calc(%s - 16px)' % 100vh
|
|
4
4
|
border-radius: $border-card-l
|
|
5
|
-
overflow: hidden
|
|
6
|
-
overflow: clip
|
|
7
|
-
overflow-clip-margin: .5px
|
|
8
5
|
.header
|
|
9
6
|
margin: var(--gap-max) var(--gap-margin) 0
|
|
10
7
|
|
|
@@ -20,23 +17,70 @@
|
|
|
20
17
|
margin-right: auto
|
|
21
18
|
|
|
22
19
|
.l_left
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
20
|
+
.sidebg
|
|
21
|
+
pointer-events: none
|
|
22
|
+
position: absolute
|
|
23
|
+
--inset: 0
|
|
24
|
+
top: var(--inset)
|
|
25
|
+
bottom: var(--inset)
|
|
26
|
+
left: var(--inset)
|
|
27
|
+
right: var(--inset)
|
|
28
|
+
background-position: center
|
|
29
|
+
background-size: cover
|
|
30
|
+
border-radius: $border-card-l
|
|
31
|
+
--saturate: 300%
|
|
32
|
+
--blur-px: convert(hexo-config('style.leftbar.blur-px'))
|
|
33
|
+
--brightness: 100%
|
|
34
|
+
if hexo-config('style.leftbar') && hexo-config('style.leftbar.background-image')
|
|
35
|
+
if hexo-config('style.leftbar.blur-px')
|
|
36
|
+
--inset: 32px
|
|
37
|
+
background-image: convert(hexo-config('style.leftbar.background-image'))
|
|
38
|
+
filter: saturate(var(--saturate)) brightness(var(--brightness)) blur(var(--blur-px))
|
|
39
|
+
@media screen and (prefers-color-scheme: dark)
|
|
40
|
+
--blur-px: 'calc(%s * 0.75)' % convert(hexo-config('style.leftbar.blur-px'))
|
|
41
|
+
--saturate: 200%
|
|
42
|
+
--brightness: 75%
|
|
43
|
+
else if hexo-config('style.leftbar') && hexo-config('style.leftbar.background')
|
|
44
|
+
background: convert(hexo-config('style.leftbar.background'))
|
|
45
|
+
|
|
29
46
|
.leftbar-container
|
|
30
|
-
height: 'calc(%s -
|
|
47
|
+
height: 'calc(%s - 80px)' % 100vh
|
|
31
48
|
display: flex
|
|
32
49
|
flex-direction: column
|
|
33
50
|
word-break: break-all
|
|
34
51
|
text-align: justify
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
52
|
+
border-radius: $border-card-l
|
|
53
|
+
overflow: hidden
|
|
54
|
+
>.widgets
|
|
55
|
+
mask: linear-gradient(transparent, white, 10%, white, 90%, transparent)
|
|
56
|
+
>*
|
|
57
|
+
z-index 1
|
|
58
|
+
&:before,&:after
|
|
59
|
+
position: absolute
|
|
60
|
+
pointer-events: none
|
|
61
|
+
content: ''
|
|
62
|
+
top: 0
|
|
63
|
+
bottom: 0
|
|
64
|
+
left: 0
|
|
65
|
+
right: 0
|
|
66
|
+
border-radius: $border-card-l
|
|
67
|
+
&:before
|
|
68
|
+
@media screen and (min-width: $device-mobile-max)
|
|
69
|
+
background: rgba(white, 0.5)
|
|
70
|
+
box-shadow: inset 0 0 32px 1px rgba(white, 0.5)
|
|
71
|
+
backdrop-filter: saturate(300%)
|
|
72
|
+
mask: linear-gradient(black, rgba(black, 0.5), 70%, transparent, 90%, transparent)
|
|
73
|
+
|
|
74
|
+
@media screen and (prefers-color-scheme: dark)
|
|
75
|
+
background: rgba(white, 0.05)
|
|
76
|
+
box-shadow: inset 0 0 32px 1px rgba(white, 0.2)
|
|
77
|
+
|
|
78
|
+
@media screen and (max-width: $device-mobile-max)
|
|
79
|
+
.l_left
|
|
80
|
+
overflow: hidden
|
|
81
|
+
background: var(--alpha100)
|
|
82
|
+
.sidebg
|
|
83
|
+
--inset: 0
|
|
84
|
+
--saturate: 300%
|
|
85
|
+
.leftbar-container:after
|
|
86
|
+
background: var(--alpha20)
|
package/source/css/_custom.styl
CHANGED
|
@@ -21,6 +21,9 @@ $ff-logo = $ff-body
|
|
|
21
21
|
$iQuoteLeft = "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 BoxIcons Solid by Atisa - https://creativecommons.org/licenses/by/4.0/ --%3E%3Cpath fill='currentColor' d='M3.691 6.292C5.094 4.771 7.217 4 10 4h1v2.819l-.804.161c-1.37.274-2.323.813-2.833 1.604A2.9 2.9 0 0 0 6.925 10H10a1 1 0 0 1 1 1v7c0 1.103-.897 2-2 2H3a1 1 0 0 1-1-1v-5l.003-2.919c-.009-.111-.199-2.741 1.688-4.789M20 20h-6a1 1 0 0 1-1-1v-5l.003-2.919c-.009-.111-.199-2.741 1.688-4.789C16.094 4.771 18.217 4 21 4h1v2.819l-.804.161c-1.37.274-2.323.813-2.833 1.604A2.9 2.9 0 0 0 17.925 10H21a1 1 0 0 1 1 1v7c0 1.103-.897 2-2 2'/%3E%3C/svg%3E"
|
|
22
22
|
$iQuoteRight = "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 BoxIcons Solid by Atisa - https://creativecommons.org/licenses/by/4.0/ --%3E%3Cpath fill='currentColor' d='M20.309 17.708C22.196 15.66 22.006 13.03 22 13V5a1 1 0 0 0-1-1h-6c-1.103 0-2 .897-2 2v7a1 1 0 0 0 1 1h3.078a2.9 2.9 0 0 1-.429 1.396c-.508.801-1.465 1.348-2.846 1.624l-.803.16V20h1c2.783 0 4.906-.771 6.309-2.292m-11.007 0C11.19 15.66 10.999 13.03 10.993 13V5a1 1 0 0 0-1-1h-6c-1.103 0-2 .897-2 2v7a1 1 0 0 0 1 1h3.078a2.9 2.9 0 0 1-.429 1.396c-.508.801-1.465 1.348-2.846 1.624l-.803.16V20h1c2.783 0 4.906-.771 6.309-2.292'/%3E%3C/svg%3E"
|
|
23
23
|
|
|
24
|
+
$h3Left = "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='currentColor' fill-rule='evenodd' d='M13.488 4.43a.75.75 0 0 1 .081 1.058L7.988 12l5.581 6.512a.75.75 0 1 1-1.138.976l-6-7a.75.75 0 0 1 0-.976l6-7a.75.75 0 0 1 1.057-.081' clip-rule='evenodd'/%3E%3Cpath fill='currentColor' d='M17.75 5a.75.75 0 0 0-1.32-.488l-6 7a.75.75 0 0 0 0 .976l6 7A.75.75 0 0 0 17.75 19z'/%3E%3C/svg%3E"
|
|
25
|
+
$h3Right = "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='currentColor' fill-rule='evenodd' d='M10.512 4.43a.75.75 0 0 0-.081 1.058L16.012 12l-5.581 6.512a.75.75 0 1 0 1.138.976l6-7a.75.75 0 0 0 0-.976l-6-7a.75.75 0 0 0-1.057-.081' clip-rule='evenodd'/%3E%3Cpath fill='currentColor' d='M6.25 5a.75.75 0 0 1 1.32-.488l6 7a.75.75 0 0 1 0 .976l-6 7A.75.75 0 0 1 6.25 19z'/%3E%3C/svg%3E"
|
|
26
|
+
|
|
24
27
|
if hexo-config('style.font-family.body')
|
|
25
28
|
$ff-body = convert(hexo-config('style.font-family.body'))
|
|
26
29
|
|
|
@@ -134,7 +134,7 @@ hoverable-card()
|
|
|
134
134
|
ondark()
|
|
135
135
|
|
|
136
136
|
newblur()
|
|
137
|
-
box-shadow: 0 0 2px rgba(black, .
|
|
137
|
+
box-shadow: 0 0 2px rgba(black, .02), 0 2px 8px rgba(black, .03), 0 4px 16px rgba(black, .05)
|
|
138
138
|
trans1: all
|
|
139
139
|
&:before,&:after
|
|
140
140
|
z-index -1
|
|
@@ -149,12 +149,12 @@ newblur()
|
|
|
149
149
|
&:before
|
|
150
150
|
backdrop-filter: blur(8px)
|
|
151
151
|
&:after
|
|
152
|
-
--blur-px:
|
|
152
|
+
--blur-px: 32px
|
|
153
153
|
--blur-sat: 500%
|
|
154
|
-
background: var(--
|
|
154
|
+
background: var(--alpha20)
|
|
155
155
|
backdrop-filter: saturate(var(--blur-sat)) blur(var(--blur-px))
|
|
156
|
-
mask: linear-gradient(rgba(white, 1), 10%, rgba(white, 0.
|
|
157
|
-
box-shadow: inset 0 0
|
|
156
|
+
mask: linear-gradient(rgba(white, 1), 10%, rgba(white, 0.1), 90%, rgba(white, 1)), linear-gradient(90deg, rgba(white, 1), 10%, rgba(white, 0.1), 90%, rgba(white, 1))
|
|
157
|
+
box-shadow: inset 0 0 4px 1px rgba(white, 0.5)
|
|
158
158
|
trans1 all
|
|
159
159
|
@media (prefers-color-scheme: dark)
|
|
160
160
|
opacity 0.4
|
|
@@ -121,11 +121,11 @@ _common_root()
|
|
|
121
121
|
_dark_root()
|
|
122
122
|
|
|
123
123
|
@media (prefers-color-scheme: dark)
|
|
124
|
-
:root:not([
|
|
124
|
+
:root:not([data-theme])
|
|
125
125
|
img,
|
|
126
126
|
.md-text .tag-plugin.chat>.content .chatcell .user-main .talk.file>.content>.top>.right>svg.icon>path
|
|
127
127
|
filter: brightness(75%)!important
|
|
128
|
-
[
|
|
128
|
+
[data-theme='dark']
|
|
129
129
|
img,
|
|
130
130
|
.md-text .tag-plugin.chat>.content .chatcell .user-main .talk.file>.content>.top>.right>svg.icon>path
|
|
131
131
|
filter: brightness(75%)!important
|
package/source/js/main.js
CHANGED
|
@@ -200,6 +200,55 @@ const init = {
|
|
|
200
200
|
window.dispatchEvent(new Event('tabs:register'));
|
|
201
201
|
},
|
|
202
202
|
|
|
203
|
+
canonicalCheck: () => {
|
|
204
|
+
const canonical = window.canonical;
|
|
205
|
+
function showTip(isOfficial = false) {
|
|
206
|
+
const meta = document.createElement('meta');
|
|
207
|
+
meta.name = 'robots';
|
|
208
|
+
meta.content = 'noindex, nofollow';
|
|
209
|
+
document.head.appendChild(meta);
|
|
210
|
+
const notice = document.createElement('div');
|
|
211
|
+
const originalURL = `https://${canonical.originalHost}`;
|
|
212
|
+
if (isOfficial) {
|
|
213
|
+
notice.className = 'canonical-tip official';
|
|
214
|
+
notice.innerHTML = `
|
|
215
|
+
<a href="${originalURL}" target="_self" rel="noopener noreferrer">
|
|
216
|
+
本站为官方备用站,仅供应急。主站:${originalURL}
|
|
217
|
+
</a>
|
|
218
|
+
`;
|
|
219
|
+
} else {
|
|
220
|
+
notice.className = 'canonical-tip unofficial';
|
|
221
|
+
notice.innerHTML = `
|
|
222
|
+
<a href="${originalURL}" target="_self" rel="noopener noreferrer">
|
|
223
|
+
<div class="headline icon">☠️</div>
|
|
224
|
+
本站为非法克隆站,请前往官方源站访问。<br>
|
|
225
|
+
源站:${originalURL}
|
|
226
|
+
</a>
|
|
227
|
+
`;
|
|
228
|
+
}
|
|
229
|
+
document.body.appendChild(notice);
|
|
230
|
+
}
|
|
231
|
+
if (!canonical.originalHost) return;
|
|
232
|
+
const canonicalTag = document.querySelector('link[rel="canonical"]');
|
|
233
|
+
if (!canonicalTag) {
|
|
234
|
+
showTip(false);
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
const canonicalURL = new URL(canonicalTag.href);
|
|
238
|
+
const currentURL = new URL(window.location.href);
|
|
239
|
+
const canonicalHost = canonicalURL.hostname.replace(/^www\./, '');
|
|
240
|
+
const currentHost = currentURL.hostname.replace(/^www\./, '');
|
|
241
|
+
if (currentHost == 'localhost') return;
|
|
242
|
+
const encodedCanonicalHost = window.btoa(canonicalHost);
|
|
243
|
+
const encodedCurrentHost = window.btoa(currentHost);
|
|
244
|
+
const isCanonicalHostValid = canonical.encoded === encodedCanonicalHost;
|
|
245
|
+
const isCurrentHostValid = canonical.encoded === encodedCurrentHost;
|
|
246
|
+
if (isCanonicalHostValid && isCurrentHostValid) {
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
showTip(canonical.officialHosts?.includes(currentHost));
|
|
250
|
+
}
|
|
251
|
+
|
|
203
252
|
}
|
|
204
253
|
|
|
205
254
|
|
|
@@ -208,3 +257,4 @@ init.toc()
|
|
|
208
257
|
init.sidebar()
|
|
209
258
|
init.relativeDate(document.querySelectorAll('#post-meta time'))
|
|
210
259
|
init.registerTabsTag()
|
|
260
|
+
init.canonicalCheck()
|
|
@@ -167,7 +167,7 @@ function extToMimes(ext) {
|
|
|
167
167
|
function downloadFileEvent(fileDoms) {
|
|
168
168
|
for (let i = 0; i < fileDoms.length; ++i) {
|
|
169
169
|
let fileDom = fileDoms[i];
|
|
170
|
-
const api = ctx.tag_plugins.chat.api + '?type=file&url='
|
|
170
|
+
const api = ctx.tag_plugins.chat.api + '?type=file&url=';
|
|
171
171
|
const obverser = new IntersectionObserver((entries, observer) => {
|
|
172
172
|
utils.requestAnimationFrame(()=>{
|
|
173
173
|
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) => {
|