处理集团OA文件,高亮指定关键字,方便查看弱项情况等。
// ==UserScript==
// @name 集团OA高亮关键词“AA”“BB”
// @namespace http://tampermonkey.net/
// @version 5.0
// @description 解决关键词被多个span拆分导致高亮失败的问题
// @author subk
// @match http://XXX/std-official-document-view/g4/process-form*
// @grant none
// ==/UserScript==
(function () {
'use strict';
const keywords = [
{ word: 'AA', color: 'yellow' },
{ word: 'BB', color: 'lightskyblue' },
];
// Escape special characters for regex
const escapeRegExp = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
// Create a single regex for all keywords
const regex = new RegExp(keywords.map(({ word }) => escapeRegExp(word)).join('|'), 'g');
function highlightInElement(el) {
const treeWalker = document.createTreeWalker(el, NodeFilter.SHOW_TEXT, {
acceptNode: (node) => {
// Skip nodes inside script, style, or already highlighted spans
if (node.parentNode.tagName === 'SCRIPT' || node.parentNode.tagName === 'STYLE' || node.parentNode.classList.contains('highlight')) {
return NodeFilter.FILTER_REJECT;
}
return node.nodeValue.match(regex) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
}
}, false);
const textNodes = [];
while (treeWalker.nextNode()) {
textNodes.push(treeWalker.currentNode);
}
textNodes.forEach(node => {
const parent = node.parentNode;
const fragment = document.createDocumentFragment();
const text = node.nodeValue;
let lastIndex = 0;
// Split text and wrap matches in spans
text.replace(regex, (match, index) => {
// Add text before the match
if (index > lastIndex) {
fragment.appendChild(document.createTextNode(text.slice(lastIndex, index)));
}
// Find the matching keyword and its color
const { color } = keywords.find(kw => kw.word === match) || { color: 'yellow' };
const span = document.createElement('span');
span.className = 'highlight';
span.style.backgroundColor = color;
span.textContent = match;
fragment.appendChild(span);
lastIndex = index + match.length;
});
// Add remaining text
if (lastIndex < text.length) {
fragment.appendChild(document.createTextNode(text.slice(lastIndex)));
}
// Replace the original text node
parent.replaceChild(fragment, node);
});
}
function applyHighlight() {
const container = document.querySelector('.WordSection1');
if (container) {
highlightInElement(container);
return true;
}
return false;
}
// Observe DOM changes to handle dynamic content
function observeDOM() {
const observer = new MutationObserver((mutations) => {
for (const mutation of mutations) {
if (mutation.addedNodes.length || mutation.type === 'childList') {
if (applyHighlight()) {
// Optionally stop observing if highlighting is successful
// observer.disconnect();
}
}
}
});
observer.observe(document.body, {
childList: true,
subtree: true
});
// Initial attempt
applyHighlight();
}
// Run on DOMContentLoaded for faster execution
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', observeDOM);
} else {
observeDOM();
}
})();