Discord Message Colorizer Enhanced

Colors <em> text yellow and text within parentheses blue in Discord messages, handling split spans

// ==UserScript==
// @name         Discord Message Colorizer Enhanced
// @namespace    http://tampermonkey.net/
// @version      1.2
// @description  Colors <em> text yellow and text within parentheses blue in Discord messages, handling split spans
// @author       Vishanka
// @match        https://discord.com/channels/*
// @grant        none
// ==/UserScript==



(function() {
    // 1. Inject CSS classes for styling
    function injectStyles() {
        const style = document.createElement('style');
        style.textContent = `
            /* Baseline color for all message content */
            div[class*="messageContent_"] {
                color: #A2A2AC;
            }

            /* Highlight colors for specific patterns */
            .highlight-yellow {
                color: #E0DF7F !important;
            }
            .highlight-blue {
                color: #737373 !important;
            }
            .highlight-white {
                color: #FFFFFF !important;
            }
        `;
        document.head.appendChild(style);
    }

    // 2. Function to style message content
    function styleMessageContent() {
        // Select all message items based on the class prefix
        const messageItems = document.querySelectorAll('li[class^="messageListItem_"]');

        messageItems.forEach(messageItem => {
            const contentDiv = messageItem.querySelector('div[class*="messageContent_"]');
            if (!contentDiv) return; // Skip if no content div found

            // a. Color all <em> elements yellow
            const emElements = contentDiv.querySelectorAll('em');
            emElements.forEach(em => {
                if (!em.classList.contains('highlight-yellow')) { // Prevent reapplying
                    em.classList.add('highlight-yellow');
                }
            });

            // b. Color text within parentheses blue
            colorTextWithinDelimiters(contentDiv, '(', ')', 'highlight-blue', false);

            // c. Color text within quotation marks white (#FFFFFF)
            // Supports straight quotes and smart quotes
            colorTextWithinQuotes(contentDiv, ['"', '“', '‘'], ['"', '”', '’'], 'highlight-white');
        });
    }

    /**
     * Helper function to color text within matched quotation marks.
     * @param {HTMLElement} container - The container element to search within.
     * @param {string[]} openDelimiters - The opening quotation marks.
     * @param {string[]} closeDelimiters - The closing quotation marks.
     * @param {string} highlightClass - The CSS class to apply for highlighting.
     */
    function colorTextWithinQuotes(container, openDelimiters, closeDelimiters, highlightClass) {
        const spans = Array.from(container.querySelectorAll('span'));
        let buffer = []; // Collect spans inside the current quote

        spans.forEach(span => {
            const text = span.textContent;

            // Process span content character by character
            for (let i = 0; i < text.length; i++) {
                const char = text[i];

                if (openDelimiters.includes(char) && buffer.length === 0) {
                    // Start a new quote
                    buffer.push(span);
                } else if (closeDelimiters.includes(char) && buffer.length > 0) {
                    // End the current quote
                    buffer.forEach(s => s.classList.add(highlightClass));
                    buffer = []; // Clear buffer
                } else if (buffer.length > 0) {
                    // Inside a quote
                    buffer.push(span);
                }
            }
        });
    }

    /**
     * Helper function to color text within specified delimiters.
     * For non-quotation mark delimiters like parentheses.
     * @param {HTMLElement} container - The container element to search within.
     * @param {string|string[]} openDelimiter - The opening delimiter character(s).
     * @param {string|string[]} closeDelimiter - The closing delimiter character(s).
     * @param {string} highlightClass - The CSS class to apply for highlighting.
     * @param {boolean} isToggle - Whether to toggle highlighting (true for quotes).
     */
    function colorTextWithinDelimiters(container, openDelimiter, closeDelimiter, highlightClass, isToggle) {
        const spans = container.querySelectorAll('span');
        let isWithin = false;

        // Normalize delimiters to arrays
        const openDelims = Array.isArray(openDelimiter) ? openDelimiter : [openDelimiter];
        const closeDelims = Array.isArray(closeDelimiter) ? closeDelimiter : [closeDelimiter];

        spans.forEach(span => {
            const text = span.textContent;

            if (isToggle) {
                let hasOpening = false;
                let hasClosing = false;

                // Check for any closing delimiters first
                closeDelims.forEach(close => {
                    if (text.includes(close)) {
                        hasClosing = true;
                    }
                });

                if (hasClosing && isWithin) {
                    // Apply highlight before closing
                    span.classList.add(highlightClass);
                    isWithin = false;
                }

                // Apply highlight if currently within delimiters
                if (isWithin) {
                    span.classList.add(highlightClass);
                }

                // Check for any opening delimiters
                openDelims.forEach(open => {
                    if (text.includes(open)) {
                        hasOpening = true;
                        isWithin = true;
                    }
                });

                if (hasOpening) {
                    // Apply highlight for the span containing the opening delimiter
                    span.classList.add(highlightClass);
                }
            } else {
                // Non-toggle: e.g., parentheses
                if (text.includes(openDelimiter)) {
                    isWithin = true;
                }

                if (isWithin) {
                    span.classList.add(highlightClass);
                }

                if (text.includes(closeDelimiter)) {
                    isWithin = false;
                }
            }
        });
    }

    // 3. Initialize the styling process
    function initializeStyling() {
        injectStyles();
        styleMessageContent();

        // Observe for new messages being added to the DOM
        const observer = new MutationObserver(mutations => {
            mutations.forEach(() => {
                styleMessageContent();
            });
        });

        // Start observing the entire document body for changes
        observer.observe(document.body, { childList: true, subtree: true });
    }

    // 4. Run the initialization
    initializeStyling();
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址