1/* global Fluid */ 2 3/** 4 * Modified from https://blog.skk.moe/post/hello-darkmode-my-old-friend/ 5 */ 6(function(window, document) { 7 var rootElement = document.documentElement; 8 var colorSchemaStorageKey = 'Fluid_Color_Scheme'; 9 var colorSchemaMediaQueryKey = '--color-mode'; 10 var userColorSchemaAttributeName = 'data-user-color-scheme'; 11 var defaultColorSchemaAttributeName = 'data-default-color-scheme'; 12 var colorToggleButtonSelector = '#color-toggle-btn'; 13 var colorToggleIconSelector = '#color-toggle-icon'; 14 var iframeSelector = 'iframe'; 15 16 function setLS(k, v) { 17 try { 18 localStorage.setItem(k, v); 19 } catch (e) {} 20 } 21 22 function removeLS(k) { 23 try { 24 localStorage.removeItem(k); 25 } catch (e) {} 26 } 27 28 function getLS(k) { 29 try { 30 return localStorage.getItem(k); 31 } catch (e) { 32 return null; 33 } 34 } 35 36 function getSchemaFromHTML() { 37 var res = rootElement.getAttribute(defaultColorSchemaAttributeName); 38 if (typeof res === 'string') { 39 return res.replace(/["'\s]/g, ''); 40 } 41 return null; 42 } 43 44 function getSchemaFromCSSMediaQuery() { 45 var res = getComputedStyle(rootElement).getPropertyValue( 46 colorSchemaMediaQueryKey 47 ); 48 if (typeof res === 'string') { 49 return res.replace(/["'\s]/g, ''); 50 } 51 return null; 52 } 53 54 function resetSchemaAttributeAndLS() { 55 rootElement.setAttribute(userColorSchemaAttributeName, getDefaultColorSchema()); 56 removeLS(colorSchemaStorageKey); 57 } 58 59 var validColorSchemaKeys = { 60 dark : true, 61 light: true 62 }; 63 64 function getDefaultColorSchema() { 65 // åé»è®¤å段çå¼ 66 var schema = getSchemaFromHTML(); 67 // 妿æç¡®æå®äº schema åè¿å 68 if (validColorSchemaKeys[schema]) { 69 return schema; 70 } 71 // é»è®¤ä¼å æ prefers-color-scheme 72 schema = getSchemaFromCSSMediaQuery(); 73 if (validColorSchemaKeys[schema]) { 74 return schema; 75 } 76 // å¦åææ¬å°æ¶é´æ¯å¦å¤§äº 18 ç¹æåæ¨ 0 ~ 6 ç¹ 77 var hours = new Date().getHours(); 78 if (hours >= 18 || (hours >= 0 && hours <= 6)) { 79 return 'dark'; 80 } 81 return 'light'; 82 } 83 84 function applyCustomColorSchemaSettings(schema) { 85 // æ¥åä»ãå¼å ³ãå¤ä¼ æ¥ç模å¼ï¼æè ä» localStorage 读åï¼å¦åæé»è®¤è®¾ç½®å¼ 86 var current = schema || getLS(colorSchemaStorageKey) || getDefaultColorSchema(); 87 88 if (current === getDefaultColorSchema()) { 89 // å½ç¨æ·åæ¢çæ¾ç¤ºæ¨¡å¼åé»è®¤æ¨¡å¼ç¸åæ¶ï¼åæ¢å¤ä¸ºèªå¨æ¨¡å¼ 90 resetSchemaAttributeAndLS(); 91 } else if (validColorSchemaKeys[current]) { 92 rootElement.setAttribute( 93 userColorSchemaAttributeName, 94 current 95 ); 96 } else { 97 // ç¹æ®æ åµéç½® 98 resetSchemaAttributeAndLS(); 99 return; 100 } 101 102 // æ ¹æ®å½å模å¼è®¾ç½®å¾æ 103 setButtonIcon(current); 104 105 // 设置代ç é«äº® 106 setHighlightCSS(current); 107 108 // è®¾ç½®å ¶ä»åºç¨ 109 setApplications(current); 110 } 111 112 var invertColorSchemaObj = { 113 dark : 'light', 114 light: 'dark' 115 }; 116 117 function getIconClass(scheme) { 118 return 'icon-' + scheme; 119 } 120 121 function toggleCustomColorSchema() { 122 var currentSetting = getLS(colorSchemaStorageKey); 123 124 if (validColorSchemaKeys[currentSetting]) { 125 // ä» localStorage ä¸è¯»å模å¼ï¼å¹¶åç¸åçæ¨¡å¼ 126 currentSetting = invertColorSchemaObj[currentSetting]; 127 } else if (currentSetting === null) { 128 // å½ localStorage 䏿²¡æç¸å ³å¼ï¼æè localStorage æäº Error 129 // å æç §æé®çç¶æè¿è¡åæ¢ 130 var iconElement = document.querySelector(colorToggleIconSelector); 131 if (iconElement) { 132 currentSetting = iconElement.getAttribute('data'); 133 } 134 if (!iconElement || !validColorSchemaKeys[currentSetting]) { 135 // å½ localStorage 䏿²¡æç¸å ³å¼ï¼æè localStorage æäº Errorï¼å读åé»è®¤å¼å¹¶åæ¢å°ç¸åçæ¨¡å¼ 136 currentSetting = invertColorSchemaObj[getSchemaFromCSSMediaQuery()]; 137 } 138 } else { 139 return; 140 } 141 // å°ç¸åçæ¨¡å¼åå ¥ localStorage 142 setLS(colorSchemaStorageKey, currentSetting); 143 144 return currentSetting; 145 } 146 147 function setButtonIcon(schema) { 148 if (validColorSchemaKeys[schema]) { 149 // 忢徿 150 var icon = getIconClass('dark'); 151 if (schema) { 152 icon = getIconClass(schema); 153 } 154 var iconElement = document.querySelector(colorToggleIconSelector); 155 if (iconElement) { 156 iconElement.setAttribute( 157 'class', 158 'iconfont ' + icon 159 ); 160 iconElement.setAttribute( 161 'data', 162 invertColorSchemaObj[schema] 163 ); 164 } else { 165 // 妿徿 ä¸åå¨å说æå¾æ è¿æ²¡å è½½åºæ¥ï¼çå°é¡µé¢å ¨é¨å è½½åå°è¯åæ¢ 166 Fluid.utils.waitElementLoaded(colorToggleIconSelector, function() { 167 var iconElement = document.querySelector(colorToggleIconSelector); 168 if (iconElement) { 169 iconElement.setAttribute( 170 'class', 171 'iconfont ' + icon 172 ); 173 iconElement.setAttribute( 174 'data', 175 invertColorSchemaObj[schema] 176 ); 177 } 178 }); 179 } 180 if (document.documentElement.getAttribute('data-user-color-scheme')) { 181 var color = getComputedStyle(document.documentElement).getPropertyValue('--navbar-bg-color').trim() 182 document.querySelector('meta[name="theme-color"]').setAttribute('content', color) 183 } 184 } 185 } 186 187 function setHighlightCSS(schema) { 188 // å¯ç¨å¯¹åºç代ç é«äº®çæ ·å¼ 189 var lightCss = document.getElementById('highlight-css'); 190 var darkCss = document.getElementById('highlight-css-dark'); 191 if (schema === 'dark') { 192 if (darkCss) { 193 darkCss.removeAttribute('disabled'); 194 } 195 if (lightCss) { 196 lightCss.setAttribute('disabled', ''); 197 } 198 } else { 199 if (lightCss) { 200 lightCss.removeAttribute('disabled'); 201 } 202 if (darkCss) { 203 darkCss.setAttribute('disabled', ''); 204 } 205 } 206 207 setTimeout(function() { 208 // 设置代ç åç»ä»¶æ ·å¼ 209 document.querySelectorAll('.markdown-body pre').forEach((pre) => {
210 var cls = Fluid.utils.getBackgroundLightness(pre) >= 0 ? 'code-widget-light' : 'code-widget-dark'; 211 var widget = pre.querySelector('.code-widget-light, .code-widget-dark'); 212 if (widget) { 213 widget.classList.remove('code-widget-light', 'code-widget-dark'); 214 widget.classList.add(cls); 215 } 216 }); 217 }, 200); 218 } 219 220 function setApplications(schema) { 221 // 设置 remark42 è¯è®ºä¸»é¢ 222 if (window.REMARK42) { 223 window.REMARK42.changeTheme(schema); 224 } 225 226 // 设置 cusdis è¯è®ºä¸»é¢ 227 if (window.CUSDIS) { 228 window.CUSDIS.setTheme(schema); 229 } 230 231 // 设置 utterances è¯è®ºä¸»é¢ 232 var utterances = document.querySelector('.utterances-frame'); 233 if (utterances) { 234 var utterancesTheme = schema === 'dark' ? window.UtterancesThemeDark : window.UtterancesThemeLight; 235 const message = { 236 type : 'set-theme', 237 theme: utterancesTheme 238 }; 239 utterances.contentWindow.postMessage(message, 'https://utteranc.es'); 240 } 241 242 // 设置 giscus è¯è®ºä¸»é¢ 243 var giscus = document.querySelector('iframe.giscus-frame'); 244 if (giscus) { 245 var giscusTheme = schema === 'dark' ? window.GiscusThemeDark : window.GiscusThemeLight; 246 const message = { 247 setConfig: { 248 theme: giscusTheme, 249 } 250 }; 251 // giscus.style.cssText += 'color-scheme: normal;'; 252 giscus.contentWindow.postMessage({ 'giscus': message }, 'https://giscus.app'); 253 } 254 } 255 256 // å½é¡µé¢å è½½æ¶ï¼å°æ¾ç¤ºæ¨¡å¼è®¾ç½®ä¸º localStorage ä¸èªå®ä¹çå¼ï¼å¦ææçè¯ï¼ 257 applyCustomColorSchemaSettings(); 258 259 Fluid.utils.waitElementLoaded(colorToggleIconSelector, function() { 260 applyCustomColorSchemaSettings(); 261 var button = document.querySelector(colorToggleButtonSelector); 262 if (button) { 263 // å½ç¨æ·ç¹å»åæ¢æé®æ¶ï¼è·å¾æ°çæ¾ç¤ºæ¨¡å¼ãåå ¥ localStorageãå¹¶å¨é¡µé¢ä¸çæ 264 button.addEventListener('click', function() { 265 applyCustomColorSchemaSettings(toggleCustomColorSchema()); 266 }); 267 var icon = document.querySelector(colorToggleIconSelector); 268 if (icon) { 269 // å æ æ¬å卿é®ä¸æ¶ï¼åæ¢å¾æ 270 button.addEventListener('mouseenter', function() { 271 var current = icon.getAttribute('data'); 272 icon.classList.replace(getIconClass(invertColorSchemaObj[current]), getIconClass(current)); 273 }); 274 button.addEventListener('mouseleave', function() { 275 var current = icon.getAttribute('data'); 276 icon.classList.replace(getIconClass(current), getIconClass(invertColorSchemaObj[current])); 277 }); 278 } 279 } 280 }); 281 282 Fluid.utils.waitElementLoaded(iframeSelector, function() { 283 applyCustomColorSchemaSettings(); 284 }); 285 286})(window, document);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.