hexo-theme-stellar 1.42.1 → 1.43.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/.claude/skills/stellar-theme-dev/SKILL.md +1 -0
- package/CHANGELOG.md +31 -0
- package/THIRD-PARTY-NOTICES.md +28 -0
- package/_config.yml +17 -7
- package/_data/icons.yml +10 -9
- package/languages/en.yml +11 -0
- package/languages/zh-CN.yml +11 -0
- package/languages/zh-TW.yml +11 -0
- package/layout/_partial/comments/artalk/layout.ejs +1 -1
- package/layout/_partial/comments/beaudar/layout.ejs +1 -1
- package/layout/_partial/comments/giscus/layout.ejs +1 -1
- package/layout/_partial/comments/twikoo/layout.ejs +1 -1
- package/layout/_partial/comments/utterances/layout.ejs +1 -1
- package/layout/_partial/comments/waline/layout.ejs +1 -1
- package/layout/_partial/components/collection-item.ejs +44 -0
- package/layout/_partial/components/collection.ejs +26 -0
- package/layout/_partial/components/widget-frame.ejs +35 -0
- package/layout/_partial/cover/wiki_cover.ejs +82 -26
- package/layout/_partial/dropdown.ejs +62 -0
- package/layout/_partial/head.ejs +9 -0
- package/layout/_partial/main/navbar/breadcrumb/blog.ejs +1 -1
- package/layout/_partial/main/post_list/archive_item.ejs +12 -0
- package/layout/_partial/main/post_list/topic_card.ejs +21 -9
- package/layout/_partial/main/post_list/wiki_card.ejs +49 -10
- package/layout/_partial/scripts/defines.ejs +2 -8
- package/layout/_partial/scripts/lazyload.ejs +0 -3
- package/layout/_partial/scripts.ejs +1 -0
- package/layout/_partial/sidebar/index_leftbar.ejs +12 -2
- package/layout/_partial/sidebar/logo.ejs +1 -1
- package/layout/_partial/sidebar/menu.ejs +21 -23
- package/layout/_partial/widgets/components/linklist.ejs +23 -21
- package/layout/_partial/widgets/linklist.ejs +7 -12
- package/layout/_partial/widgets/recent.ejs +52 -41
- package/layout/_partial/widgets/related.ejs +47 -36
- package/layout/_partial/widgets/tagtree.ejs +70 -54
- package/layout/_partial/widgets/toc.ejs +37 -62
- package/layout/_partial/widgets/tree.ejs +38 -51
- package/layout/_plugins/mermaid.ejs +3 -4
- package/layout/archive.ejs +11 -20
- package/layout/collection-preview.ejs +60 -0
- package/layout/index_topic.ejs +12 -6
- package/layout/index_wiki.ejs +49 -3
- package/layout/layout.ejs +4 -3
- package/package.json +1 -1
- package/scripts/events/index.js +0 -2
- package/scripts/generators/stellar-icons.js +1 -1
- package/scripts/lib/subtitle.js +5 -1
- package/scripts/tags/index.js +1 -0
- package/scripts/tags/lib/about.js +1 -1
- package/scripts/tags/lib/albums.js +1 -1
- package/scripts/tags/lib/banner.js +1 -1
- package/scripts/tags/lib/dropdown.js +64 -0
- package/scripts/tags/lib/friends.js +1 -1
- package/scripts/tags/lib/gallery.js +3 -3
- package/scripts/tags/lib/image.js +1 -1
- package/scripts/tags/lib/posters.js +1 -1
- package/scripts/tags/lib/sites.js +8 -4
- package/source/css/_common/base.styl +4 -4
- package/source/css/_common/blockquote.styl +2 -2
- package/source/css/_common/dropdown.styl +132 -0
- package/source/css/_common/html.styl +1 -1
- package/source/css/_common/loading.styl +5 -2
- package/source/css/_common/title.styl +8 -8
- package/source/css/_components/collection.styl +188 -0
- package/source/css/_components/layout.styl +1 -1
- package/source/css/_components/list.styl +44 -46
- package/source/css/_components/md.styl +3 -3
- package/source/css/_components/page-transition.styl +22 -0
- package/source/css/_components/pages/archives.styl +19 -18
- package/source/css/_components/pages/article-indent.styl +2 -2
- package/source/css/_components/pages/article-story.styl +9 -5
- package/source/css/_components/pages/collection-preview.styl +68 -0
- package/source/css/_components/pages/notebook.styl +11 -9
- package/source/css/_components/partial/article-footer.styl +7 -4
- package/source/css/_components/partial/cover.styl +280 -1
- package/source/css/_components/partial/related.styl +10 -6
- package/source/css/_components/sidebar/footer.styl +65 -12
- package/source/css/_components/sidebar/nav-area.styl +6 -1
- package/source/css/_components/sidebar/search.styl +6 -2
- package/source/css/_components/tag-plugins/chat.styl +1 -1
- package/source/css/_components/tag-plugins/folders.styl +4 -4
- package/source/css/_components/tag-plugins/folding.styl +3 -3
- package/source/css/_components/tag-plugins/hashtag.styl +2 -3
- package/source/css/_components/tag-plugins/mdrender.styl +1 -1
- package/source/css/_components/tag-plugins/note.styl +4 -4
- package/source/css/_components/tag-plugins/poetry.styl +5 -5
- package/source/css/_components/tag-plugins/quot.styl +1 -2
- package/source/css/_components/tag-plugins/quote.styl +1 -1
- package/source/css/_components/tag-plugins/tabs.styl +2 -2
- package/source/css/_components/tag-plugins/timeline.styl +4 -4
- package/source/css/_components/widgets/markdown.styl +1 -14
- package/source/css/_components/widgets/timeline.styl +2 -2
- package/source/css/_components/widgets/toc.styl +22 -20
- package/source/css/_components/widgets/widgets.styl +13 -1
- package/source/css/_components/wiki-card.styl +209 -0
- package/source/css/_custom.styl +22 -20
- package/source/css/_plugins/lazyload.styl +8 -5
- package/source/css/comments/utterances.styl +2 -2
- package/source/css/plugins/mermaid.styl +31 -12
- package/source/js/icons.js +1 -1
- package/source/js/main.js +62 -6
- package/source/js/plugins/adaptive-text.js +46 -2
- package/source/js/plugins/dropdown.js +435 -0
- package/source/js/plugins/galaxy.js +423 -0
- package/source/js/search/algolia-search.js +1 -1
- package/source/js/search/local-search.js +1 -1
- package/source/js/services/ghinfo.js +31 -3
- package/source/js/services/siteinfo.js +26 -0
- package/source/js/services/sites.js +6 -2
- package/source/js/services.js +5 -2
- package/source/js/tagtree.js +7 -7
- package/source/js/utils.js +1 -1
- package/layout/_partial/widgets/components/link.ejs +0 -21
- package/source/css/_components/sidebar/menu.styl +0 -77
- package/source/css/_components/widgets/components.styl +0 -68
- package/source/css/_components/widgets/list.styl +0 -46
- package/source/css/_components/widgets/related.styl +0 -40
package/layout/index_wiki.ejs
CHANGED
|
@@ -13,14 +13,22 @@ function layout_wiki_list(partial) {
|
|
|
13
13
|
if (page.filter === false) {
|
|
14
14
|
// wikiList
|
|
15
15
|
el += `<div class="post-card-wrap${scrollreveal(' ')}">`
|
|
16
|
-
|
|
16
|
+
var coverStyle = ''
|
|
17
|
+
if (proj.cover) {
|
|
18
|
+
coverStyle = ` style="--cover-url:url('${escape_html(proj.cover.replace(/'/g, '%27'))}')"`
|
|
19
|
+
}
|
|
20
|
+
el += `<a class="wiki-card${proj.cover ? '' : ' no-cover'}"${coverStyle} href="${pretty_url(proj.homepage?.path || '/')}">`
|
|
17
21
|
el += partial(proj)
|
|
18
22
|
el += `</a>`
|
|
19
23
|
el += `</div>`
|
|
20
24
|
} else if (proj.tags && proj.tags.includes(page.tagName) === true) {
|
|
21
25
|
// filtered wikiList
|
|
22
26
|
el += `<div class="post-card-wrap${scrollreveal(' ')} filter">`
|
|
23
|
-
|
|
27
|
+
var coverStyle = ''
|
|
28
|
+
if (proj.cover) {
|
|
29
|
+
coverStyle = ` style="--cover-url:url('${escape_html(proj.cover.replace(/'/g, '%27'))}')"`
|
|
30
|
+
}
|
|
31
|
+
el += `<a class="wiki-card${proj.cover ? '' : ' no-cover'}"${coverStyle} href="${pretty_url(proj.homepage?.path || '/')}">`
|
|
24
32
|
el += partial(proj)
|
|
25
33
|
el += `</a>`
|
|
26
34
|
el += `</div>`
|
|
@@ -41,4 +49,42 @@ function layoutDiv() {
|
|
|
41
49
|
}
|
|
42
50
|
%>
|
|
43
51
|
|
|
44
|
-
<%- layoutDiv() %>
|
|
52
|
+
<%- layoutDiv() %>
|
|
53
|
+
<script>
|
|
54
|
+
// Wiki 覆盖层须同时等待封面原图和平均主题色完成,避免默认主题色短暂闪现。
|
|
55
|
+
function revealWikiCover(card) {
|
|
56
|
+
if (card._wikiImageReady && card._wikiOverlayReady && !card.classList.contains('no-cover')) {
|
|
57
|
+
card.classList.add('cover-loaded');
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
document.addEventListener('wiki-overlay-ready', function(event) {
|
|
61
|
+
var card = event.target.closest('.wiki-card');
|
|
62
|
+
if (!card) return;
|
|
63
|
+
card._wikiOverlayReady = true;
|
|
64
|
+
revealWikiCover(card);
|
|
65
|
+
});
|
|
66
|
+
document.querySelectorAll('.wiki-card-cover:not(.no-cover) > img').forEach(function(img) {
|
|
67
|
+
var cover = img.parentElement;
|
|
68
|
+
var card = img.closest('.wiki-card');
|
|
69
|
+
if (!cover || !card) return;
|
|
70
|
+
var loaded = function() {
|
|
71
|
+
card._wikiImageReady = true;
|
|
72
|
+
revealWikiCover(card);
|
|
73
|
+
};
|
|
74
|
+
var failed = function() {
|
|
75
|
+
card._wikiImageReady = false;
|
|
76
|
+
card.classList.remove('cover-loaded');
|
|
77
|
+
card.classList.add('no-cover');
|
|
78
|
+
cover.classList.add('no-cover', 'cover-error');
|
|
79
|
+
};
|
|
80
|
+
img.addEventListener('load', loaded, { once: true });
|
|
81
|
+
img.addEventListener('error', failed, { once: true });
|
|
82
|
+
if (img.complete) {
|
|
83
|
+
if (img.naturalWidth > 0) {
|
|
84
|
+
loaded();
|
|
85
|
+
} else {
|
|
86
|
+
failed();
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
</script>
|
package/layout/layout.ejs
CHANGED
|
@@ -49,19 +49,20 @@ if (theme.style.prefers_theme === 'auto') {
|
|
|
49
49
|
html += site_background
|
|
50
50
|
html += `<div id="l_cover">${partial('_partial/cover/index').trim()}</div>`
|
|
51
51
|
html += `<div class="l_body ${page_type}" id="start" layout="${page.layout}" type="${article_type}" ${indent ? 'text-indent' : ''}>`
|
|
52
|
-
|
|
52
|
+
var leftbarSurface = theme.style.leftbar?.['ui-style'] === 'card' ? 'card' : 'glass'
|
|
53
|
+
html += `<aside class="l_left${leftbarSurface === 'card' ? ' leftbar-card' : ''}" data-ui-surface="${leftbarSurface}">`
|
|
53
54
|
html += `<div class="sidebg"></div>`
|
|
54
55
|
html += `<div class="leftbar-container${theme.style.leftbar?.blur ? ' leftbar-blur' : ''}">`
|
|
55
56
|
html += partial('_partial/sidebar/index_leftbar')
|
|
56
57
|
html += `</div>`
|
|
57
58
|
html += `</aside>`
|
|
58
|
-
html += `<div class="l_main" id="main">`
|
|
59
|
+
html += `<div class="l_main" id="main" data-ui-surface="content">`
|
|
59
60
|
html += partial('_partial/sidebar/logo', {where: 'main'})
|
|
60
61
|
html += body
|
|
61
62
|
html += partial('_partial/main/footer')
|
|
62
63
|
html += `<div class="main-mask" onclick="sidebar.dismiss()"></div>`
|
|
63
64
|
html += `</div>`
|
|
64
|
-
html += `<aside class="l_right">`
|
|
65
|
+
html += `<aside class="l_right" data-ui-surface="sidebar">`
|
|
65
66
|
html += partial('_partial/sidebar/index_rightbar').trim()
|
|
66
67
|
html += `</aside>`
|
|
67
68
|
html += partial('_partial/menubtn')
|
package/package.json
CHANGED
package/scripts/events/index.js
CHANGED
|
@@ -41,7 +41,6 @@ hexo.on('ready', () => {
|
|
|
41
41
|
checkVersion(hexo, { useCache: true });
|
|
42
42
|
});
|
|
43
43
|
|
|
44
|
-
|
|
45
44
|
// 防止重复注册
|
|
46
45
|
let hasRun = false;
|
|
47
46
|
|
|
@@ -66,4 +65,3 @@ hexo.extend.filter.register('before_generate', async () => {
|
|
|
66
65
|
fixMarkdownImages(hexo); // 不用 await,因为是同步的
|
|
67
66
|
}
|
|
68
67
|
});
|
|
69
|
-
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// 与 layout/_partial/scripts/defines.ejs 中旧的白名单保持一致(客户端通过 ctx.icons 读取)。
|
|
6
6
|
hexo.extend.generator.register('stellar_icons', function () {
|
|
7
7
|
const icons = (this.theme.config && this.theme.config.icons) || {};
|
|
8
|
-
const keys = ['default:tocomment', 'default:
|
|
8
|
+
const keys = ['default:tocomment', 'default:warning', 'weibo:repeat', 'weibo:like'];
|
|
9
9
|
const out = {};
|
|
10
10
|
// 去除 SVG 注释(避免 <!-- / </script> 解析风险),再转义 <
|
|
11
11
|
for (const k of keys) {
|
package/scripts/lib/subtitle.js
CHANGED
|
@@ -3,12 +3,16 @@
|
|
|
3
3
|
const { stripHTML } = require('hexo-util');
|
|
4
4
|
|
|
5
5
|
// 文章一行小字取值(hero 卡片与置顶轮播共用,未来可复用于其它场景):
|
|
6
|
-
// subtitle
|
|
6
|
+
// subtitle(含 " | " 时取非空左侧)> description > excerpt/content 前 length 字(去 HTML、压缩空白、截断;省略号由 CSS 单行处理),空则返回空串。
|
|
7
7
|
function subtitle(post, length = 50) {
|
|
8
8
|
if (post == null) {
|
|
9
9
|
return '';
|
|
10
10
|
}
|
|
11
11
|
if (post.subtitle != null && String(post.subtitle).length > 0) {
|
|
12
|
+
const separator = String(post.subtitle).indexOf(' | ');
|
|
13
|
+
if (separator > 0) {
|
|
14
|
+
return String(post.subtitle).slice(0, separator);
|
|
15
|
+
}
|
|
12
16
|
return post.subtitle;
|
|
13
17
|
}
|
|
14
18
|
if (post.description != null && String(post.description).length > 0) {
|
package/scripts/tags/index.js
CHANGED
|
@@ -12,6 +12,7 @@ hexo.extend.tag.register('grid', require('./lib/grid')(hexo), true)
|
|
|
12
12
|
hexo.extend.tag.register('swiper', require('./lib/swiper')(hexo), true)
|
|
13
13
|
hexo.extend.tag.register('gallery', require('./lib/gallery')(hexo), {ends: true})
|
|
14
14
|
hexo.extend.tag.register('banner', require('./lib/banner')(hexo), true)
|
|
15
|
+
hexo.extend.tag.register('dropdown', require('./lib/dropdown')(hexo), true)
|
|
15
16
|
|
|
16
17
|
// data
|
|
17
18
|
hexo.extend.tag.register('users', require('./lib/friends')(hexo))
|
|
@@ -18,7 +18,7 @@ module.exports = ctx => function(args, content) {
|
|
|
18
18
|
el += '<div class="tag-plugin about">'
|
|
19
19
|
if (args.back) {
|
|
20
20
|
el += '<a class="nav-back cap" href="' + url_for(ctx.config.root) + '">'
|
|
21
|
-
el += ctx.utils.icon('default:
|
|
21
|
+
el += ctx.utils.icon('default:arrow-left')
|
|
22
22
|
el += '</a>'
|
|
23
23
|
}
|
|
24
24
|
// avatar
|
|
@@ -32,7 +32,7 @@ module.exports = ctx => function(args) {
|
|
|
32
32
|
el += `<div class="grid-cell album-card">`
|
|
33
33
|
el += `<a class="card-link lazy-box" target="_blank" rel="external nofollow noopener noreferrer" href="${item.url}">`
|
|
34
34
|
el += `<img class="lazy" data-src="${item.cover || item.icon || item.avatar || ctx.theme.config.default.cover}" onerror="javascript:this.removeAttribute("data-src");this.src="${ctx.theme.config.default.cover}";"/>`
|
|
35
|
-
el += `<div class="lazy-icon"
|
|
35
|
+
el += `<div class="lazy-icon"></div>`
|
|
36
36
|
el += `<div class="image-meta">`
|
|
37
37
|
if (item.title) {
|
|
38
38
|
el += `<span class="image-caption">${item.title}</span>`
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dropdown.js v1 | https://github.com/xaoxuu/hexo-theme-stellar/
|
|
3
|
+
*
|
|
4
|
+
* {% dropdown [direction:up/down] [align:left/right] title %}
|
|
5
|
+
* - icon:key [title](url)
|
|
6
|
+
* {% enddropdown %}
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict'
|
|
10
|
+
|
|
11
|
+
function parseItem(line) {
|
|
12
|
+
const matches = line.match(/^\s*(?:[-*]\s+)?(?:icon:([^\s]+)\s+)?\[([^\]]+)\]\(([^)\s]+)\)(?:\s+icon:([^\s]+))?\s*$/)
|
|
13
|
+
if (!matches) {
|
|
14
|
+
return null
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
icon: matches[1] || matches[4],
|
|
18
|
+
title: matches[2],
|
|
19
|
+
url: matches[3]
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
module.exports = ctx => function(args, content = '') {
|
|
24
|
+
const { escapeHTML, url_for } = require('hexo-util')
|
|
25
|
+
args = ctx.args.map(args, ['icon', 'direction', 'align', 'open'], ['title'])
|
|
26
|
+
if (!args.title) {
|
|
27
|
+
return ''
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const items = content.split(/\r?\n/).map(parseItem).filter(Boolean)
|
|
31
|
+
if (items.length === 0) {
|
|
32
|
+
return ''
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const direction = ['up', 'down'].includes(args.direction) ? args.direction : 'auto'
|
|
36
|
+
const align = ['left', 'right'].includes(args.align) ? args.align : 'auto'
|
|
37
|
+
const title = escapeHTML(args.title)
|
|
38
|
+
const toUrl = url_for.bind(ctx)
|
|
39
|
+
var el = `<details class="tag-plugin dropdown" direction="${direction}" align="${align}"`
|
|
40
|
+
if (args.open === 'true') {
|
|
41
|
+
el += ' open'
|
|
42
|
+
}
|
|
43
|
+
el += '>'
|
|
44
|
+
el += `<summary class="dropdown-trigger" title="${title}" aria-label="${title}">`
|
|
45
|
+
el += `<span>${title}</span>`
|
|
46
|
+
el += '<svg class="dropdown-arrow" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M6 9l6 6 6-6" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>'
|
|
47
|
+
el += '</summary>'
|
|
48
|
+
el += '<div class="dropdown-menu ui-collection" data-ui-surface="glass" data-layout="list" data-variant="nav" data-density="compact">'
|
|
49
|
+
for (const item of items) {
|
|
50
|
+
const url = String(item.url)
|
|
51
|
+
el += `<a class="dropdown-item ui-collection__item" href="${escapeHTML(toUrl(url))}`
|
|
52
|
+
if (url.includes('://')) {
|
|
53
|
+
el += '" target="_blank" rel="external nofollow noopener noreferrer">'
|
|
54
|
+
} else {
|
|
55
|
+
el += '" rel="noopener noreferrer">'
|
|
56
|
+
}
|
|
57
|
+
if (item.icon) {
|
|
58
|
+
el += `<span class="ui-collection__leading">${ctx.utils.icon(item.icon, 'no-lazy', true)}</span>`
|
|
59
|
+
}
|
|
60
|
+
el += `<span class="ui-collection__content"><span class="ui-collection__title">${escapeHTML(item.title)}</span></span></a>`
|
|
61
|
+
}
|
|
62
|
+
el += '</div></details>'
|
|
63
|
+
return el
|
|
64
|
+
}
|
|
@@ -29,7 +29,7 @@ module.exports = ctx => function(args) {
|
|
|
29
29
|
el += `<a class="card-link" target="_blank" rel="external nofollow noopener noreferrer" href="${item.url}">`
|
|
30
30
|
el += `<div class="lazy-box icon">`
|
|
31
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"
|
|
32
|
+
el += `<div class="lazy-icon"></div>`
|
|
33
33
|
el += `</div>`
|
|
34
34
|
el += `<div class="name">`
|
|
35
35
|
el += `<span>${item.title}</span>`
|
|
@@ -17,14 +17,14 @@
|
|
|
17
17
|
|
|
18
18
|
var index = 0
|
|
19
19
|
|
|
20
|
-
function img(src, alt
|
|
20
|
+
function img(src, alt) {
|
|
21
21
|
let img = ''
|
|
22
22
|
img += `<img class="lazy" data-fancybox="gallery-${index}" data-src="${src}"`
|
|
23
23
|
if (alt?.length > 0) {
|
|
24
24
|
img += ` alt="${alt}"`
|
|
25
25
|
}
|
|
26
26
|
img += `/>`
|
|
27
|
-
img += `<div class="lazy-icon"
|
|
27
|
+
img += `<div class="lazy-icon"></div>`
|
|
28
28
|
// cap
|
|
29
29
|
img += `<div class="image-meta">`
|
|
30
30
|
if (alt?.length > 0) {
|
|
@@ -55,7 +55,7 @@ module.exports = ctx => function(args, content) {
|
|
|
55
55
|
if (matches?.length > 2) {
|
|
56
56
|
let alt = matches[1]
|
|
57
57
|
let src = matches[2]
|
|
58
|
-
el += `<div class="${layoutType}-cell lazy-box">${img(src, alt
|
|
58
|
+
el += `<div class="${layoutType}-cell lazy-box">${img(src, alt)}</div>`
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
el += `</div>`
|
|
@@ -50,7 +50,7 @@ module.exports = ctx => function(args) {
|
|
|
50
50
|
img += `onerror="this.src="${ctx.theme.config.default.image_onerror || ctx.utils.iconData('image:onerror')}""`
|
|
51
51
|
img += '/>'
|
|
52
52
|
// loading
|
|
53
|
-
img += `<div class="lazy-icon"
|
|
53
|
+
img += `<div class="lazy-icon"></div>`
|
|
54
54
|
if (fancyboxHref) {
|
|
55
55
|
a += ` href="${fancyboxHref}">${img}</a>`
|
|
56
56
|
return a
|
|
@@ -32,7 +32,7 @@ module.exports = ctx => function(args) {
|
|
|
32
32
|
el += `<div class="grid-cell poster-card">`
|
|
33
33
|
el += `<a class="card-link lazy-box" target="_blank" rel="external nofollow noopener noreferrer" href="${item.url}">`
|
|
34
34
|
el += `<img class="lazy" data-src="${item.cover || item.icon || item.avatar || ctx.theme.config.default.cover}" onerror="javascript:this.removeAttribute("data-src");this.src="${ctx.theme.config.default.cover}";"/>`
|
|
35
|
-
el += `<div class="lazy-icon"
|
|
35
|
+
el += `<div class="lazy-icon"></div>`
|
|
36
36
|
el += `<div class="image-meta">`
|
|
37
37
|
if (item.title) {
|
|
38
38
|
el += `<span class="image-caption">${item.title}</span>`
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
module.exports = ctx => function(args) {
|
|
11
11
|
args = ctx.args.map(args, ['repo', 'api'], ['group'])
|
|
12
12
|
const host = ctx.theme.config.api_host.ghraw
|
|
13
|
+
const siteinfoApi = ctx.theme.config.data_services.siteinfo?.api
|
|
13
14
|
var api
|
|
14
15
|
if (args.api) {
|
|
15
16
|
api = args.api
|
|
@@ -29,16 +30,19 @@ module.exports = ctx => function(args) {
|
|
|
29
30
|
el += '<div class="grid-box">'
|
|
30
31
|
for (let item of (links[args.group] || [])) {
|
|
31
32
|
if (item?.url && item?.title) {
|
|
33
|
+
const itemSiteinfoApi = !item.icon && !item.avatar && siteinfoApi
|
|
34
|
+
? siteinfoApi.replace('{href}', item.url)
|
|
35
|
+
: ''
|
|
32
36
|
el += `<div class="grid-cell site-card">`
|
|
33
|
-
el += `<a class="card-link" target="_blank" rel="external nofollow noopener noreferrer" href="${item.url}">`
|
|
37
|
+
el += `<a class="card-link"${itemSiteinfoApi ? ` data-siteinfo-api="${itemSiteinfoApi}"` : ''} target="_blank" rel="external nofollow noopener noreferrer" href="${item.url}">`
|
|
34
38
|
el += `<div class="lazy-box snapshot">`
|
|
35
39
|
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
|
-
el += `<div class="lazy-icon"
|
|
40
|
+
el += `<div class="lazy-icon"></div>`
|
|
37
41
|
el += `</div>`
|
|
38
42
|
el += `<div class="info">`
|
|
39
43
|
el += `<div class="lazy-box icon">`
|
|
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
|
-
el += `<div class="lazy-icon"
|
|
44
|
+
el += `<img class="lazy siteinfo-icon" 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}";"/>`
|
|
45
|
+
el += `<div class="lazy-icon"></div>`
|
|
42
46
|
el += `</div>`
|
|
43
47
|
el += `<span class="title">${item.title}</span>`
|
|
44
48
|
el += `<span class="desc">${item.description || item.url}</span>`
|
|
@@ -24,11 +24,11 @@ img
|
|
|
24
24
|
max-width: 100%
|
|
25
25
|
|
|
26
26
|
li
|
|
27
|
-
font-size: 'calc(%s - 1px)' % var(--
|
|
27
|
+
font-size: 'calc(%s - 1px)' % var(--fs-content)
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
ul,ol
|
|
31
|
-
padding-left: var(--
|
|
31
|
+
padding-left: var(--fs-content)
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
// table
|
|
@@ -40,8 +40,8 @@ table:not([class])
|
|
|
40
40
|
margin: 1rem 0
|
|
41
41
|
max-width: 100%
|
|
42
42
|
vertical-align: text-top
|
|
43
|
-
--
|
|
44
|
-
font-size: var(--
|
|
43
|
+
--fs-content: $fs-content-2
|
|
44
|
+
font-size: var(--fs-content)
|
|
45
45
|
scrollbar(0,0)
|
|
46
46
|
th
|
|
47
47
|
background: var(--block)
|
|
@@ -2,7 +2,7 @@ blockquote
|
|
|
2
2
|
display: block
|
|
3
3
|
margin-left: 0
|
|
4
4
|
margin-right: 0
|
|
5
|
-
padding: 0 var(--
|
|
5
|
+
padding: 0 var(--fs-content)
|
|
6
6
|
$bd-left = 4px
|
|
7
7
|
color: var(--text-p3)
|
|
8
8
|
position: relative
|
|
@@ -18,4 +18,4 @@ blockquote
|
|
|
18
18
|
opacity: 0.5
|
|
19
19
|
background: var(--text-meta)
|
|
20
20
|
&:hover:before
|
|
21
|
-
background: var(--theme)
|
|
21
|
+
background: var(--theme)
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
.dropdown
|
|
2
|
+
position: relative
|
|
3
|
+
display: inline-block
|
|
4
|
+
z-index: 0
|
|
5
|
+
overflow: visible
|
|
6
|
+
line-height: 1
|
|
7
|
+
font-size: $fs-14
|
|
8
|
+
>.dropdown-trigger
|
|
9
|
+
display: inline-flex
|
|
10
|
+
align-items: center
|
|
11
|
+
gap: 0.5rem
|
|
12
|
+
box-sizing: border-box
|
|
13
|
+
min-height: 2rem
|
|
14
|
+
padding: 0.5rem 0.75rem
|
|
15
|
+
cursor: pointer
|
|
16
|
+
list-style: none
|
|
17
|
+
outline: none
|
|
18
|
+
border-radius: $border-bar
|
|
19
|
+
color: var(--text-p2)
|
|
20
|
+
background: var(--block)
|
|
21
|
+
text-decoration: none
|
|
22
|
+
white-space: nowrap
|
|
23
|
+
&::-webkit-details-marker
|
|
24
|
+
display: none
|
|
25
|
+
&::marker
|
|
26
|
+
display: none
|
|
27
|
+
&:hover, &:focus-visible
|
|
28
|
+
color: var(--text-p1)
|
|
29
|
+
background: var(--block-border)
|
|
30
|
+
>svg, >img, >.icon
|
|
31
|
+
flex: 0 0 1.25rem
|
|
32
|
+
width: 1.25rem
|
|
33
|
+
height: 1.25rem
|
|
34
|
+
>.dropdown-arrow
|
|
35
|
+
transition: transform 0.2s ease
|
|
36
|
+
>span
|
|
37
|
+
overflow: hidden
|
|
38
|
+
text-overflow: ellipsis
|
|
39
|
+
&[open]
|
|
40
|
+
z-index: 10
|
|
41
|
+
>.dropdown-trigger
|
|
42
|
+
color: var(--text-p1)
|
|
43
|
+
background: var(--block-border)
|
|
44
|
+
>.dropdown-arrow
|
|
45
|
+
transform: rotate(180deg)
|
|
46
|
+
.dropdown-menu
|
|
47
|
+
display: flex
|
|
48
|
+
flex-direction: column
|
|
49
|
+
gap: 0.125rem
|
|
50
|
+
box-sizing: border-box
|
|
51
|
+
max-width: calc(100vw - 2rem)
|
|
52
|
+
max-height: calc(100vh - 2rem)
|
|
53
|
+
padding: 0.25rem
|
|
54
|
+
overflow-x: hidden
|
|
55
|
+
overflow-y: auto
|
|
56
|
+
font-size: $fs-14
|
|
57
|
+
border: 1px solid var(--block-border)
|
|
58
|
+
border-radius: $border-card
|
|
59
|
+
corner-shape: $corner-shape
|
|
60
|
+
background: rgba(white, 0.3)
|
|
61
|
+
box-shadow: 0 0 2px rgba(black, .04), 0 2px 8px rgba(black, .04), 0 4px 16px rgba(black, .04)
|
|
62
|
+
backdrop-filter: saturate(300%) blur(16px)
|
|
63
|
+
-webkit-backdrop-filter: saturate(300%) blur(16px)
|
|
64
|
+
:root[data-theme="dark"] &
|
|
65
|
+
background: rgba(white, 0.2)
|
|
66
|
+
:root:not([data-theme]) &
|
|
67
|
+
@media (prefers-color-scheme: dark)
|
|
68
|
+
background: rgba(white, 0.2)
|
|
69
|
+
text-align: left
|
|
70
|
+
line-height: 1
|
|
71
|
+
|
|
72
|
+
.dropdown-menu.ui-collection[data-density='compact']
|
|
73
|
+
min-width: 150px
|
|
74
|
+
--ui-item-min-height: calc(1.5rem + 2 * var(--ui-item-padding-y))
|
|
75
|
+
|
|
76
|
+
.dropdown > .dropdown-menu
|
|
77
|
+
position: absolute
|
|
78
|
+
z-index: 10
|
|
79
|
+
top: calc(100% + 0.5rem)
|
|
80
|
+
left: 50%
|
|
81
|
+
transform: translateX(-50%)
|
|
82
|
+
visibility: hidden
|
|
83
|
+
|
|
84
|
+
.dropdown[direction=up] > .dropdown-menu
|
|
85
|
+
top: auto
|
|
86
|
+
bottom: calc(100% + 0.5rem)
|
|
87
|
+
|
|
88
|
+
.dropdown[align=left] > .dropdown-menu
|
|
89
|
+
left: 0
|
|
90
|
+
transform: none
|
|
91
|
+
|
|
92
|
+
.dropdown[align=right] > .dropdown-menu
|
|
93
|
+
right: 0
|
|
94
|
+
left: auto
|
|
95
|
+
transform: none
|
|
96
|
+
|
|
97
|
+
.dropdown-layer
|
|
98
|
+
position: fixed
|
|
99
|
+
z-index: 1000
|
|
100
|
+
top: 0
|
|
101
|
+
right: 0
|
|
102
|
+
bottom: 0
|
|
103
|
+
left: 0
|
|
104
|
+
pointer-events: none
|
|
105
|
+
> .dropdown-bridge
|
|
106
|
+
position: fixed
|
|
107
|
+
z-index: 0
|
|
108
|
+
top: 0
|
|
109
|
+
right: 0
|
|
110
|
+
bottom: 0
|
|
111
|
+
left: 0
|
|
112
|
+
pointer-events: auto
|
|
113
|
+
background: transparent
|
|
114
|
+
> .dropdown-menu
|
|
115
|
+
position: fixed
|
|
116
|
+
z-index: 1000
|
|
117
|
+
top: 0
|
|
118
|
+
left: 0
|
|
119
|
+
transform: none
|
|
120
|
+
pointer-events: auto
|
|
121
|
+
visibility: hidden
|
|
122
|
+
opacity: 0
|
|
123
|
+
contain: paint
|
|
124
|
+
will-change: opacity
|
|
125
|
+
transition: opacity 0.16s ease-out
|
|
126
|
+
&.dropdown-menu-visible
|
|
127
|
+
visibility: visible
|
|
128
|
+
opacity: 1
|
|
129
|
+
|
|
130
|
+
@media (prefers-reduced-motion: reduce)
|
|
131
|
+
.dropdown-layer > .dropdown-menu, .dropdown > .dropdown-trigger > .dropdown-arrow
|
|
132
|
+
transition: none
|
|
@@ -22,8 +22,11 @@ svg.loading
|
|
|
22
22
|
border-radius: $border-card
|
|
23
23
|
position relative
|
|
24
24
|
padding: 2rem
|
|
25
|
-
svg
|
|
25
|
+
svg,
|
|
26
|
+
.lazy-icon
|
|
26
27
|
margin: 4px
|
|
28
|
+
.lazy-icon
|
|
29
|
+
display: inline-block
|
|
27
30
|
&:after
|
|
28
31
|
content: hexo-config('style.loading.loading')
|
|
29
32
|
color: var(--text-p1)
|
|
@@ -35,4 +38,4 @@ svg.loading
|
|
|
35
38
|
|
|
36
39
|
.article-footer
|
|
37
40
|
.loading-wrap
|
|
38
|
-
background: none
|
|
41
|
+
background: none
|
|
@@ -11,9 +11,9 @@ h3,.h3
|
|
|
11
11
|
h4,.h4
|
|
12
12
|
font-size: var(--fsh4)
|
|
13
13
|
h5
|
|
14
|
-
font-size: 'calc(%s + 1px)' % var(--
|
|
14
|
+
font-size: 'calc(%s + 1px)' % var(--fs-content)
|
|
15
15
|
h6
|
|
16
|
-
font-size: 'calc(%s + 0px)' % var(--
|
|
16
|
+
font-size: 'calc(%s + 0px)' % var(--fs-content)
|
|
17
17
|
|
|
18
18
|
// story 文章段落标题(h2):居中 + 两侧 accent 斜杠装饰
|
|
19
19
|
// 专栏列表页专栏标题(.topic-title)与 story 文章 h2 共用
|
|
@@ -34,15 +34,15 @@ story-title()
|
|
|
34
34
|
|
|
35
35
|
// 次级段落字号
|
|
36
36
|
.fs15
|
|
37
|
-
--
|
|
38
|
-
font-size: var(--
|
|
37
|
+
--fs-content: $fs-15
|
|
38
|
+
font-size: var(--fs-content)
|
|
39
39
|
.fs14
|
|
40
|
-
--
|
|
41
|
-
font-size: var(--
|
|
40
|
+
--fs-content: $fs-14
|
|
41
|
+
font-size: var(--fs-content)
|
|
42
42
|
|
|
43
43
|
.footnote
|
|
44
|
-
--
|
|
45
|
-
font-size: var(--
|
|
44
|
+
--fs-content: $fs-13
|
|
45
|
+
font-size: var(--fs-content)
|
|
46
46
|
|
|
47
47
|
.widgets
|
|
48
48
|
.post-title
|