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