Greasy Fork

Greasy Fork is available in English.

自动复制

自动复制,鼠标选中,直接复制,省去你的左手。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         自动复制
// @name:zh-CN   自动复制
// @name:en      Auto-Copy
// @name:ja      オートコピー
// @name:ko      자동 복사
// @name:es      Copia Automática
// @namespace    gura8390/copy/1
// @license MIT
// @version      2.5.1
// @description  自动复制,鼠标选中,直接复制,省去你的左手。
// @description:en Automatically copy selected text to clipboard
// @description:ja 選択したテキストを自動的にコピーします
// @description:ko 선택한 텍스트를 자동으로 복사합니다
// @description:es Copia automáticamente el texto seleccionado
// @author       lbihhe
// @icon         data:image/png;base64,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
// @match        *://*/*
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_registerMenuCommand
// @grant        GM_unregisterMenuCommand
// @grant        GM_addStyle
// ==/UserScript==

(function() {
    'use strict';

    const STORAGE_KEY = 'auto_copy_enabled';
    let isEnabled = GM_getValue(STORAGE_KEY, true);
    let menuCommands = [];
    let copyTimer;

    // ========================
    // 多语言支持(保持不变)
    // ========================
    const i18n = {
        'en': {
            panelTitle: 'Auto Copy',
            toggleBtn: isEnabled => isEnabled ? 'Enabled' : 'Disabled',
            statusText: isEnabled => isEnabled ? 'System Active' : 'System Paused',
            copied: 'Copied to clipboard',
            copyFailed: 'Copy failed',
            openPanel: 'Control Panel',
            closePanel: 'Close Panel'
        },
        'zh-CN': {
            panelTitle: '智能复制',
            toggleBtn: isEnabled => isEnabled ? '已启用' : '已禁用',
            statusText: isEnabled => isEnabled ? '✓ 正在监控选中文字' : '✗ 自动复制已暂停',
            copied: '文本已存入剪贴板',
            copyFailed: '复制失败',
            openPanel: '打开控制面板',
            closePanel: '关闭控制面板'
        }
    };
    const currentLang = navigator.language.startsWith('zh') ? 'zh-CN' : 'en';
    const t = i18n[currentLang];

    // ========================
    // 全新现代 UI 样式(2026 审美)
    // ========================
    GM_addStyle(`
        :root {
            --ac-radius: 28px;
            --ac-blur: 20px;
            --ac-primary: 99 102 241;
            --ac-success: 34 197 94;
            --ac-danger: 239 68 68;
            --ac-bg-light: 255 255 255 / 0.78;
            --ac-bg-dark: 31 41 55 / 0.82;
            --ac-border-light: 255 255 255 / 0.18;
            --ac-border-dark: 255 255 255 / 0.12;
            --ac-shadow: 0 16px 40px -12px rgb(0 0 0 / 0.18);
            --ac-text: 15 23 42;
            --ac-text-dark: 243 244 246;
        }

        @media (prefers-color-scheme: dark) {
            :root {
                --ac-bg: var(--ac-bg-dark);
                --ac-border: var(--ac-border-dark);
                --ac-text: var(--ac-text-dark);
            }
        }

        @media (prefers-color-scheme: light) {
            :root {
                --ac-bg: var(--ac-bg-light);
                --ac-border: var(--ac-border-light);
            }
        }

        .ac-feedback,
        .ac-status-icon,
        .ac-panel {
            font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            color: hsl(var(--ac-text));
            background: rgba(var(--ac-bg));
            backdrop-filter: blur(var(--ac-blur));
            -webkit-backdrop-filter: blur(var(--ac-blur));
            border: 1px solid rgba(var(--ac-border));
            border-radius: var(--ac-radius);
            box-shadow: var(--ac-shadow);
            transition: all 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
        }

        /* 反馈气泡 */
        .ac-feedback {
            position: fixed;
            z-index: 2147483647;
            pointer-events: none;
            padding: 12px 20px;
            font-size: 15px;
            font-weight: 500;
            display: flex;
            align-items: center;
            gap: 12px;
            animation: ac-bounce-in 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
            border: 1px solid rgba(255,255,255,0.25);
        }

        @keyframes ac-bounce-in {
            0%   { transform: scale(0.7) translateY(16px); opacity: 0; }
            60%  { transform: scale(1.08) translateY(-4px); }
            100% { transform: scale(1) translateY(0); opacity: 1; }
        }

        /* 状态图标 - 胶囊形 + 悬浮光晕 */
        .ac-status-icon {
            position: fixed;
            bottom: 24px;
            right: 24px;
            width: 56px;
            height: 56px;
            border-radius: 9999px;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            z-index: 2147483646;
            transition: all 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
            box-shadow: 0 12px 32px -8px rgba(0,0,0,0.2);
        }

        .ac-status-icon:hover {
            transform: scale(1.14) translateY(-4px);
            box-shadow: 0 20px 48px -12px rgba(99,102,241,0.4);
        }

        .ac-status-icon svg {
            width: 28px;
            height: 28px;
            stroke-width: 2.8;
            transition: transform 0.4s ease;
        }

        .ac-status-icon:hover svg {
            transform: rotate(360deg);
        }

        /* 控制面板 */
        .ac-panel {
            position: fixed;
            bottom: 100px;
            right: 24px;
            width: 320px;
            padding: 28px 24px;
            z-index: 2147483647;
            animation: ac-slide-up 0.55s cubic-bezier(0.16, 1, 0.3, 1);
            overflow: hidden;
        }

        .ac-panel-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 28px;
        }

        .ac-panel-header h3 {
            margin: 0;
            font-size: 19px;
            font-weight: 700;
            letter-spacing: -0.02em;
        }

        .ac-close {
            cursor: pointer;
            font-size: 22px;
            opacity: 0.6;
            transition: all 0.3s;
        }

        .ac-close:hover {
            opacity: 1;
            transform: rotate(90deg);
        }

        .ac-toggle-btn {
            width: 100%;
            padding: 16px;
            border: none;
            border-radius: 20px;
            font-size: 16px;
            font-weight: 600;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 10px;
            transition: all 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
            box-shadow: inset 0 2px 8px rgba(0,0,0,0.08);
        }

        .ac-btn-on {
            background: rgb(var(--ac-primary));
            color: white;
            box-shadow: 0 8px 24px -8px rgb(var(--ac-primary) / 0.5);
        }

        .ac-btn-on:hover {
            transform: translateY(-2px) scale(1.02);
            box-shadow: 0 16px 32px -10px rgb(var(--ac-primary) / 0.6);
        }

        .ac-btn-off {
            background: rgba(229,231,235,0.9);
            color: #4b5563;
        }

        .ac-btn-off:hover {
            background: rgba(209,213,219,0.9);
        }

        .ac-status-hint {
            margin-top: 20px;
            font-size: 13px;
            text-align: center;
            opacity: 0.7;
            letter-spacing: -0.01em;
        }

        @keyframes ac-slide-up {
            from { transform: translateY(40px) scale(0.94); opacity: 0; }
            to   { transform: translateY(0) scale(1); opacity: 1; }
        }
    `);

    // ========================
    // 核心逻辑(基本保持原样)
    // ========================
    const handleSelection = (e) => {
        if (!isEnabled) return;
        clearTimeout(copyTimer);
        copyTimer = setTimeout(() => {
            const selection = window.getSelection();
            const text = selection.toString().trim();
            if (text.length > 0 && !['INPUT', 'TEXTAREA'].includes(document.activeElement.tagName)) {
                navigator.clipboard.writeText(text).then(() => {
                    createFeedback('copied', e);
                }).catch(() => {
                    createFeedback('copyFailed', e);
                });
            }
        }, 200);
    };

    const createFeedback = (key, e) => {
        const div = document.createElement('div');
        div.className = 'ac-feedback';
        const color = key === 'copied' ? `rgb(var(--ac-success))` : `rgb(var(--ac-danger))`;
        div.innerHTML = `
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="${color}" stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
                ${key === 'copied'
                    ? '<polyline points="20 6 9 17 4 12"></polyline>'
                    : '<line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line>'}
            </svg>
            <span>${t[key]}</span>
        `;
        Object.assign(div.style, {
            left: `${Math.min(e.clientX + 10, window.innerWidth - 220)}px`,
            top: `${e.clientY + 20}px`
        });
        document.body.appendChild(div);
        setTimeout(() => {
            div.style.opacity = '0';
            div.style.transition = 'opacity 0.6s ease';
            setTimeout(() => div.remove(), 600);
        }, 1800);
    };

    const toggleFeature = () => {
        isEnabled = !isEnabled;
        GM_setValue(STORAGE_KEY, isEnabled);
        updateStatusIcon();
        const panel = document.querySelector('.ac-panel');
        if (panel) {
            panel.remove();
            showControlPanel();
        }
        updateMenuCommands();
    };

    const updateStatusIcon = () => {
        const icon = document.querySelector('.ac-status-icon');
        if (icon) {
            const color = isEnabled ? `rgb(var(--ac-primary))` : `rgb(var(--ac-danger))`;
            icon.style.color = color;
            icon.style.borderColor = `rgba(${isEnabled ? '99,102,241' : '239,68,68'}, 0.3)`;
        }
    };

    const showControlPanel = () => {
        if (document.querySelector('.ac-panel')) return;
        const panel = document.createElement('div');
        panel.className = 'ac-panel';
        panel.innerHTML = `
            <div class="ac-panel-header">
                <h3>${t.panelTitle}</h3>
                <div class="ac-close">✕</div>
            </div>
            <button class="ac-toggle-btn ${isEnabled ? 'ac-btn-on' : 'ac-btn-off'}">
                ${isEnabled ? '✨' : '💤'} ${t.toggleBtn(isEnabled)}
            </button>
            <div class="ac-status-hint">${t.statusText(isEnabled)}</div>
        `;
        panel.querySelector('.ac-toggle-btn').onclick = toggleFeature;
        panel.querySelector('.ac-close').onclick = () => panel.remove();
        document.body.appendChild(panel);
    };

    const createStatusIcon = () => {
        const btn = document.createElement('div');
        btn.className = 'ac-status-icon';
        btn.innerHTML = `
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor">
                <circle cx="12" cy="12" r="10" stroke-width="2.5"/>
                ${isEnabled
                    ? '<path d="M9 12l2 2 4-4" stroke-width="2.8"/>'
                    : '<path d="M8 8l8 8M16 8l-8 8" stroke-width="2.8"/>'}
            </svg>
        `;
        btn.onclick = () => {
            const panel = document.querySelector('.ac-panel');
            panel ? panel.remove() : showControlPanel();
        };
        document.body.appendChild(btn);
        updateStatusIcon();
    };

    const updateMenuCommands = () => {
        menuCommands.forEach(cmd => GM_unregisterMenuCommand(cmd));
        menuCommands = [];
        menuCommands.push(GM_registerMenuCommand(
            isEnabled ? '⏸ 禁用自动复制' : '▶️ 启用自动复制',
            toggleFeature
        ));
    };

    // 初始化
    createStatusIcon();
    document.addEventListener('mouseup', handleSelection);
    updateMenuCommands();

})();