-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
20 changed files
with
4,029 additions
and
295 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,22 @@ | ||
Fluid.boot={},Fluid.boot.registerEvents=function(){Fluid.events.billboard(),Fluid.events.registerNavbarEvent(),Fluid.events.registerParallaxEvent(),Fluid.events.registerScrollDownArrowEvent(),Fluid.events.registerScrollTopArrowEvent(),Fluid.events.registerImageLoadedEvent()},Fluid.boot.refresh=function(){Fluid.plugins.fancyBox(),Fluid.plugins.codeWidget(),Fluid.events.refresh()},document.addEventListener("DOMContentLoaded",(function(){Fluid.boot.registerEvents()})); | ||
/* global Fluid */ | ||
|
||
Fluid.boot = {}; | ||
|
||
Fluid.boot.registerEvents = function() { | ||
Fluid.events.billboard(); | ||
Fluid.events.registerNavbarEvent(); | ||
Fluid.events.registerParallaxEvent(); | ||
Fluid.events.registerScrollDownArrowEvent(); | ||
Fluid.events.registerScrollTopArrowEvent(); | ||
Fluid.events.registerImageLoadedEvent(); | ||
}; | ||
|
||
Fluid.boot.refresh = function() { | ||
Fluid.plugins.fancyBox(); | ||
Fluid.plugins.codeWidget(); | ||
Fluid.events.refresh(); | ||
}; | ||
|
||
document.addEventListener('DOMContentLoaded', function() { | ||
Fluid.boot.registerEvents(); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,279 @@ | ||
!function(e,t){var r=t.documentElement,i="Fluid_Color_Scheme",a="--color-mode",o="data-user-color-scheme",n="data-default-color-scheme",c="#color-toggle-icon";function u(e){try{return localStorage.getItem(e)}catch(t){return null}}function s(){var e=getComputedStyle(r).getPropertyValue(a);return"string"==typeof e?e.replace(/["'\s]/g,""):null}function l(){r.setAttribute(o,g()),function(e){try{localStorage.removeItem(e)}catch(t){}}(i)}var d={dark:!0,light:!0};function g(){var e,t="string"==typeof(e=r.getAttribute(n))?e.replace(/["'\s]/g,""):null;if(d[t])return t;if(t=s(),d[t])return t;var i=(new Date).getHours();return i>=18||i>=0&&i<=6?"dark":"light"}function m(a){var n=a||u(i)||g();if(n===g())l();else{if(!d[n])return void l();r.setAttribute(o,n)}!function(e){if(d[e]){var r=h("dark");e&&(r=h(e));var i=t.querySelector(c);if(i?(i.setAttribute("class","iconfont "+r),i.setAttribute("data",f[e])):Fluid.utils.waitElementLoaded(c,(function(){var i=t.querySelector(c);i&&(i.setAttribute("class","iconfont "+r),i.setAttribute("data",f[e]))})),t.documentElement.getAttribute("data-user-color-scheme")){var a=getComputedStyle(t.documentElement).getPropertyValue("--navbar-bg-color").trim();t.querySelector('meta[name="theme-color"]').setAttribute("content",a)}}}(n),function(e){var r=t.getElementById("highlight-css"),i=t.getElementById("highlight-css-dark");"dark"===e?(i&&i.removeAttribute("disabled"),r&&r.setAttribute("disabled","")):(r&&r.removeAttribute("disabled"),i&&i.setAttribute("disabled",""));setTimeout((function(){t.querySelectorAll(".markdown-body pre").forEach((e=>{var t=Fluid.utils.getBackgroundLightness(e)>=0?"code-widget-light":"code-widget-dark",r=e.querySelector(".code-widget-light, .code-widget-dark");r&&(r.classList.remove("code-widget-light","code-widget-dark"),r.classList.add(t))}))}),200)}(n),function(r){e.REMARK42&&e.REMARK42.changeTheme(r);e.CUSDIS&&e.CUSDIS.setTheme(r);var i=t.querySelector(".utterances-frame");if(i){const t={type:"set-theme",theme:"dark"===r?e.UtterancesThemeDark:e.UtterancesThemeLight};i.contentWindow.postMessage(t,"https://utteranc.es")}var a=t.querySelector("iframe.giscus-frame");if(a){const t={setConfig:{theme:"dark"===r?e.GiscusThemeDark:e.GiscusThemeLight}};a.contentWindow.postMessage({giscus:t},"https://giscus.app")}}(n)}var f={dark:"light",light:"dark"};function h(e){return"icon-"+e}function v(){var e=u(i);if(d[e])e=f[e];else{if(null!==e)return;var r=t.querySelector(c);r&&(e=r.getAttribute("data")),r&&d[e]||(e=f[s()])}return function(e,t){try{localStorage.setItem(e,t)}catch(r){}}(i,e),e}m(),Fluid.utils.waitElementLoaded(c,(function(){m();var e=t.querySelector("#color-toggle-btn");if(e){e.addEventListener("click",(function(){m(v())}));var r=t.querySelector(c);r&&(e.addEventListener("mouseenter",(function(){var e=r.getAttribute("data");r.classList.replace(h(f[e]),h(e))})),e.addEventListener("mouseleave",(function(){var e=r.getAttribute("data");r.classList.replace(h(e),h(f[e]))})))}}))}(window,document); | ||
/* global Fluid */ | ||
|
||
/** | ||
* Modified from https://blog.skk.moe/post/hello-darkmode-my-old-friend/ | ||
*/ | ||
(function(window, document) { | ||
var rootElement = document.documentElement; | ||
var colorSchemaStorageKey = 'Fluid_Color_Scheme'; | ||
var colorSchemaMediaQueryKey = '--color-mode'; | ||
var userColorSchemaAttributeName = 'data-user-color-scheme'; | ||
var defaultColorSchemaAttributeName = 'data-default-color-scheme'; | ||
var colorToggleButtonSelector = '#color-toggle-btn'; | ||
var colorToggleIconSelector = '#color-toggle-icon'; | ||
|
||
function setLS(k, v) { | ||
try { | ||
localStorage.setItem(k, v); | ||
} catch (e) {} | ||
} | ||
|
||
function removeLS(k) { | ||
try { | ||
localStorage.removeItem(k); | ||
} catch (e) {} | ||
} | ||
|
||
function getLS(k) { | ||
try { | ||
return localStorage.getItem(k); | ||
} catch (e) { | ||
return null; | ||
} | ||
} | ||
|
||
function getSchemaFromHTML() { | ||
var res = rootElement.getAttribute(defaultColorSchemaAttributeName); | ||
if (typeof res === 'string') { | ||
return res.replace(/["'\s]/g, ''); | ||
} | ||
return null; | ||
} | ||
|
||
function getSchemaFromCSSMediaQuery() { | ||
var res = getComputedStyle(rootElement).getPropertyValue( | ||
colorSchemaMediaQueryKey | ||
); | ||
if (typeof res === 'string') { | ||
return res.replace(/["'\s]/g, ''); | ||
} | ||
return null; | ||
} | ||
|
||
function resetSchemaAttributeAndLS() { | ||
rootElement.setAttribute(userColorSchemaAttributeName, getDefaultColorSchema()); | ||
removeLS(colorSchemaStorageKey); | ||
} | ||
|
||
var validColorSchemaKeys = { | ||
dark : true, | ||
light: true | ||
}; | ||
|
||
function getDefaultColorSchema() { | ||
// 取默认字段的值 | ||
var schema = getSchemaFromHTML(); | ||
// 如果明确指定了 schema 则返回 | ||
if (validColorSchemaKeys[schema]) { | ||
return schema; | ||
} | ||
// 默认优先按 prefers-color-scheme | ||
schema = getSchemaFromCSSMediaQuery(); | ||
if (validColorSchemaKeys[schema]) { | ||
return schema; | ||
} | ||
// 否则按本地时间是否大于 18 点或凌晨 0 ~ 6 点 | ||
var hours = new Date().getHours(); | ||
if (hours >= 18 || (hours >= 0 && hours <= 6)) { | ||
return 'dark'; | ||
} | ||
return 'light'; | ||
} | ||
|
||
function applyCustomColorSchemaSettings(schema) { | ||
// 接受从「开关」处传来的模式,或者从 localStorage 读取,否则按默认设置值 | ||
var current = schema || getLS(colorSchemaStorageKey) || getDefaultColorSchema(); | ||
|
||
if (current === getDefaultColorSchema()) { | ||
// 当用户切换的显示模式和默认模式相同时,则恢复为自动模式 | ||
resetSchemaAttributeAndLS(); | ||
} else if (validColorSchemaKeys[current]) { | ||
rootElement.setAttribute( | ||
userColorSchemaAttributeName, | ||
current | ||
); | ||
} else { | ||
// 特殊情况重置 | ||
resetSchemaAttributeAndLS(); | ||
return; | ||
} | ||
|
||
// 根据当前模式设置图标 | ||
setButtonIcon(current); | ||
|
||
// 设置代码高亮 | ||
setHighlightCSS(current); | ||
|
||
// 设置其他应用 | ||
setApplications(current); | ||
} | ||
|
||
var invertColorSchemaObj = { | ||
dark : 'light', | ||
light: 'dark' | ||
}; | ||
|
||
function getIconClass(scheme) { | ||
return 'icon-' + scheme; | ||
} | ||
|
||
function toggleCustomColorSchema() { | ||
var currentSetting = getLS(colorSchemaStorageKey); | ||
|
||
if (validColorSchemaKeys[currentSetting]) { | ||
// 从 localStorage 中读取模式,并取相反的模式 | ||
currentSetting = invertColorSchemaObj[currentSetting]; | ||
} else if (currentSetting === null) { | ||
// 当 localStorage 中没有相关值,或者 localStorage 抛了 Error | ||
// 先按照按钮的状态进行切换 | ||
var iconElement = document.querySelector(colorToggleIconSelector); | ||
if (iconElement) { | ||
currentSetting = iconElement.getAttribute('data'); | ||
} | ||
if (!iconElement || !validColorSchemaKeys[currentSetting]) { | ||
// 当 localStorage 中没有相关值,或者 localStorage 抛了 Error,则读取默认值并切换到相反的模式 | ||
currentSetting = invertColorSchemaObj[getSchemaFromCSSMediaQuery()]; | ||
} | ||
} else { | ||
return; | ||
} | ||
// 将相反的模式写入 localStorage | ||
setLS(colorSchemaStorageKey, currentSetting); | ||
|
||
return currentSetting; | ||
} | ||
|
||
function setButtonIcon(schema) { | ||
if (validColorSchemaKeys[schema]) { | ||
// 切换图标 | ||
var icon = getIconClass('dark'); | ||
if (schema) { | ||
icon = getIconClass(schema); | ||
} | ||
var iconElement = document.querySelector(colorToggleIconSelector); | ||
if (iconElement) { | ||
iconElement.setAttribute( | ||
'class', | ||
'iconfont ' + icon | ||
); | ||
iconElement.setAttribute( | ||
'data', | ||
invertColorSchemaObj[schema] | ||
); | ||
} else { | ||
// 如果图标不存在则说明图标还没加载出来,等到页面全部加载再尝试切换 | ||
Fluid.utils.waitElementLoaded(colorToggleIconSelector, function() { | ||
var iconElement = document.querySelector(colorToggleIconSelector); | ||
if (iconElement) { | ||
iconElement.setAttribute( | ||
'class', | ||
'iconfont ' + icon | ||
); | ||
iconElement.setAttribute( | ||
'data', | ||
invertColorSchemaObj[schema] | ||
); | ||
} | ||
}); | ||
} | ||
if (document.documentElement.getAttribute('data-user-color-scheme')) { | ||
var color = getComputedStyle(document.documentElement).getPropertyValue('--navbar-bg-color').trim() | ||
document.querySelector('meta[name="theme-color"]').setAttribute('content', color) | ||
} | ||
} | ||
} | ||
|
||
function setHighlightCSS(schema) { | ||
// 启用对应的代码高亮的样式 | ||
var lightCss = document.getElementById('highlight-css'); | ||
var darkCss = document.getElementById('highlight-css-dark'); | ||
if (schema === 'dark') { | ||
if (darkCss) { | ||
darkCss.removeAttribute('disabled'); | ||
} | ||
if (lightCss) { | ||
lightCss.setAttribute('disabled', ''); | ||
} | ||
} else { | ||
if (lightCss) { | ||
lightCss.removeAttribute('disabled'); | ||
} | ||
if (darkCss) { | ||
darkCss.setAttribute('disabled', ''); | ||
} | ||
} | ||
|
||
setTimeout(function() { | ||
// 设置代码块组件样式 | ||
document.querySelectorAll('.markdown-body pre').forEach((pre) => { | ||
var cls = Fluid.utils.getBackgroundLightness(pre) >= 0 ? 'code-widget-light' : 'code-widget-dark'; | ||
var widget = pre.querySelector('.code-widget-light, .code-widget-dark'); | ||
if (widget) { | ||
widget.classList.remove('code-widget-light', 'code-widget-dark'); | ||
widget.classList.add(cls); | ||
} | ||
}); | ||
}, 200); | ||
} | ||
|
||
function setApplications(schema) { | ||
// 设置 remark42 评论主题 | ||
if (window.REMARK42) { | ||
window.REMARK42.changeTheme(schema); | ||
} | ||
|
||
// 设置 cusdis 评论主题 | ||
if (window.CUSDIS) { | ||
window.CUSDIS.setTheme(schema); | ||
} | ||
|
||
// 设置 utterances 评论主题 | ||
var utterances = document.querySelector('.utterances-frame'); | ||
if (utterances) { | ||
var utterancesTheme = schema === 'dark' ? window.UtterancesThemeDark : window.UtterancesThemeLight; | ||
const message = { | ||
type : 'set-theme', | ||
theme: utterancesTheme | ||
}; | ||
utterances.contentWindow.postMessage(message, 'https://utteranc.es'); | ||
} | ||
|
||
// 设置 giscus 评论主题 | ||
var giscus = document.querySelector('iframe.giscus-frame'); | ||
if (giscus) { | ||
var giscusTheme = schema === 'dark' ? window.GiscusThemeDark : window.GiscusThemeLight; | ||
const message = { | ||
setConfig: { | ||
theme: giscusTheme, | ||
} | ||
}; | ||
giscus.contentWindow.postMessage({ 'giscus': message }, 'https://giscus.app'); | ||
} | ||
} | ||
|
||
// 当页面加载时,将显示模式设置为 localStorage 中自定义的值(如果有的话) | ||
applyCustomColorSchemaSettings(); | ||
|
||
Fluid.utils.waitElementLoaded(colorToggleIconSelector, function() { | ||
applyCustomColorSchemaSettings(); | ||
var button = document.querySelector(colorToggleButtonSelector); | ||
if (button) { | ||
// 当用户点击切换按钮时,获得新的显示模式、写入 localStorage、并在页面上生效 | ||
button.addEventListener('click', function() { | ||
applyCustomColorSchemaSettings(toggleCustomColorSchema()); | ||
}); | ||
var icon = document.querySelector(colorToggleIconSelector); | ||
if (icon) { | ||
// 光标悬停在按钮上时,切换图标 | ||
button.addEventListener('mouseenter', function() { | ||
var current = icon.getAttribute('data'); | ||
icon.classList.replace(getIconClass(invertColorSchemaObj[current]), getIconClass(current)); | ||
}); | ||
button.addEventListener('mouseleave', function() { | ||
var current = icon.getAttribute('data'); | ||
icon.classList.replace(getIconClass(current), getIconClass(invertColorSchemaObj[current])); | ||
}); | ||
} | ||
} | ||
}); | ||
})(window, document); |
Oops, something went wrong.