高亮白宫网站上的特朗普名字,并在悬停时隐藏光标 (视障辅助)

在 www.whitehouse.gov 网站上将“Donald J. Trump”及其变体的字体加粗加大,并在鼠标悬停时隐藏光标,以提高可见性。

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

You will need to install an extension such as Tampermonkey to install this script.

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Highlight Trump Name & Hide Cursor on Hover on Whitehouse.gov (For Accessibility)
// @name:zh-CN   高亮白宫网站上的特朗普名字,并在悬停时隐藏光标 (视障辅助)
// @namespace    http://tampermonkey.net/
// @version      1.1
// @description  Highlights mentions of Donald J. Trump on www.whitehouse.gov with bold/larger font and hides the cursor when hovering over them for better visibility.
// @description:zh-CN 在 www.whitehouse.gov 网站上将“Donald J. Trump”及其变体的字体加粗加大,并在鼠标悬停时隐藏光标,以提高可见性。
// @author       Lyragosa
// @match        *://www.whitehouse.gov/*
// @grant        GM_addStyle
// @run-at       document-idle
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // --- 配置 ---
    const highlightStyleClass = 'highlighted-trump-name-vz'; // 自定义CSS类名,避免冲突
    const patternsToHighlight = [
        /\bPresident\s+Donald\s+J\.\s+Trump\b/gi, // President Donald J. Trump
        /\bPresident\s+Trump\b/gi,              // President Trump
        /\bDonald\s+J\.\s+Trump\b/gi,          // Donald J. Trump
        /\bTrump\b/gi                         // 单独的 "Trump"
    ];
    // --- CSS 样式 ---
    // 更新:增加了 :hover 规则来隐藏光标
    const cssStyle = `
        .${highlightStyleClass} {
            font-weight: bold !important;
            font-size: 1.2em !important; /* 比周围文字大20% */
            /* 可以添加其他样式 */
        }
        /* 新增:当鼠标悬停在高亮的span上时,隐藏光标 */
        .${highlightStyleClass}:hover {
            cursor: none !important;
        }
    `;

    // --- 注入CSS样式 ---
    GM_addStyle(cssStyle);

    // --- 核心处理函数 ---
    function highlightTextInNode(node) {
        const walker = document.createTreeWalker(
            node,
            NodeFilter.SHOW_TEXT,
            {
                acceptNode: function(textNode) {
                    if (textNode.parentNode.nodeName === 'SCRIPT' || textNode.parentNode.nodeName === 'STYLE') {
                        return NodeFilter.FILTER_REJECT;
                    }
                    if (textNode.parentNode.classList.contains(highlightStyleClass)) {
                        return NodeFilter.FILTER_REJECT;
                    }
                    if (textNode.nodeValue.trim() === '') {
                        return NodeFilter.FILTER_SKIP;
                    }
                    for (const pattern of patternsToHighlight) {
                        pattern.lastIndex = 0;
                        if (pattern.test(textNode.nodeValue)) {
                            return NodeFilter.FILTER_ACCEPT;
                        }
                    }
                    return NodeFilter.FILTER_SKIP;
                }
            },
            false
        );

        let textNode;
        const nodesToProcess = [];
        while(textNode = walker.nextNode()) {
            nodesToProcess.push(textNode);
        }

        for (const nodeToProcess of nodesToProcess) {
            let currentNode = nodeToProcess;
            let nodeReplaced = false; // 标记节点是否已被替换

            for (const pattern of patternsToHighlight) {
                if (nodeReplaced) break; // 如果节点已被替换,跳过后续模式对此节点的处理

                pattern.lastIndex = 0;
                let match;
                let lastIndex = 0;
                const fragment = document.createDocumentFragment();
                let foundMatchInPattern = false;

                while ((match = pattern.exec(currentNode.nodeValue)) !== null) {
                    foundMatchInPattern = true;
                    const matchedText = match[0];
                    const matchIndex = match.index;

                    if (matchIndex > lastIndex) {
                        fragment.appendChild(document.createTextNode(currentNode.nodeValue.substring(lastIndex, matchIndex)));
                    }

                    const span = document.createElement('span');
                    span.className = highlightStyleClass;
                    span.textContent = matchedText;
                    fragment.appendChild(span);

                    lastIndex = pattern.lastIndex;
                 }

                 if (foundMatchInPattern) {
                     if (lastIndex < currentNode.nodeValue.length) {
                         fragment.appendChild(document.createTextNode(currentNode.nodeValue.substring(lastIndex)));
                     }
                     if (currentNode.parentNode) {
                         currentNode.parentNode.replaceChild(fragment, currentNode);
                         nodeReplaced = true; // 标记此原始节点已被替换
                     }
                 }
            }
        }
    }

    // --- 初始执行 ---
    highlightTextInNode(document.body);

    // --- 监听DOM变化 (处理动态加载的内容) ---
    const observer = new MutationObserver(function(mutationsList) {
        for (const mutation of mutationsList) {
            if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
                mutation.addedNodes.forEach(function(addedNode) {
                    if (addedNode.nodeType === Node.ELEMENT_NODE) {
                        // 检查添加的节点本身或其父节点是否是高亮节点,避免递归触发
                        if (!addedNode.classList || !addedNode.classList.contains(highlightStyleClass)) {
                             if (!addedNode.parentNode || !addedNode.parentNode.classList || !addedNode.parentNode.classList.contains(highlightStyleClass)){
                                highlightTextInNode(addedNode);
                            }
                        }
                    }
                });
            }
        }
    });

    observer.observe(document.body, {
        childList: true,
        subtree: true
    });

})();