hexo-theme-stellar 1.40.0 → 1.41.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/CHANGELOG.md +41 -0
- package/_config.yml +33 -10
- package/_data/icons.yml +250 -37
- package/languages/en.yml +6 -0
- package/languages/zh-CN.yml +6 -0
- package/languages/zh-TW.yml +6 -0
- package/layout/_partial/comments/artalk/script.ejs +25 -8
- package/layout/_partial/comments/beaudar/script.ejs +1 -0
- package/layout/_partial/comments/twikoo/script.ejs +1 -0
- package/layout/_partial/comments/utterances/script.ejs +1 -0
- package/layout/_partial/comments/waline/script.ejs +1 -0
- package/layout/_partial/head.ejs +43 -7
- package/layout/_partial/main/article/article_tags.ejs +16 -0
- package/layout/_partial/main/navbar/article_banner.ejs +11 -1
- package/layout/_partial/main/notebook/note_card.ejs +1 -1
- package/layout/_partial/main/notebook/paginator.ejs +2 -2
- package/layout/_partial/main/pin_slider.ejs +2 -2
- package/layout/_partial/main/post_list/paginator.ejs +2 -2
- package/layout/_partial/menubtn.ejs +2 -2
- package/layout/_partial/scripts/defines.ejs +26 -2
- package/layout/_partial/scripts.ejs +30 -7
- package/layout/_partial/sidebar/logo.ejs +1 -1
- package/layout/_partial/sidebar/menu.ejs +1 -1
- package/layout/_partial/sidebar/search.ejs +1 -1
- package/layout/_partial/widgets/author.ejs +1 -1
- package/layout/_partial/widgets/components/link.ejs +2 -2
- package/layout/_partial/widgets/ghuser.ejs +1 -1
- package/layout/_partial/widgets/related.ejs +1 -1
- package/layout/_partial/widgets/toc.ejs +1 -1
- package/layout/_partial/widgets/tree.ejs +1 -1
- package/layout/_plugins/fancybox.ejs +4 -2
- package/layout/_plugins/mermaid.ejs +2 -1
- package/layout/_plugins/search/local_search.ejs +4 -3
- package/layout/_plugins/swiper.ejs +1 -0
- package/layout/categories.ejs +1 -1
- package/layout/page.ejs +3 -0
- package/layout/tags.ejs +1 -0
- package/package.json +1 -1
- package/scripts/events/lib/doc_tree.js +12 -208
- package/scripts/events/lib/notebooks.js +8 -148
- package/scripts/events/lib/utils.js +10 -1
- package/scripts/filters/index.js +1 -0
- package/scripts/filters/lib/img_lazyload.js +4 -0
- package/scripts/filters/lib/img_onerror.js +4 -0
- package/scripts/filters/lib/md_table.js +46 -0
- package/scripts/generators/search.js +12 -18
- package/scripts/generators/stellar-icons.js +47 -0
- package/scripts/helpers/ai_label.js +29 -0
- package/scripts/helpers/icon.js +2 -2
- package/scripts/helpers/json_ld.js +10 -13
- package/scripts/helpers/related_posts.js +0 -7
- package/scripts/helpers/seo.js +9 -0
- package/scripts/lib/ai_label.js +55 -0
- package/scripts/lib/doc_tree.js +267 -0
- package/scripts/lib/notebooks.js +181 -0
- package/scripts/lib/search_index.js +82 -0
- package/scripts/lib/seo.js +79 -0
- package/scripts/tags/lib/about.js +2 -2
- package/scripts/tags/lib/albums.js +1 -1
- package/scripts/tags/lib/banner.js +1 -1
- package/scripts/tags/lib/chat.js +49 -49
- package/scripts/tags/lib/copy.js +1 -1
- package/scripts/tags/lib/friends.js +1 -1
- package/scripts/tags/lib/gallery.js +1 -1
- package/scripts/tags/lib/hashtag.js +1 -1
- package/scripts/tags/lib/image.js +3 -3
- package/scripts/tags/lib/posters.js +1 -1
- package/scripts/tags/lib/sites.js +2 -2
- package/source/css/_common/base.styl +5 -9
- package/source/css/_common/device.styl +3 -3
- package/source/css/_components/md-table.styl +23 -0
- package/source/css/_components/pages/archives.styl +2 -22
- package/source/css/_components/pages/article-story.styl +4 -4
- package/source/css/_components/partial/article-tags.styl +10 -0
- package/source/css/_components/partial/bread-nav.styl +14 -0
- package/source/css/_components/partial/navbar.styl +10 -2
- package/source/css/_components/sidebar/search.styl +24 -4
- package/source/css/_components/tag-plugins/table.styl +16 -11
- package/source/css/_components/widgets/components.styl +6 -0
- package/source/css/_components/widgets/list.styl +6 -0
- package/source/css/_components/widgets/toc.styl +1 -1
- package/source/css/_custom.styl +1 -12
- package/source/css/_defines/func.styl +28 -3
- package/source/css/_plugins/index.styl +0 -18
- package/source/css/{_plugins/comments → comments}/artalk.styl +4 -0
- package/source/css/{_plugins/comments → comments}/twikoo.styl +4 -0
- package/source/css/{_plugins → plugins}/mermaid.styl +3 -0
- package/source/css/{_plugins → plugins}/swiper.styl +5 -1
- package/source/js/icons.js +60 -0
- package/source/js/main.js +114 -0
- package/source/js/search/highlight.js +82 -0
- package/source/js/search/local-search.js +294 -103
- package/source/js/services/timeline.js +1 -1
- package/source/js/services/weibo.js +3 -3
- package/source/js/services.js +179 -0
- package/source/js/tagtree.js +29 -0
- package/source/js/theme.js +61 -0
- package/{layout/_partial/scripts/utils.ejs → source/js/utils.js} +13 -10
- package/layout/_partial/scripts/services.ejs +0 -178
- package/layout/_partial/scripts/sidebar.ejs +0 -25
- package/layout/_partial/scripts/tagtree.ejs +0 -29
- package/layout/_partial/scripts/theme.ejs +0 -67
- /package/source/css/{_plugins/comments → comments}/beaudar.styl +0 -0
- /package/source/css/{_plugins/comments → comments}/utterances.styl +0 -0
- /package/source/css/{_plugins/comments → comments}/waline.styl +0 -0
- /package/source/css/{_plugins → plugins}/fancybox.styl +0 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
(() => {
|
|
2
|
+
const tagtreeConf = window.__STELLAR_TAGTREE__ || {};
|
|
3
|
+
|
|
4
|
+
const tagSwitchers = document.querySelectorAll('.tag-subtree.parent-tag > a > .tag-switcher-wrapper')
|
|
5
|
+
for (const tagSwitcher of tagSwitchers) {
|
|
6
|
+
tagSwitcher.addEventListener('click', (e) => {
|
|
7
|
+
const parent = e.target.closest('.tag-subtree.parent-tag')
|
|
8
|
+
parent.classList.toggle('expanded')
|
|
9
|
+
e.preventDefault()
|
|
10
|
+
})
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Get active tag from query string, then activate it.
|
|
14
|
+
const urlParams = new URLSearchParams(window.location.search)
|
|
15
|
+
const activeTag = urlParams.get('tag')
|
|
16
|
+
if (activeTag) {
|
|
17
|
+
let tag = document.querySelector(`.tag-subtree[data-tag="${activeTag}"]`)
|
|
18
|
+
if (tag) {
|
|
19
|
+
tag.querySelector('a').classList.add('active')
|
|
20
|
+
if (!tagtreeConf.expand_active) {
|
|
21
|
+
tag = tag.parentElement.closest('.tag-subtree.parent-tag')
|
|
22
|
+
}
|
|
23
|
+
while (tag) {
|
|
24
|
+
tag.classList.add('expanded')
|
|
25
|
+
tag = tag.parentElement.closest('.tag-subtree.parent-tag')
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
})()
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
const applyTheme = (theme) => {
|
|
2
|
+
if (theme === 'auto') {
|
|
3
|
+
document.documentElement.removeAttribute('data-theme')
|
|
4
|
+
} else {
|
|
5
|
+
document.documentElement.setAttribute('data-theme', theme)
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// applyThemeToGiscus(theme)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// FIXME: 这会导致无法使用 preferred_color_scheme 以外的主题
|
|
12
|
+
const applyThemeToGiscus = (theme) => {
|
|
13
|
+
// theme = theme === 'auto' ? 'preferred_color_scheme' : theme
|
|
14
|
+
const cmt = document.getElementById('giscus')
|
|
15
|
+
if (cmt) {
|
|
16
|
+
// This works before giscus load.
|
|
17
|
+
cmt.setAttribute('data-theme', theme)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const iframe = document.querySelector('#comments > section.giscus > iframe')
|
|
21
|
+
if (iframe) {
|
|
22
|
+
// This works after giscus loaded.
|
|
23
|
+
const src = iframe.src
|
|
24
|
+
const newSrc = src.replace(/theme=[\w]+/, `theme=${theme}`)
|
|
25
|
+
iframe.src = newSrc
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const switchTheme = () => {
|
|
30
|
+
// light -> dark -> auto -> light -> ...
|
|
31
|
+
const currentTheme = document.documentElement.getAttribute('data-theme')
|
|
32
|
+
let newTheme;
|
|
33
|
+
switch (currentTheme) {
|
|
34
|
+
case 'light':
|
|
35
|
+
newTheme = 'dark'
|
|
36
|
+
break
|
|
37
|
+
case 'dark':
|
|
38
|
+
newTheme = 'auto'
|
|
39
|
+
break
|
|
40
|
+
default:
|
|
41
|
+
newTheme = 'light'
|
|
42
|
+
}
|
|
43
|
+
applyTheme(newTheme)
|
|
44
|
+
window.localStorage.setItem('Stellar.theme', newTheme)
|
|
45
|
+
utils.dark.mode = newTheme === 'auto' ? (window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light") : newTheme;
|
|
46
|
+
utils.dark.method.toggle.start();
|
|
47
|
+
|
|
48
|
+
const messages = window.__STELLAR_I18N__ || {};
|
|
49
|
+
hud?.toast?.(messages[newTheme])
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
(() => {
|
|
53
|
+
// Apply user's preferred theme, if any.
|
|
54
|
+
const theme = window.localStorage.getItem('Stellar.theme')
|
|
55
|
+
if (theme !== null) {
|
|
56
|
+
applyTheme(theme)
|
|
57
|
+
} else {
|
|
58
|
+
utils.dark.mode = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
59
|
+
}
|
|
60
|
+
utils.dark.method.toggle.start();
|
|
61
|
+
})()
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
<script type="text/javascript">
|
|
2
1
|
|
|
3
2
|
function RunItem() {
|
|
4
3
|
this.list = []; // 存放回调函数
|
|
@@ -63,7 +62,7 @@
|
|
|
63
62
|
var sheets = doc.styleSheets;
|
|
64
63
|
if (attributes) {
|
|
65
64
|
for (var attributeName in attributes) {
|
|
66
|
-
if (
|
|
65
|
+
if (Object.prototype.hasOwnProperty.call(attributes, attributeName)) {
|
|
67
66
|
ss.setAttribute(attributeName, attributes[attributeName]);
|
|
68
67
|
}
|
|
69
68
|
}
|
|
@@ -296,7 +295,7 @@
|
|
|
296
295
|
onLoading: (el) => {
|
|
297
296
|
if (el) {
|
|
298
297
|
if (el.querySelector('.loading-wrap') === null) {
|
|
299
|
-
el.insertAdjacentHTML('beforeend',
|
|
298
|
+
el.insertAdjacentHTML('beforeend', `<div class="loading-wrap">${ctx.icons['default:loading-spinner']}</div>`);
|
|
300
299
|
}
|
|
301
300
|
}
|
|
302
301
|
},
|
|
@@ -312,7 +311,7 @@
|
|
|
312
311
|
if (wrap) {
|
|
313
312
|
var svg = wrap.querySelector('svg');
|
|
314
313
|
if (svg) svg.remove();
|
|
315
|
-
wrap.insertAdjacentHTML('beforeend',
|
|
314
|
+
wrap.insertAdjacentHTML('beforeend', ctx.icons['default:warning']);
|
|
316
315
|
wrap.classList.add('error');
|
|
317
316
|
}
|
|
318
317
|
}
|
|
@@ -533,11 +532,13 @@
|
|
|
533
532
|
if (timedOut) return;
|
|
534
533
|
// 标记元素实例为已加载
|
|
535
534
|
if (el) utils._loadedElements.add(el);
|
|
536
|
-
//
|
|
535
|
+
// 写入缓存:回调会立即消费 data 的 body,必须先同步 clone 再延迟读取
|
|
537
536
|
if (cacheable && data.ok) {
|
|
537
|
+
const cacheClone = data.clone();
|
|
538
|
+
const contentType = data.headers.get('Content-Type') || 'application/json';
|
|
538
539
|
utils._defer(() => {
|
|
539
|
-
|
|
540
|
-
utils.cache.set(url, text,
|
|
540
|
+
cacheClone.text().then(text => {
|
|
541
|
+
utils.cache.set(url, text, contentType, ttl);
|
|
541
542
|
}).catch(() => {});
|
|
542
543
|
});
|
|
543
544
|
}
|
|
@@ -609,9 +610,12 @@
|
|
|
609
610
|
clearTimeout(timer);
|
|
610
611
|
if (timedOut) return;
|
|
611
612
|
if (cacheable) {
|
|
613
|
+
// 调用方会消费 resp 的 body,必须先同步 clone 再延迟读取
|
|
614
|
+
const cacheClone = resp.clone();
|
|
615
|
+
const contentType = resp.headers.get('Content-Type') || 'application/json';
|
|
612
616
|
utils._defer(() => {
|
|
613
|
-
|
|
614
|
-
utils.cache.set(url, text,
|
|
617
|
+
cacheClone.text().then(text => {
|
|
618
|
+
utils.cache.set(url, text, contentType, ttl);
|
|
615
619
|
}).catch(() => {});
|
|
616
620
|
});
|
|
617
621
|
}
|
|
@@ -722,4 +726,3 @@
|
|
|
722
726
|
utils.dark = Object.assign(utils.dark, {
|
|
723
727
|
push: utils.dark.method.toggle.push,
|
|
724
728
|
});
|
|
725
|
-
</script>
|
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
<script defer>
|
|
2
|
-
const initServices = () => {
|
|
3
|
-
// 用于存储需要清理的资源
|
|
4
|
-
let timers = [];
|
|
5
|
-
|
|
6
|
-
ctx.services = Object.assign({}, JSON.parse(`<%- JSON.stringify(theme.data_services) %>`));
|
|
7
|
-
for (let id of Object.keys(ctx.services)) {
|
|
8
|
-
const js = ctx.services[id].js;
|
|
9
|
-
if (id == 'siteinfo') {
|
|
10
|
-
const cardlinks = document.querySelectorAll('a.link-card[cardlink]');
|
|
11
|
-
if (cardlinks?.length > 0) {
|
|
12
|
-
utils.js(js, { defer: true }).then(function () {
|
|
13
|
-
setCardLink(cardlinks);
|
|
14
|
-
});
|
|
15
|
-
}
|
|
16
|
-
} else if (id == 'ghinfo') {
|
|
17
|
-
const els = document.querySelectorAll('.ds-ghinfo');
|
|
18
|
-
if (els.length > 0) {
|
|
19
|
-
utils.js(js, { defer: true });
|
|
20
|
-
}
|
|
21
|
-
} else if (id == 'voice') {
|
|
22
|
-
const voiceAudios = document.querySelectorAll('.voice>audio');
|
|
23
|
-
if (voiceAudios?.length > 0) {
|
|
24
|
-
utils.js(js, { defer: true }).then(function () {
|
|
25
|
-
createVoiceDom(voiceAudios);
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
} else if (id == 'video') {
|
|
29
|
-
const videos = document.querySelectorAll('.video>video');
|
|
30
|
-
if (videos?.length > 0) {
|
|
31
|
-
utils.js(js, { defer: true }).then(function () {
|
|
32
|
-
videoEvents(videos);
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
} else if (id == 'download-file') {
|
|
36
|
-
const files = document.querySelectorAll('.chat-file');
|
|
37
|
-
if (files?.length > 0) {
|
|
38
|
-
utils.js(js, { defer: true }).then(function () {
|
|
39
|
-
downloadFileEvent(files);
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
} else {
|
|
43
|
-
const els = document.getElementsByClassName(`ds-${id}`);
|
|
44
|
-
if (els?.length > 0) {
|
|
45
|
-
if (id == 'timeline' || id == 'memos' || id == 'marked' || id == 'mdrender') {
|
|
46
|
-
utils.js(deps.marked).then(function () {
|
|
47
|
-
utils.js(js, { defer: true });
|
|
48
|
-
});
|
|
49
|
-
} else {
|
|
50
|
-
utils.js(js, { defer: true });
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// search
|
|
57
|
-
if (ctx.search && typeof searchFunc === 'function') {
|
|
58
|
-
const inputArea = document.querySelector("input#search-input");
|
|
59
|
-
if (inputArea && !inputArea._searchInitialized) {
|
|
60
|
-
const path = ctx.search.path.startsWith('/') ? ctx.root + ctx.search.path.substring(1) : ctx.root + ctx.search.path;
|
|
61
|
-
const filter = inputArea.getAttribute('data-filter') || '';
|
|
62
|
-
searchFunc(path, filter, 'search-wrapper', 'search-input', 'search-result');
|
|
63
|
-
// 标记为已初始化,防止重复绑定
|
|
64
|
-
inputArea._searchInitialized = true;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// chat iphone time
|
|
69
|
-
let phoneTimes = document.querySelectorAll('.chat .status-bar .time');
|
|
70
|
-
let firstAdjustInterval = null;
|
|
71
|
-
let mainInterval = null;
|
|
72
|
-
|
|
73
|
-
if (phoneTimes.length > 0) {
|
|
74
|
-
NowTime();
|
|
75
|
-
const date = new Date();
|
|
76
|
-
const sec = date.getSeconds();
|
|
77
|
-
firstAdjustInterval = setInterval(firstAdjustTime, 1000 * (60 - sec));
|
|
78
|
-
timers.push(firstAdjustInterval);
|
|
79
|
-
|
|
80
|
-
function firstAdjustTime() {
|
|
81
|
-
NowTime();
|
|
82
|
-
if (firstAdjustInterval) {
|
|
83
|
-
clearInterval(firstAdjustInterval);
|
|
84
|
-
firstAdjustInterval = null;
|
|
85
|
-
}
|
|
86
|
-
mainInterval = setInterval(NowTime, 1000 * 60);
|
|
87
|
-
timers.push(mainInterval);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function NowTime() {
|
|
91
|
-
for (let i = 0; i < phoneTimes.length; ++i) {
|
|
92
|
-
const timeSpan = phoneTimes[i];
|
|
93
|
-
const date = new Date();
|
|
94
|
-
const hour = date.getHours();
|
|
95
|
-
const min = date.getMinutes();
|
|
96
|
-
timeSpan.innerHTML = check(hour) + ":" + check(min);
|
|
97
|
-
}
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
function check(val) {
|
|
101
|
-
if (val < 10) {
|
|
102
|
-
return ("0" + val);
|
|
103
|
-
}
|
|
104
|
-
return (val);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// chat quote - 存储事件监听器以便清理
|
|
109
|
-
const quoteClickHandlers = new Map();
|
|
110
|
-
const chat_quote_obverser = new IntersectionObserver((entries, observer) => {
|
|
111
|
-
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) => {
|
|
112
|
-
observer.unobserve(entry.target);
|
|
113
|
-
setTimeout(() => {
|
|
114
|
-
entry.target.classList.add('quote-blink');
|
|
115
|
-
setTimeout(() => {
|
|
116
|
-
entry.target.classList.remove('quote-blink');
|
|
117
|
-
}, 1000);
|
|
118
|
-
}, Math.max(100, 16) * (index + 1));
|
|
119
|
-
});
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
var chatQuotes = document.querySelectorAll(".chat .talk .quote");
|
|
123
|
-
chatQuotes.forEach((quote) => {
|
|
124
|
-
const handler = function () {
|
|
125
|
-
var chatCellDom = document.getElementById("quote-" + quote.getAttribute("quotedCellTag"));
|
|
126
|
-
if (chatCellDom) {
|
|
127
|
-
var chatDiv = chatCellDom.parentElement;
|
|
128
|
-
var mid = chatDiv.clientHeight / 2;
|
|
129
|
-
var offsetTop = chatCellDom.offsetTop;
|
|
130
|
-
if (offsetTop > mid - chatCellDom.clientHeight / 2) {
|
|
131
|
-
chatDiv.scrollTo({
|
|
132
|
-
top: chatCellDom.offsetTop - mid + chatCellDom.clientHeight / 2,
|
|
133
|
-
behavior: "smooth"
|
|
134
|
-
});
|
|
135
|
-
} else {
|
|
136
|
-
chatDiv.scrollTo({
|
|
137
|
-
top: 0,
|
|
138
|
-
behavior: "smooth"
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
chat_quote_obverser.observe(chatCellDom);
|
|
142
|
-
}
|
|
143
|
-
};
|
|
144
|
-
quote.addEventListener('click', handler);
|
|
145
|
-
quoteClickHandlers.set(quote, handler); // 保存处理器引用
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
// 返回清理函数,用于清理定时器和观察器
|
|
149
|
-
return () => {
|
|
150
|
-
// 清理所有定时器(包括可能未完成的 firstAdjustInterval)
|
|
151
|
-
timers.forEach(timer => {
|
|
152
|
-
if (timer) clearInterval(timer);
|
|
153
|
-
});
|
|
154
|
-
timers = [];
|
|
155
|
-
if (firstAdjustInterval) {
|
|
156
|
-
clearInterval(firstAdjustInterval);
|
|
157
|
-
firstAdjustInterval = null;
|
|
158
|
-
}
|
|
159
|
-
if (mainInterval) {
|
|
160
|
-
clearInterval(mainInterval);
|
|
161
|
-
mainInterval = null;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// 断开观察器
|
|
165
|
-
if (chat_quote_obverser) {
|
|
166
|
-
chat_quote_obverser.disconnect();
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
// 移除所有 click 事件监听器
|
|
170
|
-
quoteClickHandlers.forEach((handler, quote) => {
|
|
171
|
-
quote.removeEventListener('click', handler);
|
|
172
|
-
});
|
|
173
|
-
quoteClickHandlers.clear();
|
|
174
|
-
};
|
|
175
|
-
};
|
|
176
|
-
|
|
177
|
-
utils.initPlugin(initServices, 'services');
|
|
178
|
-
</script>
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
const sidebar = {
|
|
3
|
-
leftbar: () => {
|
|
4
|
-
if (l_body) {
|
|
5
|
-
l_body.toggleAttribute('leftbar');
|
|
6
|
-
l_body.removeAttribute('rightbar');
|
|
7
|
-
}
|
|
8
|
-
},
|
|
9
|
-
rightbar: () => {
|
|
10
|
-
if (l_body) {
|
|
11
|
-
l_body.toggleAttribute('rightbar');
|
|
12
|
-
l_body.removeAttribute('leftbar');
|
|
13
|
-
}
|
|
14
|
-
},
|
|
15
|
-
dismiss: () => {
|
|
16
|
-
if (l_body) {
|
|
17
|
-
l_body.removeAttribute('leftbar');
|
|
18
|
-
l_body.removeAttribute('rightbar');
|
|
19
|
-
}
|
|
20
|
-
},
|
|
21
|
-
toggleTOC: () => {
|
|
22
|
-
document.querySelector('#data-toc').classList.toggle('collapse');
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
</script>
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
<script type="text/javascript">
|
|
2
|
-
(() => {
|
|
3
|
-
const tagSwitchers = document.querySelectorAll('.tag-subtree.parent-tag > a > .tag-switcher-wrapper')
|
|
4
|
-
for (const tagSwitcher of tagSwitchers) {
|
|
5
|
-
tagSwitcher.addEventListener('click', (e) => {
|
|
6
|
-
const parent = e.target.closest('.tag-subtree.parent-tag')
|
|
7
|
-
parent.classList.toggle('expanded')
|
|
8
|
-
e.preventDefault()
|
|
9
|
-
})
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// Get active tag from query string, then activate it.
|
|
13
|
-
const urlParams = new URLSearchParams(window.location.search)
|
|
14
|
-
const activeTag = urlParams.get('tag')
|
|
15
|
-
if (activeTag) {
|
|
16
|
-
let tag = document.querySelector(`.tag-subtree[data-tag="${activeTag}"]`)
|
|
17
|
-
if (tag) {
|
|
18
|
-
tag.querySelector('a').classList.add('active')
|
|
19
|
-
<% if (!theme.widgets.tagtree.expand_active) { %>
|
|
20
|
-
tag = tag.parentElement.closest('.tag-subtree.parent-tag')
|
|
21
|
-
<% } %>
|
|
22
|
-
while (tag) {
|
|
23
|
-
tag.classList.add('expanded')
|
|
24
|
-
tag = tag.parentElement.closest('.tag-subtree.parent-tag')
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
})()
|
|
29
|
-
</script>
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
<script type="text/javascript">
|
|
2
|
-
const applyTheme = (theme) => {
|
|
3
|
-
if (theme === 'auto') {
|
|
4
|
-
document.documentElement.removeAttribute('data-theme')
|
|
5
|
-
} else {
|
|
6
|
-
document.documentElement.setAttribute('data-theme', theme)
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
// applyThemeToGiscus(theme)
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// FIXME: 这会导致无法使用 preferred_color_scheme 以外的主题
|
|
13
|
-
const applyThemeToGiscus = (theme) => {
|
|
14
|
-
// theme = theme === 'auto' ? 'preferred_color_scheme' : theme
|
|
15
|
-
const cmt = document.getElementById('giscus')
|
|
16
|
-
if (cmt) {
|
|
17
|
-
// This works before giscus load.
|
|
18
|
-
cmt.setAttribute('data-theme', theme)
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const iframe = document.querySelector('#comments > section.giscus > iframe')
|
|
22
|
-
if (iframe) {
|
|
23
|
-
// This works after giscus loaded.
|
|
24
|
-
const src = iframe.src
|
|
25
|
-
const newSrc = src.replace(/theme=[\w]+/, `theme=${theme}`)
|
|
26
|
-
iframe.src = newSrc
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const switchTheme = () => {
|
|
31
|
-
// light -> dark -> auto -> light -> ...
|
|
32
|
-
const currentTheme = document.documentElement.getAttribute('data-theme')
|
|
33
|
-
let newTheme;
|
|
34
|
-
switch (currentTheme) {
|
|
35
|
-
case 'light':
|
|
36
|
-
newTheme = 'dark'
|
|
37
|
-
break
|
|
38
|
-
case 'dark':
|
|
39
|
-
newTheme = 'auto'
|
|
40
|
-
break
|
|
41
|
-
default:
|
|
42
|
-
newTheme = 'light'
|
|
43
|
-
}
|
|
44
|
-
applyTheme(newTheme)
|
|
45
|
-
window.localStorage.setItem('Stellar.theme', newTheme)
|
|
46
|
-
utils.dark.mode = newTheme === 'auto' ? (window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light") : newTheme;
|
|
47
|
-
utils.dark.method.toggle.start();
|
|
48
|
-
|
|
49
|
-
const messages = {
|
|
50
|
-
light: `<%- __('message.theme_switched.light') %>`,
|
|
51
|
-
dark: `<%- __('message.theme_switched.dark') %>`,
|
|
52
|
-
auto: `<%- __('message.theme_switched.auto') %>`,
|
|
53
|
-
}
|
|
54
|
-
hud?.toast?.(messages[newTheme])
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
(() => {
|
|
58
|
-
// Apply user's preferred theme, if any.
|
|
59
|
-
const theme = window.localStorage.getItem('Stellar.theme')
|
|
60
|
-
if (theme !== null) {
|
|
61
|
-
applyTheme(theme)
|
|
62
|
-
} else {
|
|
63
|
-
utils.dark.mode = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
64
|
-
}
|
|
65
|
-
utils.dark.method.toggle.start();
|
|
66
|
-
})()
|
|
67
|
-
</script>
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|