hexo-theme-stellar 1.42.0 → 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 +2 -0
- package/CHANGELOG.md +42 -0
- package/THIRD-PARTY-NOTICES.md +28 -0
- package/_config.yml +20 -10
- 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/bootstrap.ejs +3 -1
- 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/index.ejs +25 -0
- 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/filters/lib/img_lazyload.js +184 -40
- 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/ghrepo.styl +4 -0
- 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/comments/waline.styl +24 -0
- 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/source/css/_custom.styl
CHANGED
|
@@ -8,25 +8,24 @@ $ff-codeblock = convert(hexo-config('style.font-family.codeblock'))
|
|
|
8
8
|
|
|
9
9
|
// font size
|
|
10
10
|
$fs-root = convert(hexo-config('style.font-size.root'))
|
|
11
|
-
$fs-15 =
|
|
12
|
-
$fs-14 =
|
|
13
|
-
$fs-13 =
|
|
14
|
-
$fs-12 =
|
|
11
|
+
$fs-15 = 'calc(%s - 1px)' % var(--fs-content-base)
|
|
12
|
+
$fs-14 = 'calc(%s - 2px)' % var(--fs-content-base)
|
|
13
|
+
$fs-13 = 'calc(%s - 3px)' % var(--fs-content-base)
|
|
14
|
+
$fs-12 = 'calc(%s - 4px)' % var(--fs-content-base)
|
|
15
15
|
|
|
16
|
-
$fs-body = convert(hexo-config('style.font-size.body'))
|
|
17
16
|
$fs-code = convert(hexo-config('style.font-size.code'))
|
|
18
17
|
$fs-codeblock = convert(hexo-config('style.font-size.codeblock'))
|
|
19
18
|
|
|
20
|
-
$fsh1 = 'calc(%s + 9px)' %
|
|
21
|
-
$fsh2 = 'calc(%s + 11px)' %
|
|
22
|
-
$fsh3 = 'calc(%s + 7px)' %
|
|
23
|
-
$fsh4 = 'calc(%s + 4px)' %
|
|
24
|
-
$fsh5 = 'calc(%s + 2px)' %
|
|
19
|
+
$fsh1 = 'calc(%s + 9px)' % var(--fs-content-base)
|
|
20
|
+
$fsh2 = 'calc(%s + 11px)' % var(--fs-content-base)
|
|
21
|
+
$fsh3 = 'calc(%s + 7px)' % var(--fs-content-base)
|
|
22
|
+
$fsh4 = 'calc(%s + 4px)' % var(--fs-content-base)
|
|
23
|
+
$fsh5 = 'calc(%s + 2px)' % var(--fs-content-base)
|
|
25
24
|
|
|
26
|
-
$
|
|
27
|
-
$
|
|
28
|
-
$
|
|
29
|
-
$
|
|
25
|
+
$fs-content-0 = 'calc(%s - 0px)' % var(--fs-content-base)
|
|
26
|
+
$fs-content-1 = 'calc(%s - 1px)' % var(--fs-content-base)
|
|
27
|
+
$fs-content-2 = 'calc(%s - 2px)' % var(--fs-content-base)
|
|
28
|
+
$fs-content-3 = 'calc(%s - 3px)' % var(--fs-content-base)
|
|
30
29
|
|
|
31
30
|
// site main
|
|
32
31
|
$site-background-image = hexo-config('style.site.background-image')
|
|
@@ -56,11 +55,13 @@ $corner-shape = convert(hexo-config('style.corner-shape'))
|
|
|
56
55
|
|
|
57
56
|
// 可以动态变化的属性
|
|
58
57
|
:root
|
|
58
|
+
--fs-root: $fs-root
|
|
59
|
+
--fs-content-base: var(--fs-root)
|
|
60
|
+
--fs-content: var(--fs-content-base)
|
|
59
61
|
--width-main: 720px
|
|
60
|
-
--
|
|
61
|
-
--
|
|
62
|
-
--
|
|
63
|
-
--fsh4: 'calc(%s + 4px)' % var(--fsp)
|
|
62
|
+
--fsh2: 'calc(%s + 11px)' % var(--fs-content)
|
|
63
|
+
--fsh3: 'calc(%s + 7px)' % var(--fs-content)
|
|
64
|
+
--fsh4: 'calc(%s + 4px)' % var(--fs-content)
|
|
64
65
|
|
|
65
66
|
// 侧边栏文字内容宽度
|
|
66
67
|
--side-content-width: 224px
|
|
@@ -73,8 +74,8 @@ $corner-shape = convert(hexo-config('style.corner-shape'))
|
|
|
73
74
|
// 右栏宽度增量(在 --width-sidebar 基础上加宽)
|
|
74
75
|
--rightbar-width-extra: calc(var(--gap-base) * 2)
|
|
75
76
|
|
|
76
|
-
--gap-p: 'calc(%s + 4px)' %
|
|
77
|
-
--gap-p-compact: 'calc(%s * 0.75)' %
|
|
77
|
+
--gap-p: 'calc(%s + 4px)' % var(--fs-content-base) // gap for paragraph
|
|
78
|
+
--gap-p-compact: 'calc(%s * 0.75)' % var(--fs-content-base)
|
|
78
79
|
// desktop 2k or larger
|
|
79
80
|
@media screen and (min-width: $device-2k)
|
|
80
81
|
--width-main: 780px
|
|
@@ -85,6 +86,7 @@ $corner-shape = convert(hexo-config('style.corner-shape'))
|
|
|
85
86
|
@media screen and (max-width: $device-tablet)
|
|
86
87
|
--side-content-width: 188px
|
|
87
88
|
@media screen and (max-width: $device-mobile-max)
|
|
89
|
+
--fs-root: 'calc(%s + 2px)' % $fs-root
|
|
88
90
|
--side-content-width: 224px
|
|
89
91
|
|
|
90
92
|
// shadow
|
|
@@ -18,18 +18,21 @@ img:not([src])
|
|
|
18
18
|
min-height: 4rem
|
|
19
19
|
|
|
20
20
|
// 加载占位动画
|
|
21
|
-
|
|
22
|
-
position: absolute
|
|
21
|
+
.lazy-icon
|
|
23
22
|
width: $loadingImageSize
|
|
24
23
|
height: $loadingImageSize
|
|
25
24
|
max-width: 100%
|
|
26
25
|
max-height: 100%
|
|
26
|
+
// 蒙版上色:SVG 作为 mask(只取形状),颜色由 background-color 提供,
|
|
27
|
+
// 避免 currentColor 在 SVG-as-image 场景(Safari)退化为黑色
|
|
28
|
+
background-color: var(--theme)
|
|
29
|
+
svg-mask-icon(var(--icon-loading, url("https://api.iconify.design/eos-icons:three-dots-loading.svg?color=%231cd0fd")))
|
|
30
|
+
|
|
31
|
+
img.lazy.loading + .lazy-icon
|
|
32
|
+
position: absolute
|
|
27
33
|
top: 50%
|
|
28
34
|
left: 50%
|
|
29
35
|
transform: translateX(-50%) translateY(-50%)
|
|
30
|
-
background-size: contain
|
|
31
|
-
background-repeat: no-repeat
|
|
32
|
-
background-position: center
|
|
33
36
|
|
|
34
37
|
// 加载完成
|
|
35
38
|
img.lazy.loaded + .lazy-icon,
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
@import '../_defines/const'
|
|
2
|
+
@import '../_custom'
|
|
3
|
+
@import '../_defines/func'
|
|
4
|
+
|
|
1
5
|
.cmt-body
|
|
2
6
|
.wl-panel
|
|
3
7
|
margin: 0.5em 0 !important
|
|
@@ -66,3 +70,23 @@
|
|
|
66
70
|
:root:not([data-theme]) &
|
|
67
71
|
@media (prefers-color-scheme: dark)
|
|
68
72
|
ondark()
|
|
73
|
+
|
|
74
|
+
// override
|
|
75
|
+
.md-text .cmt-body.waline
|
|
76
|
+
p
|
|
77
|
+
font-size: var(--waline-font-size)
|
|
78
|
+
line-height: 1.5
|
|
79
|
+
margin: 0
|
|
80
|
+
.wl-reply-to *
|
|
81
|
+
line-height: 1.5
|
|
82
|
+
.wl-header label, .wl-input
|
|
83
|
+
font-size: 0.875em
|
|
84
|
+
.wl-editor
|
|
85
|
+
font-size: var(--waline-font-size)
|
|
86
|
+
font-family: $ff-body
|
|
87
|
+
.wl-content
|
|
88
|
+
.wl-emoji, .vemoji
|
|
89
|
+
height: 2.5em
|
|
90
|
+
img:not(.wl-emoji):not(.vemoji)
|
|
91
|
+
margin-top: 0.5em
|
|
92
|
+
margin-bottom: 0.5em
|
|
@@ -7,17 +7,36 @@ pre.mermaid
|
|
|
7
7
|
justify-content: center;
|
|
8
8
|
font-family: $ff-body
|
|
9
9
|
|
|
10
|
-
.mermaid span,
|
|
10
|
+
.mermaid span,
|
|
11
|
+
.mermaid text
|
|
11
12
|
font-family: $ff-body
|
|
12
13
|
|
|
13
14
|
.mermaid .edgeLabel
|
|
14
15
|
padding: 4px
|
|
15
16
|
background-color: var(--background) !important
|
|
17
|
+
color: var(--text-p1) !important
|
|
18
|
+
|
|
19
|
+
.mermaid .edgeLabel text,
|
|
20
|
+
.mermaid .label text,
|
|
21
|
+
.mermaid .nodeLabel,
|
|
22
|
+
.mermaid .cluster-label text,
|
|
23
|
+
.mermaid .cluster-label span
|
|
24
|
+
fill: var(--text-p1) !important
|
|
25
|
+
color: var(--text-p1) !important
|
|
16
26
|
|
|
17
27
|
.mermaid rect.basic.label-container
|
|
18
28
|
stroke: var(--block-border) !important
|
|
19
29
|
fill: var(--block) !important
|
|
20
30
|
|
|
31
|
+
.mermaid .node rect,
|
|
32
|
+
.mermaid .node circle,
|
|
33
|
+
.mermaid .node ellipse,
|
|
34
|
+
.mermaid .node polygon,
|
|
35
|
+
.mermaid .node path,
|
|
36
|
+
.mermaid .cluster rect
|
|
37
|
+
stroke: var(--block-border) !important
|
|
38
|
+
fill: var(--block) !important
|
|
39
|
+
|
|
21
40
|
_dark_mermaid()
|
|
22
41
|
.mermaid
|
|
23
42
|
fill: #ccc !important
|
|
@@ -42,21 +61,21 @@ _dark_mermaid()
|
|
|
42
61
|
|
|
43
62
|
|
|
44
63
|
.mermaid .label
|
|
45
|
-
color:
|
|
64
|
+
color: var(--text-p1) !important
|
|
46
65
|
|
|
47
66
|
|
|
48
67
|
.mermaid .cluster-label text
|
|
49
|
-
fill:
|
|
68
|
+
fill: var(--text-p1) !important
|
|
50
69
|
|
|
51
70
|
|
|
52
71
|
.mermaid .cluster-label span
|
|
53
|
-
color:
|
|
72
|
+
color: var(--text-p1) !important
|
|
54
73
|
|
|
55
74
|
|
|
56
75
|
.mermaid .label text,
|
|
57
76
|
.mermaid span
|
|
58
|
-
fill:
|
|
59
|
-
color:
|
|
77
|
+
fill: var(--text-p1) !important
|
|
78
|
+
color: var(--text-p1) !important
|
|
60
79
|
|
|
61
80
|
|
|
62
81
|
.mermaid .node rect,
|
|
@@ -64,8 +83,8 @@ _dark_mermaid()
|
|
|
64
83
|
.mermaid .node ellipse,
|
|
65
84
|
.mermaid .node polygon,
|
|
66
85
|
.mermaid .node path
|
|
67
|
-
fill:
|
|
68
|
-
stroke:
|
|
86
|
+
fill: var(--block) !important
|
|
87
|
+
stroke: var(--block-border) !important
|
|
69
88
|
|
|
70
89
|
|
|
71
90
|
.mermaid .arrowheadPath
|
|
@@ -90,16 +109,16 @@ _dark_mermaid()
|
|
|
90
109
|
|
|
91
110
|
|
|
92
111
|
.mermaid .cluster rect
|
|
93
|
-
fill:
|
|
94
|
-
stroke:
|
|
112
|
+
fill: var(--block) !important
|
|
113
|
+
stroke: var(--block-border) !important
|
|
95
114
|
|
|
96
115
|
|
|
97
116
|
.mermaid .cluster text
|
|
98
|
-
fill:
|
|
117
|
+
fill: var(--text-p1) !important
|
|
99
118
|
|
|
100
119
|
|
|
101
120
|
.mermaid .cluster span
|
|
102
|
-
color:
|
|
121
|
+
color: var(--text-p1) !important
|
|
103
122
|
|
|
104
123
|
|
|
105
124
|
.mermaid div.mermaidTooltip
|
package/source/js/icons.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* 服务端 icon() 对非首屏 SVG 图标输出 <svg class="icon" data-icon="ns:key"> 占位符,
|
|
5
5
|
* 本脚本按命名空间拉取构建期生成的 js/icons/{ns}.json,成功后原位替换为完整内联 SVG,
|
|
6
6
|
* 最终 DOM 与全量内联一致,现有 CSS 钩子(搜索三态、菜单渐变、chat 着色等)不受影响。
|
|
7
|
-
* 首屏关键图标(搜索、菜单、leftbar/rightbar、
|
|
7
|
+
* 首屏关键图标(搜索、菜单、leftbar/rightbar、arrow-left)由模板内联,不经过本脚本。
|
|
8
8
|
*/
|
|
9
9
|
(function () {
|
|
10
10
|
'use strict';
|
package/source/js/main.js
CHANGED
|
@@ -177,7 +177,7 @@ function rebuildToc(scope) {
|
|
|
177
177
|
return;
|
|
178
178
|
}
|
|
179
179
|
const ol = document.createElement('ol');
|
|
180
|
-
ol.className = 'toc';
|
|
180
|
+
ol.className = 'toc ui-collection-adapter';
|
|
181
181
|
const stack = [];
|
|
182
182
|
headings.forEach(function (h) {
|
|
183
183
|
const id = h.id;
|
|
@@ -372,6 +372,56 @@ const init = {
|
|
|
372
372
|
}
|
|
373
373
|
});
|
|
374
374
|
},
|
|
375
|
+
wikiCover: () => {
|
|
376
|
+
document.querySelectorAll('.wiki-cover-terminal').forEach(function (terminal) {
|
|
377
|
+
const code = terminal.querySelector('pre code');
|
|
378
|
+
const tabs = terminal.querySelectorAll('[role="tab"]');
|
|
379
|
+
function renderCodes(value) {
|
|
380
|
+
const lines = value.split(/\r?\n/).filter(function (line) {
|
|
381
|
+
return line.trim().length > 0;
|
|
382
|
+
});
|
|
383
|
+
terminal.dataset.codes = lines.join('\n');
|
|
384
|
+
code.innerHTML = '';
|
|
385
|
+
lines.forEach(function (line) {
|
|
386
|
+
const row = document.createElement('span');
|
|
387
|
+
row.textContent = line;
|
|
388
|
+
code.appendChild(row);
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
if (tabs.length > 0) {
|
|
392
|
+
renderCodes(tabs[0].getAttribute('data-codes') || '');
|
|
393
|
+
}
|
|
394
|
+
tabs.forEach(function (tab) {
|
|
395
|
+
tab.addEventListener('click', function () {
|
|
396
|
+
tabs.forEach(function (item) {
|
|
397
|
+
const active = item === tab;
|
|
398
|
+
item.classList.toggle('active', active);
|
|
399
|
+
item.setAttribute('aria-selected', active ? 'true' : 'false');
|
|
400
|
+
});
|
|
401
|
+
renderCodes(tab.getAttribute('data-codes') || '');
|
|
402
|
+
});
|
|
403
|
+
});
|
|
404
|
+
const copy = terminal.querySelector('.wiki-cover-copy');
|
|
405
|
+
if (copy) {
|
|
406
|
+
copy.addEventListener('click', function () {
|
|
407
|
+
const value = terminal.dataset.codes || '';
|
|
408
|
+
if (!value || !navigator.clipboard) return;
|
|
409
|
+
navigator.clipboard.writeText(value).then(function () {
|
|
410
|
+
hud.toast(copy.getAttribute('data-copy-message') || 'Copied', 2500);
|
|
411
|
+
}).catch(function () {});
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
const galaxyCanvases = document.querySelectorAll('.wiki-cover-background.galaxy canvas');
|
|
417
|
+
const reduceMotion = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
418
|
+
if (reduceMotion || galaxyCanvases.length === 0) return;
|
|
419
|
+
utils.js('/js/plugins/galaxy.js').then(function () {
|
|
420
|
+
if (stellar.galaxy && typeof stellar.galaxy.mountAll === 'function') {
|
|
421
|
+
stellar.galaxy.mountAll(galaxyCanvases);
|
|
422
|
+
}
|
|
423
|
+
}).catch(function () {});
|
|
424
|
+
},
|
|
375
425
|
leftbarScroll: () => {
|
|
376
426
|
const container = document.querySelector('.l_left .widgets');
|
|
377
427
|
if (container == null) {
|
|
@@ -380,7 +430,7 @@ const init = {
|
|
|
380
430
|
const PREFIX = 'Stellar.leftbarScroll.';
|
|
381
431
|
const encode = (s) => encodeURIComponent(String(s || ''));
|
|
382
432
|
function scope() {
|
|
383
|
-
const wikiEl = document.querySelector('.doc-tree[data-wiki]');
|
|
433
|
+
const wikiEl = document.querySelector('.doc-tree-widget[data-wiki]');
|
|
384
434
|
if (wikiEl != null) {
|
|
385
435
|
return 'wiki:' + encode(wikiEl.getAttribute('data-wiki'));
|
|
386
436
|
}
|
|
@@ -409,7 +459,7 @@ const init = {
|
|
|
409
459
|
return;
|
|
410
460
|
}
|
|
411
461
|
container.scrollTop = parseInt(value, 10) || 0;
|
|
412
|
-
const link = container.querySelector('
|
|
462
|
+
const link = container.querySelector('.ui-collection__item.is-active');
|
|
413
463
|
if (link == null) {
|
|
414
464
|
return;
|
|
415
465
|
}
|
|
@@ -426,22 +476,27 @@ const init = {
|
|
|
426
476
|
} catch (e) {}
|
|
427
477
|
},
|
|
428
478
|
navbarPin: () => {
|
|
429
|
-
// 列表页 navbar top
|
|
430
|
-
//
|
|
479
|
+
// 列表页 navbar top 背景条状态切换:未滚动/未吸顶为卡片样式(var(--card) + 文章卡片同款阴影),
|
|
480
|
+
// 页面滚动达到阈值且吸顶后恢复玻璃效果。在吸顶边界切换 .pinned 类,视觉由 CSS 控制。
|
|
431
481
|
// 吸顶判定直接测 navbar 的实际视口位置,而非用 scrollY 推算:
|
|
432
482
|
// 移动端浏览器顶栏伸缩会改变 scrollY(展开顶栏时 scrollY 减小),
|
|
433
483
|
// 即使 navbar 仍吸顶也可能跌破阈值,导致玻璃效果误消失。
|
|
484
|
+
// 无轮播区页面(如 wiki)的 navbar 在页面顶部即已吸顶,需额外要求页面实际滚动达到阈值,
|
|
485
|
+
// 否则默认保持卡片样式;回到顶部(滚动小于阈值)恢复卡片。
|
|
434
486
|
const navbars = document.querySelectorAll('.navbar.top');
|
|
435
487
|
if (navbars.length === 0) {
|
|
436
488
|
return;
|
|
437
489
|
}
|
|
438
490
|
// 视口顶部允许的偏差(px),吸收亚像素/取整误差
|
|
439
491
|
const TOLERANCE = 2;
|
|
492
|
+
// 页面滚动阈值(px):未滚动时保持卡片样式,滚动达到该值后才切换玻璃效果
|
|
493
|
+
const SCROLL_THRESHOLD = 2;
|
|
440
494
|
let states = [];
|
|
441
495
|
function update() {
|
|
496
|
+
const scrolled = window.scrollY >= SCROLL_THRESHOLD;
|
|
442
497
|
states.forEach((state) => {
|
|
443
498
|
const top = state.navbar.getBoundingClientRect().top;
|
|
444
|
-
state.bar.classList.toggle('pinned', top <= state.stickyTop + TOLERANCE);
|
|
499
|
+
state.bar.classList.toggle('pinned', scrolled && top <= state.stickyTop + TOLERANCE);
|
|
445
500
|
});
|
|
446
501
|
}
|
|
447
502
|
function measure() {
|
|
@@ -621,6 +676,7 @@ stellar.initPage = function () {
|
|
|
621
676
|
init.toc();
|
|
622
677
|
init.sidebar();
|
|
623
678
|
init.wikiStart();
|
|
679
|
+
init.wikiCover();
|
|
624
680
|
init.leftbarScroll();
|
|
625
681
|
init.navbarPin();
|
|
626
682
|
init.relativeDate(document.querySelectorAll('#post-meta time'));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// 文字自适应颜色 DOM 插件
|
|
2
|
-
// 扫描 [data-text-adaptive] 元素,解析背景来源(--cover-url → --bg-url →
|
|
2
|
+
// 扫描 [data-text-adaptive] 元素,解析背景来源(--adaptive-background → --cover-url → --bg-url →
|
|
3
3
|
// background-image → background-color),调用 stellar.color 计算文字颜色,
|
|
4
|
-
// 写入内联 --text-banner 与 --text-banner-theme
|
|
4
|
+
// 写入内联 --text-banner 与 --text-banner-theme;Wiki 封面另写入主题色蒙版变量。
|
|
5
5
|
// 属性值:
|
|
6
6
|
// theme(默认) 背景图平均色 lighten/darken(两种变量同色)
|
|
7
7
|
// contrast 黑白对比(两种变量同色)
|
|
@@ -19,6 +19,10 @@ function parseCssUrl(value) {
|
|
|
19
19
|
|
|
20
20
|
function resolveBackground(el) {
|
|
21
21
|
var style = window.getComputedStyle(el);
|
|
22
|
+
var adaptiveBackground = stellar.color.parse(style.getPropertyValue('--adaptive-background'));
|
|
23
|
+
if (adaptiveBackground) {
|
|
24
|
+
return { type: 'color', rgb: adaptiveBackground };
|
|
25
|
+
}
|
|
22
26
|
var cover = parseCssUrl(style.getPropertyValue('--cover-url'));
|
|
23
27
|
if (cover) {
|
|
24
28
|
return { type: 'image', url: cover };
|
|
@@ -85,6 +89,39 @@ function setSplitTextColors(el, rgb) {
|
|
|
85
89
|
}
|
|
86
90
|
}
|
|
87
91
|
|
|
92
|
+
// Wiki 卡片的 Today 风格内容层使用封面平均色:保留色相,增强弱饱和度后压低明度,
|
|
93
|
+
// 让满不透明蒙版下的白色文字始终可读。变量写到 .wiki-card:蒙版用深色版本,
|
|
94
|
+
// hover 边框使用同源但提高 20 个明度点的版本。
|
|
95
|
+
function setWikiOverlayColor(el, rgb) {
|
|
96
|
+
var node = el.parentElement;
|
|
97
|
+
while (node && node.nodeType === 1) {
|
|
98
|
+
if ((' ' + node.className + ' ').indexOf(' wiki-card ') !== -1) {
|
|
99
|
+
var themed = stellar.color.enhanceSaturation(rgb, { minSaturation: 0.45, boostBelow: 0.35 });
|
|
100
|
+
var overlay = stellar.color.darken(themed, 0.26);
|
|
101
|
+
var border = stellar.color.lighten(themed, 0.46);
|
|
102
|
+
if (overlay) {
|
|
103
|
+
node.style.setProperty('--wiki-overlay-color', overlay);
|
|
104
|
+
}
|
|
105
|
+
if (border) {
|
|
106
|
+
node.style.setProperty('--wiki-border-color', border);
|
|
107
|
+
}
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
node = node.parentElement;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Wiki 卡片主题色确定后(包括提取失败时的 CSS 回退)通知索引页。
|
|
115
|
+
// 覆盖层会同时等待原图 load,避免先用默认主题色绘制、再切换为平均色。
|
|
116
|
+
function notifyWikiOverlayReady(el) {
|
|
117
|
+
if (!el || !el.dispatchEvent || !document.createEvent) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
var event = document.createEvent('Event');
|
|
121
|
+
event.initEvent('wiki-overlay-ready', true, false);
|
|
122
|
+
el.dispatchEvent(event);
|
|
123
|
+
}
|
|
124
|
+
|
|
88
125
|
function applyToElement(el) {
|
|
89
126
|
// 用户显式覆盖优先:首次处理时元素已有内联 --text-banner 或内联 color 则跳过
|
|
90
127
|
// (插件自身写入的变量不视为用户覆盖,主题切换重算时需重新应用)
|
|
@@ -103,6 +140,10 @@ function applyToElement(el) {
|
|
|
103
140
|
} else {
|
|
104
141
|
setTextColor(el, styleName, rgb);
|
|
105
142
|
}
|
|
143
|
+
if (styleName === 'split' && el.parentElement && (' ' + el.parentElement.className + ' ').indexOf(' wiki-card-cover ') !== -1) {
|
|
144
|
+
setWikiOverlayColor(el, rgb);
|
|
145
|
+
notifyWikiOverlayReady(el);
|
|
146
|
+
}
|
|
106
147
|
appliedElements.add(el);
|
|
107
148
|
};
|
|
108
149
|
if (bg.type === 'color') {
|
|
@@ -112,6 +153,9 @@ function applyToElement(el) {
|
|
|
112
153
|
stellar.color.getAverageColor(bg.url, { background: backdrop }).then(function (rgb) {
|
|
113
154
|
if (rgb) {
|
|
114
155
|
apply(rgb);
|
|
156
|
+
} else if (styleName === 'split' && el.parentElement && (' ' + el.parentElement.className + ' ').indexOf(' wiki-card-cover ') !== -1) {
|
|
157
|
+
// 平均色提取失败时不写变量,保留 CSS 回退色;但仍须解除 Wiki 覆盖层等待。
|
|
158
|
+
notifyWikiOverlayReady(el);
|
|
115
159
|
}
|
|
116
160
|
});
|
|
117
161
|
}
|