日期改色

Detect and highlight date formats xxxx-xx-xx and xxxx年xx月xx日

// ==UserScript==
// @name         日期改色
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Detect and highlight date formats xxxx-xx-xx and xxxx年xx月xx日
// @author       Kimi
// @match        *://*/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';


    // 定义日期格式的正则表达式
    const datePatterns = [
        '\\b\\d{4}-\\d{2}-\\d{2}\\b', // 匹配 YYYY-MM-DD
        '\\b\\d{4}年\\d{2}月\\d{2}日\\b', // 匹配 YYYY年MM月DD日
        '\\b\\d{4}年\\d{2}月\\d{2}日 \\d{2}:\\d{2}\\b', // 匹配 YYYY年MM月DD日 HH:MM
        '\\b\\d+秒前(?=\\s|$)', // 匹配 X秒前
        '\\b\\d+小时前(?=\\s|$)', // 匹配 X小时前
        '\\b\\d+分钟前(?=\\s|$)', // 匹配 X分钟前
        '',// 匹配 昨天
        '\\b\\d+天前(?=\\s|$)', // 匹配 X天前
        '\\b\\d+周前(?=\\s|$)', // 匹配 X周前
        '\\b\\d+月前(?=\\s|$)', // 匹配 X月前
        '\\b\\d+年前(?=\\s|$)', // 匹配 X年前
        '\\b\\d 秒前(?=\\s|$)', // 匹配 1-5位数字的 X 秒前
        '\\b\\d 小时前(?=\\s|$)', // 匹配 1-5位数字的 X 小时前
        '\\b\\d 分钟前(?=\\s|$)', // 匹配 1-5位数字的 X 分钟前
        '\\b\\d 天前(?=\\s|$)', // 匹配 1-5位数字的 X 天前
        '\\b\\d 周前(?=\\s|$)', // 匹配 1-5位数字的 X 周前
        '\\b\\d 月前(?=\\s|$)', // 匹配 1-5位数字的 X 月前
        '\\b\\d 年前(?=\\s|$)', // 匹配 1-5位数字的 X 年前
        '\\b\\d{4}年(?=\\s|$)',// 匹配 YYYY年
        '\\b\\d{2}月\\d{2}日(?=\\s|$)', // 匹配 MM月DD日
        '\\b\\d{1,2}-\\d{1,2}(?=\\s|$)', // 匹配 MM-DD
        '(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun) [A-Za-z]+ \\d{1,2}, \\d{4}(?=\\s|$)' // 匹配 
    ];
    const dateFormatRegex = new RegExp(datePatterns.join('|'), 'g');


    // 定义要应用的样式
    const style = `
        color: #338143 !important;
        font-weight: 600 !important;
        font-family: bilifont, -apple-system, BlinkMacSystemFont, Inter, "Segoe UI Variable", "Segoe UI", "Roboto Flex", Roboto, "Noto Sans", Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", "PingFang SC", "Source Han Sans SC VF", "Noto Sans CJK SC", "Source Han Sans SC", "Microsoft YaHei", system-ui, Arial, sans-serif !important;
    `;

    // 遍历页面中所有的元素
    const elements = document.querySelectorAll('*');
    elements.forEach(element => {
        // 获取元素的所有文本节点
        const textNodes = getTextNodes(element);

        // 遍历每个文本节点
        textNodes.forEach(textNode => {
            // 检查文本内容是否包含日期格式
            if (dateFormatRegex.test(textNode.nodeValue)) {
                // 匹配所有日期格式
                const matches = textNode.nodeValue.match(dateFormatRegex);

                // 从后向前处理每个匹配项
                for (let i = matches.length - 1; i >= 0; i--) {
                    const match = matches[i];
                    const index = textNode.nodeValue.indexOf(match);

                    // 创建一个新 <span> 元素
                    const span = document.createElement('font');
                    span.style.cssText = style;
                    span.textContent = match;

                    // 使用 Range 来分割文本节点
                    const range = new Range();
                    range.setStart(textNode, index);
                    range.setEnd(textNode, index + match.length);

                    // 替换匹配的文本节点部分
                    range.deleteContents();
                    range.insertNode(span);
                }
            }
        });
    });

    // 获取元素的所有文本节点
    function getTextNodes(node) {
        const textNodes = [];
        if (node.nodeType === Node.TEXT_NODE) {
            textNodes.push(node);
        } else if (node.nodeType === Node.ELEMENT_NODE) {
            for (let child of node.childNodes) {
                textNodes.push(...getTextNodes(child));
            }
        }
        return textNodes;
    }


})();