Change Clicked Link Color

Change color of clicked links in body with color presets and custom hex input

当前为 2024-07-20 提交的版本,查看 最新版本

// ==UserScript==
// @name         Change Clicked Link Color
// @license      MIT
// @namespace    http://tampermonkey.net/
// @author       [email protected]
// @version      0.4.3
// @description  Change color of clicked links in body with color presets and custom hex input
// @match        *://*/*
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_registerMenuCommand
// @grant        GM_addStyle
// ==/UserScript==

(function() {
    'use strict';

    const colorPresets = {
        'Purple': '#800080',
        'Red': '#FF0000',
        'Blue': '#0000FF',
        'Green': '#008000',
        'Orange': '#FFA500',
        'Pink': '#FFC0CB',
        'Brown': '#A52A2A',
        'Gray': '#808080'
    };

    let clickedColor = GM_getValue('clickedLinkColor', '#800080');
    let enabledSites = GM_getValue('enabledSites', []);

    GM_addStyle(`
        .color-selector-dialog {
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
            font-family: Arial, sans-serif;
            max-width: 400px;
        }
        .color-selector-dialog h3 {
            margin-top: 0;
            margin-bottom: 15px;
        }
        .color-selector-dialog select,
        .color-selector-dialog input[type="text"],
        .color-selector-dialog textarea {
            width: 100%;
            padding: 8px;
            margin-bottom: 15px;
            border: 1px solid #ccc;
            border-radius: 4px;
        }
        .color-selector-dialog .section {
            margin-bottom: 20px;
            padding-bottom: 20px;
            border-bottom: 1px solid #eee;
        }
        .color-selector-dialog .section:last-child {
            border-bottom: none;
            margin-bottom: 0;
            padding-bottom: 0;
        }
        .color-selector-dialog button {
            padding: 8px 16px;
            margin-right: 10px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }
        .color-selector-dialog button[type="submit"] {
            background-color: #4CAF50;
            color: white;
        }
        .color-selector-dialog button[type="button"] {
            background-color: #f44336;
            color: white;
        }
        .color-selector-dialog #addCurrentDomain {
            background-color: #2196F3;
            color: white;
        }
    `);

    function createColorSelector() {
        const dialog = document.createElement('dialog');
        dialog.className = 'color-selector-dialog';
        dialog.innerHTML = `
            <form method="dialog">
                <h3>Configure Clicked Link Color</h3>
                <div class="section">
                    <label for="colorPreset">Choose a preset color:</label>
                    <select id="colorPreset">
                        <option value="">-- Choose a preset color --</option>
                        ${Object.entries(colorPresets).map(([name, value]) => 
                            `<option value="${value}">${name} (${value})</option>`
                        ).join('')}
                    </select>
                </div>
                <div class="section">
                    <label for="customColor">Or enter a custom hex color:</label>
                    <input type="text" id="customColor" placeholder="#RRGGBB" pattern="^#[0-9A-Fa-f]{6}$">
                </div>
                <div class="section">
                    <label for="enabledSites">Enable on these sites (one per line):</label>
                    <textarea id="enabledSites" rows="5" placeholder="example.com"></textarea>
                    <button type="button" id="addCurrentDomain">Add Current Domain</button>
                </div>
                <div>
                    <button type="submit">Apply</button>
                    <button type="button" id="cancelBtn">Cancel</button>
                </div>
            </form>
        `;
        document.body.appendChild(dialog);

        const colorPreset = dialog.querySelector('#colorPreset');
        const customColor = dialog.querySelector('#customColor');
        const enabledSitesTextarea = dialog.querySelector('#enabledSites');
        const cancelBtn = dialog.querySelector('#cancelBtn');
        const addCurrentDomainBtn = dialog.querySelector('#addCurrentDomain');

        colorPreset.value = clickedColor;
        customColor.value = clickedColor;
        enabledSitesTextarea.value = enabledSites.join('\n');

        colorPreset.addEventListener('change', function() {
            if (this.value) {
                customColor.value = this.value;
            }
        });

        cancelBtn.addEventListener('click', () => dialog.close());

        addCurrentDomainBtn.addEventListener('click', () => {
            const currentDomain = window.location.hostname;
            const currentSites = enabledSitesTextarea.value.split('\n').map(site => site.trim());
            if (!currentSites.includes(currentDomain)) {
                currentSites.push(currentDomain);
                enabledSitesTextarea.value = currentSites.join('\n');
            }
        });

        dialog.addEventListener('close', () => {
            if (dialog.returnValue !== 'cancel') {
                const newColor = customColor.value;
                if (/^#[0-9A-F]{6}$/i.test(newColor)) {
                    clickedColor = newColor;
                    GM_setValue('clickedLinkColor', clickedColor);
                    
                    enabledSites = enabledSitesTextarea.value.split('\n').map(site => site.trim()).filter(Boolean);
                    GM_setValue('enabledSites', enabledSites);
                    
                    applyClickedLinkColor();
                } else {
                    alert("Invalid color code. Please use hex format (e.g., #800080).");
                }
            }
        });

        return dialog;
    }

    function showColorSelector() {
        const dialog = createColorSelector();
        dialog.showModal();
    }

    GM_registerMenuCommand("Configure clicked link color", showColorSelector);

    function applyClickedLinkColor() {
        if (isEnabledForCurrentSite()) {
            let style = document.getElementById('clickedLinkStyle');
            if (!style) {
                style = document.createElement('style');
                style.id = 'clickedLinkStyle';
                document.head.appendChild(style);
            }
            style.textContent = `
                body:not(header):not(footer) a:visited {
                    color: ${clickedColor} !important;
                }
            `;
        }
    }

    function isEnabledForCurrentSite() {
        const currentHost = window.location.hostname;
        return enabledSites.some(site => currentHost.includes(site));
    }

    if (isEnabledForCurrentSite()) {
        window.addEventListener('load', applyClickedLinkColor);

        document.body.addEventListener('click', function(e) {
            if (e.target.tagName === 'A' && !e.target.closest('header, footer')) {
                e.target.style.color = clickedColor;
            }
        });
    }
})();

QingJ © 2025

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