强制系统字体

让网页强制使用系统字体

// ==UserScript==
// @name         强制系统字体
// @name:en      System Fonts
// @name:zh-CN   强制系统字体
// @name:zh-TW   強制系統字體
// @namespace    http://tampermonkey.net/
// @version      1.0.1
// @description  让网页强制使用系统字体
// @description:en  Let web pages force the use of system fonts
// @description:zh-CN    让网页强制使用系统字体
// @description:zh-TW    讓網頁強制使用系統字體
// @author       Deepseek
// @match        *://*/*
// @grant        GM_addStyle
// @license      MIT
// @run-at       document-start
// ==/UserScript==

(function() {
    'use strict';

    // 排除规则
    const baseExcludes = [
        'pre, code, img, svg, audio, video',
        '[class*="icon"], [class*="logo"]',
        '[id*="logo"], [id*="icon"]'
    ].join(',');

    // Google域名的特殊处理
    function isGoogleDomain() {
        return location.hostname.match(/\.google\./);
    }

    function getGoogleExcludes() {
        return [
            'div[aria-label*="Google"]',
            '[class*="gb_"]',
            '[font-family*="Google Sans"]'
        ].join(',');
    }

    // 合并排除规则
    function getExcludeSelectors() {
        let excludes = baseExcludes;
        if (isGoogleDomain()) {
            excludes += `, ${getGoogleExcludes()}`;
        }
        return excludes;
    }

    // 核心样式规则
    function applyCoreStyles() {
        const excludeSelectors = getExcludeSelectors();
        const styles = `
            *:not(${excludeSelectors}) {
                font-family: system-ui, sans-serif !important;
            }

            /* Google Logo保留 */
            [class*="gb_"] > svg,
            .logo-subtext,
            [aria-label*="Google"] span {
                font-family: 'Google Sans', system-ui !important;
            }
        `;
        GM_addStyle(styles);
    }

    // 智能DOM监听器
    function setUpDOMObserver() {
        const observer = new MutationObserver(mutations => {
            mutations.forEach(({ addedNodes }) => {
                addedNodes.forEach(node => {
                    if (node.nodeType === 1 && node.querySelectorAll('*').length) {
                        const elements = Array.from(node.querySelectorAll('*'));
                        elements.forEach(element => {
                            if (!isElementExcluded(element)) {
                                element.style.fontFamily = 'system-ui, sans-serif';
                            }
                        });
                    }
                });
            });
        });

        observer.observe(document, {
            childList: true,
            subtree: true,
            attributes: true,
            attributeFilter: ['class', 'id', 'aria-label']
        });
    }

    // 判断元素是否被排除
    function isElementExcluded(element) {
        const excludeSelectors = getExcludeSelectors();
        const isExcluded = [...new Set(excludeSelectors.split(', '))].some(selector => {
            return element.matches(selector) ||
                element.closest(selector) ||
                (isGoogleDomain() && element.matches('[font-family*="Google Sans"]'));
        });
        return isExcluded;
    }

    // 初始化
    function init() {
        applyCoreStyles();
        setUpDOMObserver();
    }

    init();
})();