{"id":604,"date":"2025-08-09T11:08:37","date_gmt":"2025-08-09T03:08:37","guid":{"rendered":"https:\/\/www.subkme.com\/?p=604"},"modified":"2025-08-12T12:46:00","modified_gmt":"2025-08-12T04:46:00","slug":"%e3%80%90%e6%b2%b9%e7%8c%b4%e8%84%9a%e6%9c%ac%e3%80%91%e9%9b%86%e5%9b%a2oa%e9%ab%98%e4%ba%ae%e6%8c%87%e5%ae%9a%e5%85%b3%e9%94%ae%e5%ad%97","status":"publish","type":"post","link":"https:\/\/subk.me\/?p=604","title":{"rendered":"\u3010\u6cb9\u7334\u811a\u672c\u3011\u96c6\u56e2OA\u9ad8\u4eae\u6307\u5b9a\u5173\u952e\u5b57"},"content":{"rendered":"<p>\u5904\u7406\u96c6\u56e2OA\u6587\u4ef6\uff0c\u9ad8\u4eae\u6307\u5b9a\u5173\u952e\u5b57\uff0c\u65b9\u4fbf\u67e5\u770b\u5f31\u9879\u60c5\u51b5\u7b49\u3002<\/p>\n<pre><code>\/\/ ==UserScript==\n\/\/ @name         \u96c6\u56e2OA\u9ad8\u4eae\u5173\u952e\u8bcd&ldquo;AA&rdquo;&ldquo;BB&rdquo;\n\/\/ @namespace    http:\/\/tampermonkey.net\/\n\/\/ @version      5.0\n\/\/ @description  \u89e3\u51b3\u5173\u952e\u8bcd\u88ab\u591a\u4e2aspan\u62c6\u5206\u5bfc\u81f4\u9ad8\u4eae\u5931\u8d25\u7684\u95ee\u9898\n\/\/ @author       subk\n\/\/ @match        http:\/\/XXX\/std-official-document-view\/g4\/process-form*\n\/\/ @grant        none\n\/\/ ==\/UserScript==\n\n(function () {\n    &#039;use strict&#039;;\n\n    const keywords = [\n        { word: &#039;AA&#039;, color: &#039;yellow&#039; },\n        { word: &#039;BB&#039;, color: &#039;lightskyblue&#039; },\n    ];\n\n    \/\/ Escape special characters for regex\n    const escapeRegExp = (str) =&gt; str.replace(\/[.*+?^${}()|[\\]\\\\]\/g, &#039;\\\\$&amp;&#039;);\n\n    \/\/ Create a single regex for all keywords\n    const regex = new RegExp(keywords.map(({ word }) =&gt; escapeRegExp(word)).join(&#039;|&#039;), &#039;g&#039;);\n\n    function highlightInElement(el) {\n        const treeWalker = document.createTreeWalker(el, NodeFilter.SHOW_TEXT, {\n            acceptNode: (node) =&gt; {\n                \/\/ Skip nodes inside script, style, or already highlighted spans\n                if (node.parentNode.tagName === &#039;SCRIPT&#039; || node.parentNode.tagName === &#039;STYLE&#039; || node.parentNode.classList.contains(&#039;highlight&#039;)) {\n                    return NodeFilter.FILTER_REJECT;\n                }\n                return node.nodeValue.match(regex) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;\n            }\n        }, false);\n\n        const textNodes = [];\n        while (treeWalker.nextNode()) {\n            textNodes.push(treeWalker.currentNode);\n        }\n\n        textNodes.forEach(node =&gt; {\n            const parent = node.parentNode;\n            const fragment = document.createDocumentFragment();\n            const text = node.nodeValue;\n            let lastIndex = 0;\n\n            \/\/ Split text and wrap matches in spans\n            text.replace(regex, (match, index) =&gt; {\n                \/\/ Add text before the match\n                if (index &gt; lastIndex) {\n                    fragment.appendChild(document.createTextNode(text.slice(lastIndex, index)));\n                }\n\n                \/\/ Find the matching keyword and its color\n                const { color } = keywords.find(kw =&gt; kw.word === match) || { color: &#039;yellow&#039; };\n                const span = document.createElement(&#039;span&#039;);\n                span.className = &#039;highlight&#039;;\n                span.style.backgroundColor = color;\n                span.textContent = match;\n                fragment.appendChild(span);\n\n                lastIndex = index + match.length;\n            });\n\n            \/\/ Add remaining text\n            if (lastIndex &lt; text.length) {\n                fragment.appendChild(document.createTextNode(text.slice(lastIndex)));\n            }\n\n            \/\/ Replace the original text node\n            parent.replaceChild(fragment, node);\n        });\n    }\n\n    function applyHighlight() {\n        const container = document.querySelector(&#039;.WordSection1&#039;);\n        if (container) {\n            highlightInElement(container);\n            return true;\n        }\n        return false;\n    }\n\n    \/\/ Observe DOM changes to handle dynamic content\n    function observeDOM() {\n        const observer = new MutationObserver((mutations) =&gt; {\n            for (const mutation of mutations) {\n                if (mutation.addedNodes.length || mutation.type === &#039;childList&#039;) {\n                    if (applyHighlight()) {\n                        \/\/ Optionally stop observing if highlighting is successful\n                        \/\/ observer.disconnect();\n                    }\n                }\n            }\n        });\n\n        observer.observe(document.body, {\n            childList: true,\n            subtree: true\n        });\n\n        \/\/ Initial attempt\n        applyHighlight();\n    }\n\n    \/\/ Run on DOMContentLoaded for faster execution\n    if (document.readyState === &#039;loading&#039;) {\n        document.addEventListener(&#039;DOMContentLoaded&#039;, observeDOM);\n    } else {\n        observeDOM();\n    }\n})();<\/code><\/pre>","protected":false},"excerpt":{"rendered":"<p>\u5904\u7406\u96c6\u56e2OA\u6587\u4ef6\uff0c\u9ad8\u4eae\u6307\u5b9a\u5173\u952e\u5b57\uff0c\u65b9\u4fbf\u67e5\u770b\u5f31\u9879\u60c5\u51b5\u7b49\u3002 \/\/ ==UserScript== \/\/ @name  [&hellip;]<\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[32],"class_list":["post-604","post","type-post","status-publish","format-standard","hentry","category-it","tag-32"],"_links":{"self":[{"href":"https:\/\/subk.me\/index.php?rest_route=\/wp\/v2\/posts\/604","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/subk.me\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/subk.me\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/subk.me\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/subk.me\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=604"}],"version-history":[{"count":3,"href":"https:\/\/subk.me\/index.php?rest_route=\/wp\/v2\/posts\/604\/revisions"}],"predecessor-version":[{"id":612,"href":"https:\/\/subk.me\/index.php?rest_route=\/wp\/v2\/posts\/604\/revisions\/612"}],"wp:attachment":[{"href":"https:\/\/subk.me\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=604"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/subk.me\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=604"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/subk.me\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=604"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}