Force Aptos Font with Whitelist

Forces websites to use the Aptos font family, with a customizable whitelist of sites to exclude.

当前为 2025-06-17 提交的版本,查看 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Force Aptos Font with Whitelist
// @namespace    http://tampermonkey.net/
// @version      1.2
// @description  Forces websites to use the Aptos font family, with a customizable whitelist of sites to exclude.
// @author       Your Name/AI (Update with your actual name/handle)
// @match        *://*/*
// @grant        GM_addStyle
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_registerMenuCommand
// @run-at       document-start
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    const SCRIPT_NAME = "Force Aptos Font";
    const WHITELIST_KEY = 'aptosFontWhitelist_v1'; // Added version to key in case of future structure changes

    // Comprehensive Aptos font stack
    const APTOS_FONT_FAMILY = `"Aptos", "Aptos Display", "Aptos Narrow", "Aptos Serif", "Aptos Mono", "Segoe UI Variable Text", "Segoe UI Variable Display", "Segoe UI Variable Small", "Segoe UI", Tahoma, Geneva, Verdana, sans-serif`;

    function loadWhitelist() {
        const storedValue = GM_getValue(WHITELIST_KEY, '[]');
        try {
            const parsed = JSON.parse(storedValue);
            return Array.isArray(parsed) ? parsed : [];
        } catch (e) {
            console.error(`${SCRIPT_NAME}: Error parsing whitelist, resetting. Stored value:`, storedValue, e);
            // If parsing fails, return an empty array to prevent further errors
            // and allow the user to rebuild the whitelist.
            return [];
        }
    }

    function saveWhitelist(whitelist) {
        if (!Array.isArray(whitelist)) {
            console.error(`${SCRIPT_NAME}: Attempted to save invalid whitelist type.`);
            return;
        }
        GM_setValue(WHITELIST_KEY, JSON.stringify(whitelist.map(site => site.trim().toLowerCase()).filter(site => site.length > 0)));
    }

    function isSiteWhitelisted(hostname) {
        const whitelist = loadWhitelist();
        const lowerHostname = hostname.toLowerCase();
        return whitelist.some(whitelistedHost => lowerHostname === whitelistedHost || lowerHostname.endsWith('.' + whitelistedHost));
    }

    function applyCustomFont() {
        GM_addStyle(`
            /* Apply to all elements */
            * {
                font-family: ${APTOS_FONT_FAMILY} !important;
            }

            /*
            Alternative, more specific selectors if '*' causes issues:
            body, p, div, span, a, li, h1, h2, h3, h4, h5, h6,
            input, button, textarea, select, option, label, legend,
            article, aside, footer, header, main, nav, section,
            td, th, caption, pre, code { // Added pre and code for monospace consistency
                font-family: ${APTOS_FONT_FAMILY} !important;
            }
            */
        `);
        console.log(`${SCRIPT_NAME}: Applied Aptos font family to ${window.location.hostname}.`);
    }

    // --- Main Logic ---
    const currentHostname = window.location.hostname;

    if (currentHostname && typeof currentHostname === 'string' && currentHostname.trim() !== "") {
        if (!isSiteWhitelisted(currentHostname)) {
            applyCustomFont();
        } else {
            console.log(`${SCRIPT_NAME}: ${currentHostname} is whitelisted. Aptos font not applied.`);
        }
    } else {
        console.warn(`${SCRIPT_NAME}: Could not determine current hostname. Font not applied.`);
    }


    // --- Menu Commands for Whitelist Management ---

    function addCurrentSiteToWhitelist() {
        const hostnameToAdd = currentHostname;
        if (!hostnameToAdd || typeof hostnameToAdd !== 'string' || hostnameToAdd.trim() === "") {
            alert(`${SCRIPT_NAME}: Cannot determine current hostname to add to whitelist.`);
            return;
        }

        const whitelist = loadWhitelist();
        // Prompt for the exact hostname to add (allows adding base domain if user prefers)
        const hostToAddInput = prompt(
            `${SCRIPT_NAME}: Enter hostname to add to whitelist (e.g., ${hostnameToAdd} or a base domain like ${hostnameToAdd.split('.').slice(-2).join('.')}):`,
            hostnameToAdd
        );

        if (hostToAddInput && hostToAddInput.trim() !== "") {
            const trimmedHost = hostToAddInput.trim().toLowerCase();
            if (!whitelist.includes(trimmedHost)) {
                whitelist.push(trimmedHost);
                saveWhitelist(whitelist);
                alert(`${SCRIPT_NAME}: ${trimmedHost} added to whitelist.\nReload the page for changes to take effect.`);
            } else {
                alert(`${SCRIPT_NAME}: ${trimmedHost} is already in the whitelist.`);
            }
        }
    }

    function removeSiteFromWhitelist() {
        const hostnameToRemove = currentHostname;
        if (!hostnameToRemove || typeof hostnameToRemove !== 'string' || hostnameToRemove.trim() === "") {
            alert(`${SCRIPT_NAME}: Cannot determine current hostname to remove from whitelist.`);
            return;
        }
        let whitelist = loadWhitelist();

        // Prompt for the exact hostname to remove
        const hostToRemoveInput = prompt(
            `${SCRIPT_NAME}: Enter hostname to remove from whitelist (e.g., ${hostnameToRemove} or a specific entry):`,
            hostnameToRemove
        );

        if (hostToRemoveInput && hostToRemoveInput.trim() !== "") {
            const trimmedHost = hostToRemoveInput.trim().toLowerCase();
            if (whitelist.includes(trimmedHost)) {
                whitelist = whitelist.filter(site => site !== trimmedHost);
                saveWhitelist(whitelist);
                alert(`${SCRIPT_NAME}: ${trimmedHost} removed from whitelist.\nReload the page for changes to take effect.`);
            } else {
                alert(`${SCRIPT_NAME}: ${trimmedHost} was not found in the whitelist.`);
            }
        }
    }

    function viewEditWhitelist() {
        const whitelist = loadWhitelist();
        const whitelistString = whitelist.join(', ');
        const newWhitelistString = prompt(
            `${SCRIPT_NAME}: Edit whitelist (comma-separated hostnames):\nExample: google.com, example.org`,
            whitelistString
        );

        if (newWhitelistString !== null) { // User didn't cancel prompt
            const newWhitelistArray = newWhitelistString
                .split(',')
                .map(site => site.trim().toLowerCase())
                .filter(site => site.length > 0 && site.includes('.')); // Basic validation: ensure it has a dot

            saveWhitelist(newWhitelistArray);
            alert(`${SCRIPT_NAME}: Whitelist updated.\nReload relevant pages for changes to take effect.`);
        }
    }

    // Register menu commands only if currentHostname is valid
    if (currentHostname && typeof currentHostname === 'string' && currentHostname.trim() !== "") {
        GM_registerMenuCommand(`[${SCRIPT_NAME}] Whitelist: Add current site (${currentHostname})`, addCurrentSiteToWhitelist);
        GM_registerMenuCommand(`[${SCRIPT_NAME}] Whitelist: Remove from whitelist...`, removeSiteFromWhitelist);
    }
    GM_registerMenuCommand(`[${SCRIPT_NAME}] Whitelist: View/Edit All`, viewEditWhitelist);

})();