Wikipedia - Keep style preferences in incognito

Immediately apply the user's style preferences in incognito sessions, for a seamless experience, without needing to manually set them every time.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Wikipedia - Keep style preferences in incognito
// @version      2025-02-04.3
// @description  Immediately apply the user's style preferences in incognito sessions, for a seamless experience, without needing to manually set them every time.
// @author       jackiechan285
// @match        https://*.wikipedia.org/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=wikipedia.org
// @grant        GM_cookie
// @namespace    https://greasyfork.org/en/scripts/525906-wikipedia-keep-style-preferences-in-incognito
// ==/UserScript==

/*
When you open Wikipedia in incognito, you have to manually set the styles to your preferences all over again, which may be annoying if done multiple times.

This script does it automatically, instantly, at first run, with no reload required.

It directly changes the cookie responsible for the style preferences and changes the style preference classes to apply them immediately because the changes to the cookie only take effect after reloading.

The cookies are necessary because the class changes alone do not get saved.

This is done only once per session, so it won't affect performance or be redundant. It also allows the user to change the preferences further on, and they won't be overwritten.

It sets a flag on localStorage to indicate the cookie has already been overwritten, to ensure it's only done once per session
*/

(function() {
    'use strict';

    // Get the language subdomain dynamically
    const langSubdomain = window.location.hostname.split('.')[0];
    const cookieName = `${langSubdomain}wikimwclientpreferences`;

    // Check if the script has already run in this session
    if (localStorage.getItem('cookieModified') === 'true') {
        return; // Exit if already modified
    }

    const newCookieValue = "skin-theme-clientpref-night%2Cvector-feature-limited-width-clientpref-0%2Cvector-feature-custom-font-size-clientpref-0%2Cvector-feature-appearance-pinned-clientpref-0";

    // Check if the cookie exists
    GM_cookie.list({ name: cookieName }, function(cookies, error) {
        if (error) {
            console.error('Error retrieving cookies:', error);
            return;
        }

        if (!cookies || cookies.length === 0) {
            console.log(`Cookie ${cookieName} does not exist. Creating it.`);
        } else {
            console.log(`Cookie ${cookieName} exists. Updating it.`);
        }

        // Set or update the cookie
        GM_cookie.set({
            name: cookieName,
            value: newCookieValue,
            path: '/',
            secure: true,
            expirationDate: Math.floor(Date.now() / 1000) + (60 * 60 * 24) // Expires in 1 day
        }, function(error) {
            if (error) {
                console.error('Error setting cookie:', error);
            } else {
                console.log(`Cookie ${cookieName} set successfully.`);
            }
        });

        // Set a flag in localStorage to indicate the script has run
        localStorage.setItem('cookieModified', 'true');
    });

    // Replace specific classes in HTML elements
    const replaceClasses = () => {
        const elements = document.querySelectorAll('*');
        elements.forEach((element) => {
            element.classList.forEach((className) => {
                if (className.includes('vector-feature-limited-width-clientpref-')) {
                    element.classList.replace(className, 'vector-feature-limited-width-clientpref-0');
                }
                if (className.includes('vector-feature-custom-font-size-clientpref-')) {
                    element.classList.replace(className, 'vector-feature-custom-font-size-clientpref-0');
                }
                if (className.includes('skin-theme-clientpref-')) {
                    element.classList.replace(className, 'skin-theme-clientpref-night');
                }
                if (className.includes('vector-feature-appearance-pinned-clientpref-')) {
                    element.classList.replace(className, 'vector-feature-appearance-pinned-clientpref-0');
                }
            });
        });
    };

    // Run the class replacement
    replaceClasses();
})();