Universal Dark Theme Maker

Simple Dark Theme style for any website which you can configure per-site

当前为 2022-11-23 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Universal Dark Theme Maker
  3. // @namespace uni_dark_theme
  4. // @version 1.18
  5. // @description Simple Dark Theme style for any website which you can configure per-site
  6. // @supportURL https://github.com/Owyn/Universal_Dark_Theme/issues
  7. // @homepage https://github.com/Owyn/Universal_Dark_Theme
  8. // @icon https://images2.imgbox.com/b3/67/Aq5XazuW_o.png
  9. // @author Owyn
  10. // @match *://*/*
  11. // @grant GM_getValue
  12. // @grant GM_setValue
  13. // @grant GM_registerMenuCommand
  14. // @grant unsafeWindow
  15. // @sandbox JavaScript
  16. // @run-at document-start
  17. // ==/UserScript==
  18.  
  19. (function() {
  20. 'use strict';
  21.  
  22. var el;
  23. var css;
  24. var cfg_color;
  25. var cfg_bgclr;
  26. var cfg_bgimg;
  27. var cfg_visclr;
  28. var cfg_excl;
  29. var cfg_css;
  30. var cfg_js;
  31. var cfg_active;
  32. switch(localStorage.getItem('active'))
  33. {
  34. case "true": // back-compatibility
  35. case "1":
  36. cfg_active = true;
  37. break;
  38. default:
  39. cfg_active = false;
  40. break;
  41. }
  42. function load_settings()
  43. {
  44. cfg_excl = localStorage.getItem('excl') || "";
  45. cfg_css = localStorage.getItem('css') || "";
  46. cfg_js = localStorage.getItem('js') || "";
  47. cfg_bgimg = (localStorage.getItem('bgimg') === '1');
  48. if (typeof GM_getValue !== "undefined")
  49. {
  50. cfg_color = GM_getValue("Color", "#c0c0c0");
  51. cfg_bgclr = GM_getValue("bgColor", "#2e2e2e");
  52. cfg_visclr = GM_getValue("visitedColor", "#a4a4a4");
  53. }
  54. }
  55.  
  56. function activate(yes, prev_active)
  57. {
  58. if(prev_active && el){document.documentElement.removeChild(el);}
  59. if(yes)
  60. {
  61. make_css();
  62. el = addStyle(css);
  63. if(cfg_js){eval(cfg_js);}
  64. }
  65. }
  66. function toggleDT()
  67. {
  68. load_settings();
  69. cfg_active = !cfg_active;
  70. activate(cfg_active, !cfg_active);
  71. if(!cfg_active)
  72. {
  73. localStorage.removeItem('active');
  74. }
  75. else
  76. {
  77. localStorage.setItem('active', "1");
  78. }
  79. }
  80.  
  81. if (typeof GM_registerMenuCommand !== "undefined")
  82. {
  83. GM_registerMenuCommand("Dark Theme Configuration", cfg, "D");
  84. GM_registerMenuCommand("Toggle Dark Theme", toggleDT, "T");
  85. }
  86.  
  87. function make_css()
  88. {
  89. let exclusions;
  90. let exc_txt = ""
  91. if(cfg_excl !== "")
  92. {
  93. exclusions = cfg_excl.split(",");
  94. for (var i = 0, len = exclusions.length; i < len; i++)
  95. {
  96. exc_txt += ":not("+exclusions[i]+")";
  97. }
  98. }
  99. let bgimg_txt = cfg_bgimg ? "-color" : "";
  100. ////////////// Main thing, the style!:
  101. css = `
  102. *`+exc_txt+` {
  103. color: `+cfg_color+` !important;
  104. background`+bgimg_txt+`: `+cfg_bgclr+` !important;
  105. border-color: `+cfg_color+` !important;
  106. color-scheme: dark;
  107. }
  108. :visited`+exc_txt+`, a:hover`+exc_txt+` {
  109. color: `+cfg_visclr+` !important;
  110. }
  111. input:focus,textarea:focus,select:focus`+exc_txt+`{
  112. outline: 1px solid `+cfg_visclr+` !important;
  113. }
  114. `+cfg_css+`
  115. `;
  116. //////////////
  117. }
  118.  
  119. function addStyle (aCss)
  120. {
  121. let style = document.createElement('style');
  122. style.setAttribute('type', 'text/css');
  123. style.textContent = aCss;
  124. document.documentElement.appendChild(style);
  125. return style;
  126. };
  127.  
  128. if(cfg_active)
  129. {
  130. console.info("adding dark style...");
  131. load_settings();
  132. make_css();
  133. el = addStyle(css);
  134. console.info(unsafeWindow);
  135. console.info(el);
  136. window.addEventListener("DOMContentLoaded", function(){ el = document.documentElement.appendChild(el); if(cfg_js){eval(cfg_js);} }); // make sure style element is at the bottom & execute custom JS
  137. }
  138.  
  139. var t;
  140. function cfg()
  141. {
  142. if (typeof GM_setValue !== "undefined")
  143. {
  144. function saveCfg()
  145. {
  146. GM_setValue("Color", document.getElementById("color").value);
  147. GM_setValue("bgColor", document.getElementById("bgclr").value);
  148. GM_setValue("visitedColor", document.getElementById("visitedColor").value);
  149. localStorage.setItem('excl', document.getElementById("excl").value);
  150. localStorage.setItem('css', document.getElementById("css").value);
  151. localStorage.setItem('js', document.getElementById("js").value);
  152. localStorage.setItem('active', document.getElementById("active").checked ? "1" : "0");
  153. localStorage.setItem('bgimg', document.getElementById("bgimg").checked ? "1" : "0");
  154. // pretty text "saved"
  155. document.getElementById("cfg_save").value = "SAVED !";
  156. clearTimeout(t);
  157. t = setTimeout(function() {document.getElementById("cfg_save").value = "Save configuration";},1500)
  158. // update active configuration
  159. cfg_color = document.getElementById("color").value;
  160. cfg_bgclr = document.getElementById("bgclr").value;
  161. cfg_bgimg = document.getElementById("bgimg").checked;
  162. cfg_visclr = document.getElementById("visitedColor").value;
  163. cfg_excl = document.getElementById("excl").value;
  164. cfg_css = document.getElementById("css").value;
  165. cfg_js = document.getElementById("js").value;
  166. activate(document.getElementById("active").checked, cfg_active );
  167. cfg_active = document.getElementById("active").checked;
  168. // clean up
  169. if(!document.getElementById("active").checked) { localStorage.removeItem('active'); }
  170. if(!document.getElementById("bgimg").checked) { localStorage.removeItem('bgimg'); }
  171. if(!document.getElementById("excl").value) { localStorage.removeItem('excl'); }
  172. if(!document.getElementById("css").value) { localStorage.removeItem('css'); }
  173. if(!document.getElementById("js").value) { localStorage.removeItem('js'); }
  174. }
  175. load_settings();
  176. var div = document.createElement("div");
  177. div.style = "margin: auto; width: fit-content; height: fit-content; border: 1px solid black; color: "+cfg_color+"; background: "+cfg_bgclr+"; position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 8888888; line-height: 1;";
  178. div.innerHTML = "<b><br><center>Configuration</center></b>"
  179. + "<div style='margin: auto; display: table;'><br><input id='color' type='text' size='7' style='display:inline; color: "+cfg_color+"; background-color: "+cfg_bgclr+"; width:initial; padding: initial; margin: initial;'> Text color (empty = site default)"
  180. + "<br><br><input id='bgclr' type='text' size='7' style='display:inline; color: "+cfg_color+"; background-color: "+cfg_bgclr+"; width:initial; padding: initial; margin: initial;'> Background color"
  181. + "<br><br><input id='visitedColor' type='text' size='7' style='display:inline; color: "+cfg_color+"; background-color: "+cfg_bgclr+"; width:initial; padding: initial; margin: initial;'> <span style=\"color: "+cfg_visclr+" !important\">Visited & hovered links color</span>"
  182. + "<br><br></div><center><b>Per-site settings (stored in browser cookies called LocalStorage):</b>"
  183. + "<br><br><input id='active' type='checkbox' style='display:inline; width:initial; padding: initial; margin: initial;'> Enabled for this website"
  184. + "<br><br><input id='bgimg' type='checkbox' style='display:inline; width:initial; padding: initial; margin: initial;'> Keep background-images"
  185. + "<br><br>Excluded css elements (e.g. \"#id1,.class2,input\"):<br><textarea id='excl' style='margin: 0px; width: 400px; height: 50px; resize:both; color: "+cfg_color+"; background-color: "+cfg_bgclr+"; display:inline; padding: initial; margin: initial;'></textarea>"
  186. + "<br><br>Custom CSS style:<br><textarea id='css' style='margin: 0px; width: 400px; height: 50px; resize:both; color: "+cfg_color+"; background-color: "+cfg_bgclr+"; display:inline; padding: initial; margin: initial;'></textarea>"
  187. + "<br><br>Custom JS Action:<br><textarea id='js' style='margin: 0px; width: 400px; height: 50px; resize:both; color: "+cfg_color+"; background-color: "+cfg_bgclr+"; display:inline; padding: initial; margin: initial;'></textarea>"
  188. + "<br><input id='cfg_save' type='button' value='Save configuration' style='display:inline; color: "+cfg_color+"; background-color: "+cfg_bgclr+"; width:initial; padding: initial; margin: initial;'> <input id='cfg_close' type='button' value='Close' style='display:inline; color: "+cfg_color+"; background-color: "+cfg_bgclr+"; width:initial; padding: initial; margin: initial;'></center>";
  189. document.body.appendChild(div);
  190. document.getElementById("color").value = cfg_color;
  191. document.getElementById("bgclr").value = cfg_bgclr;
  192. document.getElementById("bgimg").checked = cfg_bgimg;
  193. document.getElementById("visitedColor").value = cfg_visclr;
  194. //
  195. document.getElementById("active").checked = cfg_active;
  196. document.getElementById("excl").value = cfg_excl;
  197. document.getElementById("css").value = cfg_css;
  198. document.getElementById("js").value = cfg_js;
  199. document.getElementById("cfg_save").addEventListener("click", saveCfg, true);
  200. document.getElementById("cfg_close").addEventListener("click", function(){div.remove();clearTimeout(t);}, true);
  201. }
  202. else
  203. {
  204. alert("Sorry, Chrome userscripts in native mode can't have configurations! Install TamperMonkey userscript-manager extension");
  205. }
  206. }
  207.  
  208. })();