您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Depends on "light" theme being the default one in f-list. Adds two buttons to TamperMonkey menu itself to switch and auto-detect light/dark.
// ==UserScript== // @name F-list inverted color theme with auto-detection. // @license MIT // @namespace https://www.f-list.net // @version 2025-02-24 // @description Depends on "light" theme being the default one in f-list. Adds two buttons to TamperMonkey menu itself to switch and auto-detect light/dark. // @author Me // @match https://www.f-list.net/* // @icon https://www.google.com/s2/favicons?sz=64&domain=f-list.net // @require https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js // @grant GM_registerMenuCommand // @grant GM_unregisterMenuCommand // @grant GM_addStyle // @grant GM_setValue // @grant GM_getValue // ==/UserScript== (function() { 'use strict'; // CSS overrides. Note: the colors here are the inverse of what you want. const cssCustomDarkOverrides = ` /* core changes - hue is for a more pleasant shade of background-image elements. */ html { filter: invert(1) hue-rotate(180deg); } /* invert images again to return them to the original color and hue */ .inverted-img { filter: invert(1) hue-rotate(180deg); } /* special cases where the core changes above don't work well */ .messages-both .message-ad { background-color: #ccd !important; } .ads-text-box, .ads-text-box:focus { background-color: #ccd !important; } `; // For auto-detection. const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); // Current dark mode state and mutation observer reference. let isDarkModeEnabled = false; let observer = null; // Saved dark mode states. const DarkModeStates = Object.freeze({ AUTO: "auto", MANUAL_ON: "manual_on", MANUAL_OFF: "manual_off" }); let darkModeState = GM_getValue('darkModeState', DarkModeStates.MANUAL_OFF); // Hold the menu command IDs so we can update their labels. let darkModeCommandId; let autoDetectCommandId; // Insert custom CSS overrides using jQuery. function enableCustomOverrides() { if ($('#customOverridesStyle').length === 0) { const $styleEl = $('<style>', { id: 'customOverridesStyle', type: 'text/css' }).text(cssCustomDarkOverrides); $('head').append($styleEl); } } // Remove custom CSS overrides. function disableCustomOverrides() { $('#customOverridesStyle').remove(); } // Update GM menu commands with dynamic text based on current state. function updateMenuCommands() { if (typeof GM_unregisterMenuCommand === 'function') { if (darkModeCommandId) { GM_unregisterMenuCommand(darkModeCommandId); } if (autoDetectCommandId) { GM_unregisterMenuCommand(autoDetectCommandId); } } darkModeCommandId = GM_registerMenuCommand( darkModeState === DarkModeStates.MANUAL_ON ? "Disable Dark Mode" : "Enable Dark Mode", toggleDarkMode ); autoDetectCommandId = GM_registerMenuCommand( darkModeState === DarkModeStates.AUTO ? "Disable Auto-Detection" : "Enable Auto-Detection", toggleAutoDetection ); } // Use jQuery to add the inverted class to images, picture, and video elements. function addInvertedClassToNode(node) { const $node = $(node); if ($node.is('img, picture, video') && !$node.hasClass('inverted-img')) { $node.addClass('inverted-img'); } $node.find('img, picture, video').not('.inverted-img').addClass('inverted-img'); } // Enable dark mode: add custom CSS and observe the DOM for new elements. function enableDarkMode() { enableCustomOverrides(); observer = new MutationObserver(mutations => { mutations.forEach(mutation => { mutation.addedNodes.forEach(node => { if (node.nodeType === Node.ELEMENT_NODE) { addInvertedClassToNode(node); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); $('img, picture, video').not('.inverted-img').addClass('inverted-img'); isDarkModeEnabled = true; } // Disable dark mode: remove custom CSS and stop DOM observation. function disableDarkMode() { disableCustomOverrides(); if (observer) { observer.disconnect(); observer = null; } $('img, picture, video').removeClass('inverted-img'); isDarkModeEnabled = false; } // Toggle dark mode manually. function toggleDarkMode() { if (isDarkModeEnabled) { darkModeState = DarkModeStates.MANUAL_OFF; disableDarkMode(); } else { darkModeState = DarkModeStates.MANUAL_ON; enableDarkMode(); } GM_setValue('darkModeState', darkModeState); updateMenuCommands(); } // When system dark mode preference changes. function handleColorSchemeChange(event) { console.log(`Browser changed its preference. Should we use dark mode now? ${event.matches}`); event.matches ? enableDarkMode() : disableDarkMode(); } // Update media query listener safely. function updateMediaQueryListener() { darkModeMediaQuery.removeEventListener('change', handleColorSchemeChange); if (darkModeState === DarkModeStates.AUTO) { darkModeMediaQuery.addEventListener('change', handleColorSchemeChange); } } // Apply auto-detection or manual override. function autoDetectNow() { updateMediaQueryListener(); if (darkModeState === DarkModeStates.AUTO) { console.log(`Autodetection active; system preference is dark? ${darkModeMediaQuery.matches}`); darkModeMediaQuery.matches ? enableDarkMode() : disableDarkMode(); } else { const manualOn = (darkModeState === DarkModeStates.MANUAL_ON); console.log(`Autodetection disabled. Manual override? ${manualOn}`); manualOn ? enableDarkMode() : disableDarkMode(); } } // Toggle auto-detection. function toggleAutoDetection() { darkModeState = darkModeState === DarkModeStates.AUTO ? DarkModeStates.MANUAL_OFF : DarkModeStates.AUTO; GM_setValue('darkModeState', darkModeState); autoDetectNow(); updateMenuCommands(); } // Initialize. autoDetectNow(); updateMenuCommands(); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址