Ultimate Night Mode

Change websites to pure black background with customization options

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Ultimate Night Mode
// @namespace    (link unavailable)
// @version      0.13
// @description  Change websites to pure black background with customization options
// @match        *://*/*
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_registerMenuCommand
// @run-at       document-start
// ==/UserScript==

(function () {
  'use strict';

  // Load settings
  const cfg = {
    bgColor: GM_getValue("bgColor", "#000000"),
    textColor: GM_getValue("textColor", "#D3D3D3"), // Light Gray
    linkColor: GM_getValue("linkColor", "#1E90FF"), // Bright Blue
    visitedLinkColor: GM_getValue("visitedLinkColor", "#551A8B"), // Purple
    imgBrightness: GM_getValue("imgBrightness", 0.8),
    imgContrast: GM_getValue("imgContrast", 1.2),
    bgTransparency: GM_getValue("bgTransparency", 1),
    disableAllExceptBg: GM_getValue("disableAllExceptBg", false) // New option to disable all except background color
  };

  // CSS styles
  const css = `
    html, body {
      background-color: ${hexToRgba(cfg.bgColor, cfg.bgTransparency)} !important;
      ${cfg.disableAllExceptBg ? '' : `color: ${cfg.textColor} !important;`}
    }
    ${cfg.disableAllExceptBg ? '' : `
      * {
        background-color: rgba(0, 0, 0, 0.5) !important;
        border-color: #444444 !important;
      }
      a {
        color: ${cfg.linkColor} !important;
      }
      a:visited {
        color: ${cfg.visitedLinkColor} !important;
      }
      img.content-image {
        filter: brightness(${cfg.imgBrightness}) contrast(${cfg.imgContrast});
      }
      video, .html5-video-container video {
        filter: none !important;
      }
    `}
  `;

  // Apply styles
  const style = document.createElement('style');
  style.type = 'text/css';
  style.appendChild(document.createTextNode(css));
  document.head.appendChild(style);

  // Mutation observer to handle dynamic content
  const observer = new MutationObserver(function () {
    document.documentElement.style.backgroundColor = hexToRgba(cfg.bgColor, cfg.bgTransparency);
    document.body.style.backgroundColor = hexToRgba(cfg.bgColor, cfg.bgTransparency);
  });

  // Limit the observer to the body to avoid performance issues
  observer.observe(document.body, { childList: true, subtree: true });

  // Create configuration window
  function openConfigWindow() {
    const div = document.createElement('div');
    div.style.position = 'fixed';
    div.style.top = '10%';
    div.style.left = '50%';
    div.style.transform = 'translateX(-50%)';
    div.style.backgroundColor = '#333';
    div.style.color = '#fff';
    div.style.padding = '20px';
    div.style.border = '1px solid #444';
    div.style.zIndex = '10000';
    div.innerHTML = `
      <h2>Customize Theme</h2>
      <label>BG Color: <input type="color" id="bgColor" value="${cfg.bgColor}"></label><br>
      <label>Text: <input type="color" id="textColor" value="${cfg.textColor}"></label><br>
      <label>Link: <input type="color" id="linkColor" value="${cfg.linkColor}"></label><br>
      <label>Visited: <input type="color" id="visitedLinkColor" value="${cfg.visitedLinkColor}"></label><br>
      <label>Brightness: <input type="range" id="imgBrightness" min="0" max="1" step="0.1" value="${cfg.imgBrightness}"></label><br>
      <label>Contrast: <input type="range" id="imgContrast" min="1" max="2" step="0.1" value="${cfg.imgContrast}"></label><br>
      <label>Transparency: <input type="range" id="bgTransparency" min="0" max="1" step="0.1" value="${cfg.bgTransparency}"></label><br>
      <label>Disable All Except BG Color: <input type="checkbox" id="disableAllExceptBg" ${cfg.disableAllExceptBg ? 'checked' : ''}></label><br>
      <button id="saveConfig">Save</button>
      <button id="closeConfig">Close</button>
    `;
    document.body.appendChild(div);

    // Save configuration
    document.getElementById('saveConfig').addEventListener('click', () => {
      GM_setValue("bgColor", document.getElementById('bgColor').value);
      GM_setValue("textColor", document.getElementById('textColor').value);
      GM_setValue("linkColor", document.getElementById('linkColor').value);
      GM_setValue("visitedLinkColor", document.getElementById('visitedLinkColor').value);
      GM_setValue("imgBrightness", parseFloat(document.getElementById('imgBrightness').value));
      GM_setValue("imgContrast", parseFloat(document.getElementById('imgContrast').value));
      GM_setValue("bgTransparency", parseFloat(document.getElementById('bgTransparency').value));
      GM_setValue("disableAllExceptBg", document.getElementById('disableAllExceptBg').checked);
      location.reload();
    });

    document.getElementById('closeConfig').addEventListener('click', () => {
      div.remove();
    });
  }

  // Convert hex to rgba
  function hexToRgba(hex, alpha) {
    let r = 0, g = 0, b = 0;
    if (hex.length === 4) {
      r = parseInt(hex[1] + hex[1], 16);
      g = parseInt(hex[2] + hex[2], 16);
      b = parseInt(hex[3] + hex[3], 16);
    } else if (hex.length === 7) {
      r = parseInt(hex.slice(1, 3), 16);
      g = parseInt(hex.slice(3, 5), 16);
      b = parseInt(hex.slice(5, 7), 16);
    }
    return `rgba(${r},${g},${b},${alpha})`;
  }

  // Menu command to open configuration window
  if (typeof GM_registerMenuCommand !== "undefined") {
    GM_registerMenuCommand("Customize Theme", openConfigWindow, "C");
  }
})();