代码块

This commit is contained in:
2026-06-20 10:11:10 +08:00 Unverified
parent 2abe35fa4e
commit 72143f35af
3 changed files with 171 additions and 75 deletions
+46 -9
View File
@@ -54,9 +54,18 @@ const consoleSites = [
<script is:inline>
(() => {
const storageKey = 'site-theme';
const savedTheme = localStorage.getItem(storageKey);
const systemTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
document.documentElement.dataset.theme = savedTheme || systemTheme;
const media = window.matchMedia('(prefers-color-scheme: dark)');
const getSystemTheme = () => (media.matches ? 'dark' : 'light');
const getSavedTheme = () => {
try {
const theme = localStorage.getItem(storageKey);
return theme === 'dark' || theme === 'light' ? theme : null;
} catch {
return null;
}
};
document.documentElement.dataset.theme = getSavedTheme() || getSystemTheme();
})();
</script>
<link rel="stylesheet" href={siteConfig.cdn.instantsearchCss} />
@@ -257,25 +266,53 @@ const consoleSites = [
const button = document.querySelector('[data-theme-toggle]');
const media = window.matchMedia('(prefers-color-scheme: dark)');
const getSystemTheme = () => (media.matches ? 'dark' : 'light');
const getTheme = () => localStorage.getItem(storageKey) || getSystemTheme();
const getSavedTheme = () => {
try {
const theme = localStorage.getItem(storageKey);
return theme === 'dark' || theme === 'light' ? theme : null;
} catch {
return null;
}
};
const setSavedTheme = (theme) => {
try {
if (theme === getSystemTheme()) localStorage.removeItem(storageKey);
else localStorage.setItem(storageKey, theme);
} catch {
// localStorage can be unavailable in strict privacy modes.
}
};
const getTheme = () => getSavedTheme() || getSystemTheme();
function applyTheme(theme) {
root.dataset.theme = theme;
root.dataset.themeMode = getSavedTheme() ? 'manual' : 'auto';
button?.setAttribute('aria-label', theme === 'dark' ? '切换到日间模式' : '切换到夜间模式');
button?.setAttribute('title', theme === 'dark' ? '切换到日间模式' : '切换到夜间模式');
button?.setAttribute(
'title',
getSavedTheme()
? (theme === 'dark' ? '切换到日间模式' : '切换到夜间模式')
: `跟随系统:${theme === 'dark' ? '夜间' : '日间'}模式`
);
}
applyTheme(getTheme());
button?.addEventListener('click', () => {
const nextTheme = root.dataset.theme === 'dark' ? 'light' : 'dark';
localStorage.setItem(storageKey, nextTheme);
setSavedTheme(nextTheme);
applyTheme(nextTheme);
});
media.addEventListener('change', () => {
if (!localStorage.getItem(storageKey)) applyTheme(getSystemTheme());
});
const handleSystemThemeChange = () => {
if (!getSavedTheme()) applyTheme(getSystemTheme());
};
if (typeof media.addEventListener === 'function') {
media.addEventListener('change', handleSystemThemeChange);
} else if (typeof media.addListener === 'function') {
media.addListener(handleSystemThemeChange);
}
})();
(() => {
+14 -2
View File
@@ -390,9 +390,17 @@ const relatedPosts = allPosts
toggleButton.textContent = '展开';
toggleButton.setAttribute('aria-expanded', 'false');
const expandCue = document.createElement('button');
expandCue.className = 'code-block-expand-cue';
expandCue.type = 'button';
expandCue.setAttribute('aria-label', 'Expand code block');
expandCue.setAttribute('aria-expanded', 'false');
expandCue.innerHTML = '<span aria-hidden="true"></span>';
toolbar.append(copyButton, toggleButton);
header.append(language, toolbar);
wrapper.appendChild(header);
wrapper.appendChild(expandCue);
const codeLines = [...code.querySelectorAll(':scope > .line')];
if (codeLines.length > 0) {
@@ -421,11 +429,15 @@ const relatedPosts = allPosts
}
});
toggleButton.addEventListener('click', () => {
function toggleExpanded() {
const isExpanded = wrapper.classList.toggle('is-expanded');
toggleButton.textContent = isExpanded ? '收起' : '展开';
toggleButton.setAttribute('aria-expanded', String(isExpanded));
});
expandCue.setAttribute('aria-expanded', String(isExpanded));
}
toggleButton.addEventListener('click', toggleExpanded);
expandCue.addEventListener('click', toggleExpanded);
});
})();
</script>
+111 -64
View File
@@ -19,14 +19,14 @@
:root[data-theme='dark'] {
color-scheme: dark;
--bg: #0f171a;
--surface: #162225;
--text: #e9f0ee;
--muted: #a7b4b1;
--line: rgba(174, 205, 197, 0.18);
--accent: #72ded2;
--accent-strong: #9af0d6;
--shadow: 0 18px 48px rgba(0, 0, 0, 0.28);
--bg: #0b1014;
--surface: #141b21;
--text: #e7edf0;
--muted: #9ba9b1;
--line: rgba(166, 184, 194, 0.2);
--accent: #7dd3c7;
--accent-strong: #b7e7d4;
--shadow: 0 18px 52px rgba(0, 0, 0, 0.36);
}
* {
@@ -49,7 +49,7 @@ body {
:root[data-theme='dark'] body {
background:
linear-gradient(rgba(8, 13, 16, 0.86), rgba(10, 17, 20, 0.94)),
linear-gradient(rgba(7, 10, 14, 0.9), rgba(8, 13, 17, 0.96)),
url('/images/background.png') center top / cover fixed;
}
@@ -563,20 +563,20 @@ a {
}
:root[data-theme='dark'] .nav {
border-color: rgba(174, 205, 197, 0.2);
border-color: rgba(166, 184, 194, 0.2);
background:
linear-gradient(135deg, rgba(29, 47, 51, 0.78), rgba(14, 23, 27, 0.54)),
rgba(12, 19, 22, 0.62);
linear-gradient(135deg, rgba(25, 35, 42, 0.82), rgba(10, 15, 20, 0.66)),
rgba(10, 15, 20, 0.68);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, 0.12),
inset 0 -18px 38px rgba(0, 0, 0, 0.18),
0 18px 54px rgba(0, 0, 0, 0.34);
0 18px 54px rgba(0, 0, 0, 0.42);
}
:root[data-theme='dark'] .nav::before {
background:
radial-gradient(circle at 18% 0%, rgba(114, 222, 210, 0.18), transparent 32%),
linear-gradient(90deg, rgba(255, 255, 255, 0.08), transparent 42%, rgba(114, 222, 210, 0.1));
radial-gradient(circle at 18% 0%, rgba(125, 211, 199, 0.16), transparent 32%),
linear-gradient(90deg, rgba(255, 255, 255, 0.07), transparent 42%, rgba(125, 211, 199, 0.08));
}
:root[data-theme='dark'] .nav::after {
@@ -589,8 +589,8 @@ a {
:root[data-theme='dark'] .nav-console:hover,
:root[data-theme='dark'] .theme-toggle:hover,
:root[data-theme='dark'] .nav-menu-toggle:hover {
border-color: rgba(114, 222, 210, 0.26);
background: rgba(114, 222, 210, 0.12);
border-color: rgba(125, 211, 199, 0.28);
background: rgba(125, 211, 199, 0.11);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, 0.12),
0 8px 18px rgba(0, 0, 0, 0.18);
@@ -601,14 +601,14 @@ a {
}
:root[data-theme='dark'] .control-console-panel {
border-color: rgba(174, 205, 197, 0.18);
border-color: rgba(166, 184, 194, 0.2);
background:
radial-gradient(circle at 14% 0%, rgba(114, 222, 210, 0.1), transparent 34%),
linear-gradient(145deg, rgba(28, 43, 47, 0.88), rgba(12, 22, 25, 0.8)),
rgba(17, 28, 31, 0.82);
radial-gradient(circle at 14% 0%, rgba(125, 211, 199, 0.08), transparent 34%),
linear-gradient(145deg, rgba(24, 34, 42, 0.9), rgba(10, 17, 22, 0.84)),
rgba(14, 22, 28, 0.84);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, 0.1),
0 28px 80px rgba(0, 0, 0, 0.38);
0 28px 80px rgba(0, 0, 0, 0.46);
}
:root[data-theme='dark'] .control-console-head h2,
@@ -620,8 +620,8 @@ a {
:root[data-theme='dark'] .control-site-card,
:root[data-theme='dark'] .control-console-info section,
:root[data-theme='dark'] .control-console-close {
border-color: rgba(114, 222, 210, 0.2);
background: rgba(114, 222, 210, 0.1);
border-color: rgba(125, 211, 199, 0.2);
background: rgba(125, 211, 199, 0.08);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08);
}
@@ -631,35 +631,35 @@ a {
}
:root[data-theme='dark'] .custom-context-menu {
border-color: rgba(174, 205, 197, 0.2);
border-color: rgba(166, 184, 194, 0.2);
color: #d8e5e2;
background:
linear-gradient(145deg, rgba(31, 48, 52, 0.88), rgba(13, 23, 26, 0.78)),
rgba(15, 25, 28, 0.82);
linear-gradient(145deg, rgba(27, 39, 47, 0.9), rgba(10, 17, 22, 0.82)),
rgba(14, 22, 28, 0.84);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, 0.1),
0 18px 42px rgba(0, 0, 0, 0.34);
0 18px 42px rgba(0, 0, 0, 0.42);
}
:root[data-theme='dark'] .context-menu-nav :where(a, button) {
border-color: rgba(174, 205, 197, 0.16);
color: #b7c7c4;
border-color: rgba(166, 184, 194, 0.16);
color: #b7c3c8;
background: rgba(255, 255, 255, 0.06);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08);
}
:root[data-theme='dark'] .context-menu-group {
border-top-color: rgba(174, 205, 197, 0.16);
border-top-color: rgba(166, 184, 194, 0.16);
}
:root[data-theme='dark'] .custom-context-menu :where(a, button):hover,
:root[data-theme='dark'] .custom-context-menu :where(a, button):focus-visible {
color: var(--accent);
background: rgba(114, 222, 210, 0.11);
background: rgba(125, 211, 199, 0.1);
}
:root[data-theme='dark'] .custom-context-menu i {
color: #a8b8b5;
color: #a8b5ba;
}
.hero {
@@ -2235,6 +2235,7 @@ time {
.prose .code-block.is-collapsible:not(.is-expanded)::after {
content: "";
position: absolute;
z-index: 1;
right: 0;
bottom: 0;
left: 0;
@@ -2243,6 +2244,52 @@ time {
pointer-events: none;
}
.code-block-expand-cue {
appearance: none;
-webkit-appearance: none;
position: absolute;
z-index: 3;
right: 50%;
bottom: 10px;
display: none;
width: 36px;
height: 28px;
align-items: center;
justify-content: center;
border: 1px solid rgba(255, 255, 255, 0.18);
border-radius: 999px;
padding: 0;
background: rgba(22, 31, 36, 0.72);
box-shadow: 0 8px 18px rgba(0, 0, 0, 0.18);
cursor: pointer;
transform: translateX(50%);
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
transition:
border-color 0.2s ease,
background-color 0.2s ease,
transform 0.2s ease;
}
.code-block-expand-cue span {
width: 10px;
height: 10px;
border-right: 2px solid rgba(255, 255, 255, 0.9);
border-bottom: 2px solid rgba(255, 255, 255, 0.9);
transform: translateY(-2px) rotate(45deg);
}
.code-block-expand-cue:hover,
.code-block-expand-cue:focus-visible {
border-color: rgba(255, 255, 255, 0.36);
background: rgba(62, 184, 190, 0.82);
transform: translateX(50%) translateY(-1px);
}
.prose .code-block.is-collapsible:not(.is-expanded) .code-block-expand-cue {
display: inline-flex;
}
.prose .code-block code {
color: #e8edf2;
line-height: 1.42;
@@ -3882,11 +3929,11 @@ meting-js {
.pagination-link,
.pagination-number
) {
border-color: rgba(174, 205, 197, 0.18);
border-color: rgba(166, 184, 194, 0.18);
background:
radial-gradient(circle at 14% 0%, rgba(114, 222, 210, 0.1), transparent 34%),
linear-gradient(145deg, rgba(28, 43, 47, 0.82), rgba(12, 22, 25, 0.72)),
rgba(17, 28, 31, 0.74);
radial-gradient(circle at 14% 0%, rgba(125, 211, 199, 0.08), transparent 34%),
linear-gradient(145deg, rgba(24, 34, 42, 0.84), rgba(10, 17, 22, 0.76)),
rgba(14, 22, 28, 0.78);
box-shadow: var(--shadow);
}
@@ -3931,12 +3978,12 @@ meting-js {
}
:root[data-theme='dark'] .chart-legend-item {
border-color: rgba(174, 205, 197, 0.16);
border-color: rgba(166, 184, 194, 0.16);
background: rgba(255, 255, 255, 0.05);
}
:root[data-theme='dark'] .pie-chart-track {
stroke: rgba(174, 205, 197, 0.16);
stroke: rgba(166, 184, 194, 0.16);
}
:root[data-theme='dark'] .line-chart-dot {
@@ -3954,9 +4001,9 @@ meting-js {
.post-copyright-action,
.post-copyright-icon
) {
border-color: rgba(114, 222, 210, 0.22);
border-color: rgba(125, 211, 199, 0.22);
color: var(--accent);
background: rgba(114, 222, 210, 0.1);
background: rgba(125, 211, 199, 0.1);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08);
}
@@ -3980,30 +4027,30 @@ meting-js {
}
:root[data-theme='dark'] .article-header-cover {
background: #0d1f21;
background: #0d171d;
}
:root[data-theme='dark'] .article-header-cover::before {
background:
linear-gradient(180deg, rgba(5, 12, 14, 0.54), rgba(7, 19, 21, 0.22) 38%, rgba(3, 10, 11, 0.82)),
linear-gradient(90deg, rgba(5, 18, 20, 0.62), rgba(12, 60, 57, 0.16) 54%, rgba(5, 18, 20, 0.44));
linear-gradient(180deg, rgba(5, 9, 12, 0.58), rgba(8, 16, 20, 0.28) 38%, rgba(3, 8, 11, 0.86)),
linear-gradient(90deg, rgba(5, 13, 17, 0.66), rgba(20, 57, 58, 0.14) 54%, rgba(5, 13, 17, 0.48));
}
:root[data-theme='dark'] .prose .code-block {
border-color: rgba(114, 222, 210, 0.2);
background: rgba(5, 10, 12, 0.96);
box-shadow: 0 14px 32px rgba(0, 0, 0, 0.24);
border-color: rgba(125, 211, 199, 0.18);
background: rgba(5, 8, 12, 0.96);
box-shadow: 0 14px 32px rgba(0, 0, 0, 0.32);
}
:root[data-theme='dark'] .prose :not(pre) > code {
border-color: rgba(114, 222, 210, 0.22);
border-color: rgba(125, 211, 199, 0.22);
color: var(--accent);
background: rgba(114, 222, 210, 0.1);
background: rgba(125, 211, 199, 0.1);
}
:root[data-theme='dark'] .butterfly-note {
color: #dce9e6;
background: rgba(114, 222, 210, 0.08);
background: rgba(125, 211, 199, 0.08);
}
:root[data-theme='dark'] .butterfly-note--disabled {
@@ -4015,7 +4062,7 @@ meting-js {
}
:root[data-theme='dark'] .butterfly-hide-block__content {
border-left-color: rgba(114, 222, 210, 0.22);
border-left-color: rgba(125, 211, 199, 0.22);
}
:root[data-theme='dark'] .prose table {
@@ -4025,43 +4072,43 @@ meting-js {
:root[data-theme='dark'] .prose thead th {
color: #effaf7;
background:
linear-gradient(135deg, rgba(40, 70, 70, 0.86), rgba(22, 41, 44, 0.76)),
rgba(13, 24, 27, 0.8);
linear-gradient(135deg, rgba(35, 55, 61, 0.86), rgba(18, 31, 38, 0.78)),
rgba(12, 21, 27, 0.84);
}
:root[data-theme='dark'] .prose tbody tr:nth-child(even) td {
background: rgba(114, 222, 210, 0.07);
background: rgba(125, 211, 199, 0.06);
}
:root[data-theme='dark'] .prose tbody tr:hover td {
background: rgba(114, 222, 210, 0.12);
background: rgba(125, 211, 199, 0.1);
}
:root[data-theme='dark'] .prose :where(th, td) {
border-color: rgba(114, 222, 210, 0.12);
border-color: rgba(125, 211, 199, 0.12);
}
:root[data-theme='dark'] .site-footer {
color: rgba(197, 214, 211, 0.74);
color: rgba(199, 211, 216, 0.76);
background:
linear-gradient(180deg, rgba(12, 20, 23, 0.68), rgba(8, 14, 17, 0.88)),
rgba(8, 14, 17, 0.84);
linear-gradient(180deg, rgba(10, 16, 21, 0.7), rgba(6, 10, 14, 0.9)),
rgba(7, 11, 15, 0.86);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08);
}
:root[data-theme='dark'] .footer-socials a {
border-color: rgba(174, 205, 197, 0.18);
border-color: rgba(166, 184, 194, 0.18);
color: rgba(218, 234, 231, 0.82);
background:
linear-gradient(145deg, rgba(34, 51, 55, 0.78), rgba(14, 24, 27, 0.72)),
rgba(18, 29, 32, 0.72);
linear-gradient(145deg, rgba(28, 40, 48, 0.8), rgba(10, 17, 22, 0.74)),
rgba(14, 22, 28, 0.74);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, 0.08),
0 10px 24px rgba(0, 0, 0, 0.22);
0 10px 24px rgba(0, 0, 0, 0.3);
}
:root[data-theme='dark'] .footer-bottom {
border-top-color: rgba(174, 205, 197, 0.16);
border-top-color: rgba(166, 184, 194, 0.16);
}
@media (min-width: 960px) {