White background replacer

Replaces the background white color with a darker one in order to decrease eye strain

目前为 2024-02-23 提交的版本。查看 最新版本

'use strict';
// ==UserScript==
// @name         White background replacer
// @namespace    http://siavoshkc.com/
// @version      2.16
// @description  Replaces the background white color with a darker one in order to decrease eye strain
// @author       siavoshkc
// @match        *://*/*
// @grant        none
// @license      MIT
// @run-at       document-idle
// ==/UserScript==

const INTERVAL = 120000
const goodBgColors = ["#b0edc4", "#79d2a6", "#8EC4C6", "#79C664", "#79AC78","#74B6C0","#A19C6D", "#61B6A1", "#66C0A9",
                      "#7BA699", "#5E8784", "#71979E", "#4E8B57", "#7D8E92","#AF9D9D", "#95BBBB", "#7FB397", "#87B8A8",
                      "#D9BD7F", "#BDA279", "#A3AA70", "#9095A1", "#7CA870", "#8EB157,", "#7B765A", "#809582", "#7DA16F"]
const knownVarNames = ['--bg', '--bg-color', '--background-color', '--background', '--theme-content-background-color', '--lighting-color'
                       , '--theme-background-color', '--theme-content-background-color', '--background-color-base', '--color-neutral-000'
                       , '--custom-select-bg-color']

var currentGoodBgColor = 0

function isWhite(bg) {
    const rgba = bg.match(/[0-9]+/g);
    const hsl = bg.match(/hsl\(\s*(\d+)\s*,\s*(\d+(?:\.\d+)?%)\s*,\s*(\d+(?:\.\d+)?%)\)/)
    const hsla = bg.match(/hsla\(\s*(\d+)\s*,\s*(\d+(?:\.\d+)?%)\s*,\s*(\d+(?:\.\d+)?%)\s*,\s*((\.\d+)|1)\)/)
    bg = bg.toLowerCase()
    hsl && console.log('hsl>>>>>', hsl)
    return (
        bg == "white"||
        bg == "#ffffff"||
        bg == "#fff"||
        bg == "#fdfdfd" ||
        (hsl && Number(hsl[2].replace('%','')) > 89) ||
        (hsla && (Number(hsl[2].replace('%','')) > 89) && Number(hsl[3] > .9)) ||
        (rgba && ((rgba[0] > 230 && rgba[1] > 230 && rgba[2] >230) || rgba[3] == 0))
    )
}

function changeColor(style) {
    //console.debug("White background replacer: Trying to change background color ", style.backgroundColor)
    style.backgroundColor = goodBgColors[currentGoodBgColor % goodBgColors.length] + 'AF'
    //console.debug("White background replacer: Changing one style background-color to ", goodBgColors[currentGoodBgColor % goodBgColors.length])
    if(style.color == style.backgroundColor) style.color = "black"
    if(currentGoodBgColor === Number.MAX_SAFE_INTEGER) currentGoodBgColor = 0
    else currentGoodBgColor++
    setTimeout(changeColor, INTERVAL, style)
}

function iterateRules(cssRules) {
    if(!cssRules) return

    for (let rule of cssRules) {
        try {
            if(checkStyle(rule?.style)){
                changeColor(rule?.style)
            }
            iterateRules(rule.cssRules)
        } catch(e) {
            console.warn("WBR: Caught exception: ", e)
        }
    }
}

function checkStyle(style) {
    if(!style) return
    return (
        isWhite(style.background) ||
        isWhite(style.backgroundColor) ||
        knownVarNames.filter(v => isWhite(style.getPropertyValue(v)))
    )
}

function checkPage() {
    //var elems = document.body.getElementsByTagName("*");
    //for (const el of elems) el.removeAttribute("style")
    //console.debug("White background replacer: Running...", window.getComputedStyle(document.documentElement));
    if(checkStyle(window.getComputedStyle(document.documentElement))){
        console.debug("Global background detected")
        try {
            const all = document.styleSheets,
                s = all[all.length - 1],
                l = s?.cssRules?.length || 0;
            if (s?.insertRule) {
                s.insertRule('body {background-color: DarkKhaki !important}', l)
                console.debug("Global rule inserted")
            }
        } catch(e) {
            console.debug("WBR: Global change using new stylesheet failed. Appending element...: ", e)
            const s = document.createElement('style');
            s.innerHTML = 'body {background-color: Tan !important;}';
            document.body.appendChild(s);
            console.debug("Global element appended")
        }
    }
    if(document.styleSheets?.length > 0) {
        for (let sheet of document.styleSheets) {
            iterateRules(sheet.cssRules)
        }
    }

}
checkPage()