[feat] support run-time theme switch, and visitor preferred theme (#449)
This commit is contained in:
parent
4f62677468
commit
09d91d06b6
|
@ -272,6 +272,9 @@ footer:
|
|||
# comments:
|
||||
# icon: '<img src="https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.12/social/942ebbf1a4b91.svg"/>'
|
||||
# url: /about/#comments
|
||||
# theme:
|
||||
# icon: default:theme
|
||||
# onclick: 'switchTheme()'
|
||||
sitemap:
|
||||
# '博客':
|
||||
# - '[近期](/)'
|
||||
|
|
|
@ -32,6 +32,7 @@ default:category: <svg style="margin-bottom:1px" xmlns="http://www.w3.org/2000/s
|
|||
default:edit: <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" d="M11.943 1.25H13.5a.75.75 0 0 1 0 1.5H12c-2.378 0-4.086.002-5.386.176c-1.279.172-2.05.5-2.62 1.069c-.569.57-.896 1.34-1.068 2.619c-.174 1.3-.176 3.008-.176 5.386s.002 4.086.176 5.386c.172 1.279.5 2.05 1.069 2.62c.57.569 1.34.896 2.619 1.068c1.3.174 3.008.176 5.386.176s4.086-.002 5.386-.176c1.279-.172 2.05-.5 2.62-1.069c.569-.57.896-1.34 1.068-2.619c.174-1.3.176-3.008.176-5.386v-1.5a.75.75 0 0 1 1.5 0v1.557c0 2.309 0 4.118-.19 5.53c-.194 1.444-.6 2.584-1.494 3.479c-.895.895-2.035 1.3-3.48 1.494c-1.411.19-3.22.19-5.529.19h-.114c-2.309 0-4.118 0-5.53-.19c-1.444-.194-2.584-.6-3.479-1.494c-.895-.895-1.3-2.035-1.494-3.48c-.19-1.411-.19-3.22-.19-5.529v-.114c0-2.309 0-4.118.19-5.53c.194-1.444.6-2.584 1.494-3.479c.895-.895 2.035-1.3 3.48-1.494c1.411-.19 3.22-.19 5.529-.19m4.827 1.026a3.503 3.503 0 0 1 4.954 4.953l-6.648 6.649c-.371.37-.604.604-.863.806a5.34 5.34 0 0 1-.987.61c-.297.141-.61.245-1.107.411l-2.905.968a1.492 1.492 0 0 1-1.887-1.887l.968-2.905c.166-.498.27-.81.411-1.107c.167-.35.372-.68.61-.987c.202-.26.435-.492.806-.863zm3.893 1.06a2.003 2.003 0 0 0-2.832 0l-.376.377c.022.096.054.21.098.338c.143.413.415.957.927 1.469a3.875 3.875 0 0 0 1.807 1.025l.376-.376a2.003 2.003 0 0 0 0-2.832m-1.558 4.391a5.397 5.397 0 0 1-1.686-1.146a5.395 5.395 0 0 1-1.146-1.686L11.218 9.95c-.417.417-.58.582-.72.76a3.84 3.84 0 0 0-.437.71c-.098.203-.172.423-.359.982l-.431 1.295l1.032 1.033l1.295-.432c.56-.187.779-.261.983-.358c.251-.12.49-.267.71-.439c.177-.139.342-.302.759-.718z" clip-rule="evenodd"/></svg>
|
||||
default:upup: <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-width="1.5"><path d="M2 12c0-4.714 0-7.071 1.464-8.536C4.93 2 7.286 2 12 2c4.714 0 7.071 0 8.535 1.464C22 4.93 22 7.286 22 12c0 4.714 0 7.071-1.465 8.535C19.072 22 16.714 22 12 22s-7.071 0-8.536-1.465C2 19.072 2 16.714 2 12Z"/><path stroke-linecap="round" stroke-linejoin="round" d="m9 15.5l3-3l3 3m-6-4l3-3l3 3"/></g></svg>
|
||||
default:tocomment: <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" d="M10.46 1.25h3.08c1.603 0 2.86 0 3.864.095c1.023.098 1.861.3 2.6.752a5.75 5.75 0 0 1 1.899 1.899c.452.738.654 1.577.752 2.6c.095 1.004.095 2.261.095 3.865v1.067c0 1.141 0 2.036-.05 2.759c-.05.735-.153 1.347-.388 1.913a5.75 5.75 0 0 1-3.112 3.112c-.805.334-1.721.408-2.977.43a10.81 10.81 0 0 0-.929.036c-.198.022-.275.054-.32.08c-.047.028-.112.078-.224.232c-.121.166-.258.396-.476.764l-.542.916c-.773 1.307-2.69 1.307-3.464 0l-.542-.916a10.605 10.605 0 0 0-.476-.764c-.112-.154-.177-.204-.224-.232c-.045-.026-.122-.058-.32-.08c-.212-.023-.49-.03-.93-.037c-1.255-.021-2.171-.095-2.976-.429A5.75 5.75 0 0 1 1.688 16.2c-.235-.566-.338-1.178-.389-1.913c-.049-.723-.049-1.618-.049-2.76v-1.066c0-1.604 0-2.86.095-3.865c.098-1.023.3-1.862.752-2.6a5.75 5.75 0 0 1 1.899-1.899c.738-.452 1.577-.654 2.6-.752C7.6 1.25 8.857 1.25 10.461 1.25M6.739 2.839c-.914.087-1.495.253-1.959.537A4.25 4.25 0 0 0 3.376 4.78c-.284.464-.45 1.045-.537 1.96c-.088.924-.089 2.11-.089 3.761v1c0 1.175 0 2.019.046 2.685c.045.659.131 1.089.278 1.441a4.25 4.25 0 0 0 2.3 2.3c.515.214 1.173.294 2.429.316h.031c.398.007.747.013 1.037.045c.311.035.616.104.909.274c.29.17.5.395.682.645c.169.232.342.525.538.856l.559.944a.52.52 0 0 0 .882 0l.559-.944c.196-.331.37-.624.538-.856c.182-.25.392-.476.682-.645c.293-.17.598-.24.909-.274c.29-.032.639-.038 1.037-.045h.032c1.255-.022 1.913-.102 2.428-.316a4.25 4.25 0 0 0 2.3-2.3c.147-.352.233-.782.278-1.441c.046-.666.046-1.51.046-2.685v-1c0-1.651 0-2.837-.089-3.762c-.087-.914-.253-1.495-.537-1.959a4.25 4.25 0 0 0-1.403-1.403c-.464-.284-1.045-.45-1.96-.537c-.924-.088-2.11-.089-3.761-.089h-3c-1.651 0-2.837 0-3.762.089" clip-rule="evenodd"/><path fill="currentColor" d="M9 11a1 1 0 1 1-2 0a1 1 0 0 1 2 0m4 0a1 1 0 1 1-2 0a1 1 0 0 1 2 0m4 0a1 1 0 1 1-2 0a1 1 0 0 1 2 0"/></svg>
|
||||
default:theme: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path fill="currentColor" fill-rule="evenodd" d="M582.4 326.4c-140.8 0-256 115.2-256 256s115.2 256 256 256 256-115.2 256-256-115.2-256-256-256z m0 448c-70.4 0-131.2-36.8-164.8-92.8 12.8 3.2 27.2 4.8 40 4.8 121.6 0 219.2-99.2 219.2-219.2 0-17.6-1.6-35.2-6.4-52.8 60.8 32 102.4 96 102.4 169.6 1.6 104-84.8 190.4-190.4 190.4zM582.4 262.4c17.6 0 32-14.4 32-32v-128c0-17.6-14.4-32-32-32s-32 14.4-32 32v128c0 17.6 14.4 32 32 32zM262.4 582.4c0-17.6-14.4-32-32-32h-128c-17.6 0-32 14.4-32 32s14.4 32 32 32h128c17.6 0 32-14.4 32-32zM310.4 356.8c6.4 6.4 14.4 9.6 22.4 9.6 8 0 16-3.2 22.4-9.6 12.8-12.8 12.8-32 0-44.8l-91.2-91.2c-12.8-12.8-32-12.8-44.8 0-12.8 12.8-12.8 32 0 44.8l91.2 91.2zM944 220.8c-12.8-12.8-32-12.8-44.8 0l-91.2 91.2c-12.8 12.8-12.8 32 0 44.8 6.4 6.4 14.4 9.6 22.4 9.6 8 0 16-3.2 22.4-9.6l91.2-91.2c12.8-12.8 12.8-33.6 0-44.8zM310.4 808l-91.2 91.2c-12.8 12.8-12.8 32 0 44.8 6.4 6.4 14.4 9.6 22.4 9.6 8 0 16-3.2 22.4-9.6l91.2-91.2c12.8-12.8 12.8-32 0-44.8-11.2-11.2-32-11.2-44.8 0z"></path></svg>
|
||||
|
||||
github:logo: <svg aria-hidden="true" role="img" class="color-icon-primary" viewBox="0 0 16 16" width="1em" height="1em" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible"><path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"></path></svg>
|
||||
github:repo: <svg aria-hidden="true" role="img" class="color-icon-primary" viewBox="0 0 16 16" width="1em" height="1em" fill="currentColor" style="user-select:none;overflow:visible"><path fill-rule="evenodd" d="M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 011-1h8zM5 12.25v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z"></path></svg>
|
||||
|
|
|
@ -53,6 +53,10 @@ search:
|
|||
|
||||
message:
|
||||
copied: Copied!
|
||||
theme_switched:
|
||||
light: Switched to Light Mode
|
||||
dark: Switched to Dark Mode
|
||||
auto: Switched to Auto Mode
|
||||
|
||||
symbol:
|
||||
comma: ", "
|
||||
|
|
|
@ -53,6 +53,10 @@ search:
|
|||
|
||||
message:
|
||||
copied: 复制成功
|
||||
theme_switched:
|
||||
light: 切换到浅色模式
|
||||
dark: 切换到深色模式
|
||||
auto: 切换到跟随系统配色
|
||||
|
||||
symbol:
|
||||
comma: ","
|
||||
|
|
|
@ -53,6 +53,10 @@ search:
|
|||
|
||||
message:
|
||||
copied: 複製成功
|
||||
theme_switched:
|
||||
light: 切換到淺色模式
|
||||
dark: 切換到深色模式
|
||||
auto: 切換到跟隨系統配色
|
||||
|
||||
symbol:
|
||||
comma: ","
|
||||
|
|
|
@ -22,6 +22,8 @@ function custom_inject() {
|
|||
<!-- required -->
|
||||
<script src="<%- `${theme.stellar.main_js}?v=${stellar_info('version')}` %>" async></script>
|
||||
|
||||
<%- partial('scripts/theme') %>
|
||||
|
||||
<!-- optional -->
|
||||
<%- partial('comments/script') %>
|
||||
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
<script type="text/javascript">
|
||||
const applyTheme = (theme) => {
|
||||
if (theme === 'auto') {
|
||||
document.documentElement.removeAttribute('data-theme')
|
||||
} else {
|
||||
document.documentElement.setAttribute('data-theme', theme)
|
||||
}
|
||||
|
||||
applyThemeToGiscus(theme)
|
||||
}
|
||||
|
||||
const applyThemeToGiscus = (theme) => {
|
||||
theme = theme === 'auto' ? 'preferred_color_scheme' : theme
|
||||
|
||||
const cmt = document.getElementById('giscus')
|
||||
if (cmt) {
|
||||
// This works before giscus load.
|
||||
cmt.setAttribute('data-theme', theme)
|
||||
}
|
||||
|
||||
const iframe = document.querySelector('#comments > section.giscus > iframe')
|
||||
if (iframe) {
|
||||
// This works after giscus loaded.
|
||||
const src = iframe.src
|
||||
const newSrc = src.replace(/theme=[\w]+/, `theme=${theme}`)
|
||||
iframe.src = newSrc
|
||||
}
|
||||
}
|
||||
|
||||
const switchTheme = () => {
|
||||
// light -> dark -> auto -> light -> ...
|
||||
const currentTheme = document.documentElement.getAttribute('data-theme')
|
||||
let newTheme;
|
||||
switch (currentTheme) {
|
||||
case 'light':
|
||||
newTheme = 'dark'
|
||||
break
|
||||
case 'dark':
|
||||
newTheme = 'auto'
|
||||
break
|
||||
default:
|
||||
newTheme = 'light'
|
||||
}
|
||||
applyTheme(newTheme)
|
||||
window.localStorage.setItem('Stellar.theme', newTheme)
|
||||
|
||||
const messages = {
|
||||
light: `<%- __('message.theme_switched.light') %>`,
|
||||
dark: `<%- __('message.theme_switched.dark') %>`,
|
||||
auto: `<%- __('message.theme_switched.auto') %>`,
|
||||
}
|
||||
hud?.toast?.(messages[newTheme])
|
||||
}
|
||||
|
||||
(() => {
|
||||
// Apply user's preferred theme, if any.
|
||||
const theme = window.localStorage.getItem('Stellar.theme')
|
||||
if (theme !== null) {
|
||||
applyTheme(theme)
|
||||
}
|
||||
})()
|
||||
</script>
|
|
@ -37,7 +37,11 @@ if (theme.style.site && theme.style.site['background-image']) {
|
|||
}
|
||||
|
||||
var html = `<!DOCTYPE html>`
|
||||
html += `<html lang="${page.lang}">`
|
||||
if (theme.style.prefers_theme === 'auto') {
|
||||
html += `<html lang="${page.lang}">`
|
||||
} else {
|
||||
html += `<html lang="${page.lang}" data-theme="${theme.style.prefers_theme}">`
|
||||
}
|
||||
html += partial('_partial/head')
|
||||
html += `<body>`
|
||||
html += site_background
|
||||
|
|
|
@ -60,8 +60,8 @@ a.button.start.gradient
|
|||
filter: blur(36px)
|
||||
opacity 1
|
||||
|
||||
if theme(dark)
|
||||
:root[data-theme="dark"] &
|
||||
ondark()
|
||||
else if theme(auto)
|
||||
:root:not([data-theme]) &
|
||||
@media (prefers-color-scheme: dark)
|
||||
ondark()
|
||||
|
|
|
@ -27,9 +27,9 @@
|
|||
trans1: all
|
||||
ondark()
|
||||
--blur-bg: alpha(#000, .4)
|
||||
if theme(dark)
|
||||
:root[data-theme="dark"] &
|
||||
ondark()
|
||||
else if theme(auto)
|
||||
:root:not([data-theme]) &
|
||||
@media (prefers-color-scheme: dark)
|
||||
ondark()
|
||||
|
||||
|
|
|
@ -50,8 +50,8 @@
|
|||
--button-hover-bg: rgba(black, 0.05)
|
||||
ondark()
|
||||
--button-hover-bg: rgba(white, 0.15)
|
||||
if theme(dark)
|
||||
:root[data-theme="dark"] &
|
||||
ondark()
|
||||
else if theme(auto)
|
||||
:root:not([data-theme]) &
|
||||
@media (prefers-color-scheme: dark)
|
||||
ondark()
|
||||
|
|
|
@ -109,9 +109,9 @@ _dark_tags()
|
|||
set_text_black()
|
||||
|
||||
|
||||
if theme(dark)
|
||||
:root[data-theme="dark"]
|
||||
_dark_tags()
|
||||
else if theme(auto)
|
||||
:root:not([data-theme])
|
||||
@media (prefers-color-scheme: dark)
|
||||
_dark_tags()
|
||||
|
||||
|
|
|
@ -113,13 +113,12 @@ hoverable-card()
|
|||
ondark()
|
||||
&:hover
|
||||
box-shadow: 0 0 4px -2px $color-theme, 0 0 24px -8px $color-theme
|
||||
if theme(light)
|
||||
:root[data-theme="light"] &
|
||||
onlight()
|
||||
else if theme(dark)
|
||||
:root[data-theme="dark"] &
|
||||
ondark()
|
||||
else
|
||||
:root:not([data-theme]) &
|
||||
@media (prefers-color-scheme: light)
|
||||
onlight()
|
||||
@media (prefers-color-scheme: dark)
|
||||
ondark()
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
// Deprecated function. Keep for compatibility.
|
||||
theme($t)
|
||||
convert(hexo-config('style.prefers_theme')) == $t
|
||||
|
||||
|
@ -40,46 +41,44 @@ _common_root()
|
|||
--theme-link: $color-link
|
||||
|
||||
_light_root()
|
||||
:root
|
||||
--site-bg: hsl($color-background-h, $color-background-s, $color-background-l)
|
||||
--card: hsl($color-block-h, $color-block-s, 100)
|
||||
--block: hsl($color-block-h, $color-block-s, 95)
|
||||
--block-border: hsl($color-block-h, $color-block-s, 90)
|
||||
--block-hover: hsl($color-block-h, $color-block-s, 92)
|
||||
--theme-link-opa: rgba($color-link, 0.2)
|
||||
--leftbar-bg: hsl($color-block-h, $color-block-s, 90)
|
||||
--alpha20: rgba(white, 0.2)
|
||||
--alpha50: rgba(white, 0.5)
|
||||
--alpha60: rgba(white, 0.6)
|
||||
--alpha75: rgba(white, 0.75)
|
||||
--alpha100: white
|
||||
_dark_text()
|
||||
--site-bg: hsl($color-background-h, $color-background-s, $color-background-l)
|
||||
--card: hsl($color-block-h, $color-block-s, 100)
|
||||
--block: hsl($color-block-h, $color-block-s, 95)
|
||||
--block-border: hsl($color-block-h, $color-block-s, 90)
|
||||
--block-hover: hsl($color-block-h, $color-block-s, 92)
|
||||
--theme-link-opa: rgba($color-link, 0.2)
|
||||
--leftbar-bg: hsl($color-block-h, $color-block-s, 90)
|
||||
--alpha20: rgba(white, 0.2)
|
||||
--alpha50: rgba(white, 0.5)
|
||||
--alpha60: rgba(white, 0.6)
|
||||
--alpha75: rgba(white, 0.75)
|
||||
--alpha100: white
|
||||
_dark_text()
|
||||
|
||||
_dark_root()
|
||||
:root
|
||||
--site-bg: hsl($color-background-h, $color-background-s * 0.5, (100 - $color-background-l) * 2 + 8)
|
||||
--card: hsl($color-block-h, $color-block-s * 1.2, 24)
|
||||
--block: hsl($color-block-h, $color-block-s, 16)
|
||||
--block-border: hsl($color-block-h, $color-block-s, 24)
|
||||
--block-hover: hsl($color-block-h, $color-block-s, 20)
|
||||
--theme-link-opa: rgba($color-link, 0.4)
|
||||
--leftbar-bg: hsl($color-block-h, $color-block-s, 24)
|
||||
--alpha20: rgba(black, 0.2)
|
||||
--alpha50: rgba(black, 0.5)
|
||||
--alpha60: rgba(black, 0.6)
|
||||
--alpha75: rgba(black, 0.75)
|
||||
--alpha100: black
|
||||
_light_text()
|
||||
@media screen and (max-width: $device-mobile-max)
|
||||
--site-bg: black
|
||||
--site-bg: hsl($color-background-h, $color-background-s * 0.5, (100 - $color-background-l) * 2 + 8)
|
||||
--card: hsl($color-block-h, $color-block-s * 1.2, 24)
|
||||
--block: hsl($color-block-h, $color-block-s, 16)
|
||||
--block-border: hsl($color-block-h, $color-block-s, 24)
|
||||
--block-hover: hsl($color-block-h, $color-block-s, 20)
|
||||
--theme-link-opa: rgba($color-link, 0.4)
|
||||
--leftbar-bg: hsl($color-block-h, $color-block-s, 24)
|
||||
--alpha20: rgba(black, 0.2)
|
||||
--alpha50: rgba(black, 0.5)
|
||||
--alpha60: rgba(black, 0.6)
|
||||
--alpha75: rgba(black, 0.75)
|
||||
--alpha100: black
|
||||
_light_text()
|
||||
@media screen and (max-width: $device-mobile-max)
|
||||
--site-bg: black
|
||||
|
||||
_common_root()
|
||||
// 默认自动模式
|
||||
if theme(light)
|
||||
|
||||
:root[data-theme="light"]
|
||||
_light_root()
|
||||
else if theme(dark)
|
||||
:root[data-theme="dark"]
|
||||
_dark_root()
|
||||
else
|
||||
:root:not([data-theme])
|
||||
@media (prefers-color-scheme: light)
|
||||
_light_root()
|
||||
@media (prefers-color-scheme: dark)
|
||||
|
|
|
@ -61,8 +61,8 @@
|
|||
font-size: 1.25em;
|
||||
color: #fff;
|
||||
|
||||
if theme(dark)
|
||||
:root[data-theme="dark"] &
|
||||
ondark()
|
||||
else if theme(auto)
|
||||
:root:not([data-theme]) &
|
||||
@media (prefers-color-scheme: dark)
|
||||
ondark()
|
||||
|
|
|
@ -108,8 +108,8 @@ _dark_mermaid()
|
|||
fill: #ccc
|
||||
|
||||
|
||||
if theme(dark)
|
||||
:root[data-theme="dark"]
|
||||
_dark_mermaid()
|
||||
else if theme(auto)
|
||||
:root:not([data-theme])
|
||||
@media (prefers-color-scheme: dark)
|
||||
_dark_mermaid()
|
||||
|
|
Loading…
Reference in New Issue