Greasy Fork

自动复制选中文本和解除复制限制按钮 by lbihhe

在任意网站选中任意文本时自动复制,并添加一个按钮以启用/禁用解除网站的复制限制和自动复制功能

目前为 2024-06-14 提交的版本。查看 最新版本

// ==UserScript==
// @name         自动复制选中文本和解除复制限制按钮 by lbihhe
// @namespace    http://tampermonkey.net/
// @version      1.5
// @description  在任意网站选中任意文本时自动复制,并添加一个按钮以启用/禁用解除网站的复制限制和自动复制功能
// @author       lbihhe
// @license      MIT
// @match        *://*/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    var copyEnabled = false; // 初始状态为禁用

    // 创建启用/禁用按钮
    var toggleButton = document.createElement('button');
    toggleButton.innerHTML = '解除复制限制并启用自动复制';
    toggleButton.style.position = 'fixed';
    toggleButton.style.top = '10px';
    toggleButton.style.right = '10px';
    toggleButton.style.zIndex = '9999';
    toggleButton.style.padding = '10px';
    toggleButton.style.backgroundColor = 'rgba(255, 255, 224, 0.6)'; // 初始背景色,60%透明度
    toggleButton.style.color = '#000000'; // 初始文字色
    toggleButton.style.border = 'none';
    toggleButton.style.borderRadius = '5px';
    toggleButton.style.cursor = 'pointer';
    toggleButton.style.fontFamily = '微软雅黑, Arial, sans-serif'; // 设置字体样式为微软雅黑
    toggleButton.style.fontSize = '14px'; // 设置字体大小为14px
    document.body.appendChild(toggleButton);

   /** 暂停执行反色
    // 自动检测并设置按钮前景色
    function setButtonTextColor() {
        var computedStyle = getComputedStyle(toggleButton);
        var backgroundColor = computedStyle.backgroundColor;
        toggleButton.style.color = getContrastColor(backgroundColor); // 根据背景色设置对比的前景色
    }

    // 获取对比色
    function getContrastColor(color) {
        var rgb = color.replace(/[^\d,]/g, '').split(',');
        var r = parseInt(rgb[0]);
        var g = parseInt(rgb[1]);
        var b = parseInt(rgb[2]);

        var brightness = (r * 299 + g * 587 + b * 114) / 1000;
        return brightness >= 128 ? '#000' : '#fff'; // 根据颜色亮度返回黑色或白色
    }

    // 页面加载完成后自动设置按钮前景色
    window.addEventListener('load', function() {
        setButtonTextColor();
    });
*/
    // 按钮点击事件 - 启用/禁用解除复制限制和自动复制
    toggleButton.addEventListener('click', function() {
        if (copyEnabled) {
            disableCopy();
            toggleButton.innerHTML = '解除复制限制并启用自动复制';
        } else {
            enableCopy();
            toggleButton.innerHTML = '禁用复制功能';
        }
        copyEnabled = !copyEnabled; // 切换状态
        setButtonTextColor(); // 设置按钮前景色
    });

    // 解除复制限制的函数
    function enableCopy() {
        // 移除常见的禁止复制的事件监听器
        document.addEventListener('copy', function(e) { e.stopPropagation(); }, true);
        document.addEventListener('cut', function(e) { e.stopPropagation(); }, true);
        document.addEventListener('contextmenu', function(e) { e.stopPropagation(); }, true);
        document.addEventListener('selectstart', function(e) { e.stopPropagation(); }, true);
        document.addEventListener('mousedown', function(e) { e.stopPropagation(); }, true);
        document.addEventListener('mouseup', function(e) { e.stopPropagation(); }, true);
        document.addEventListener('keydown', function(e) { e.stopPropagation(); }, true);
        document.addEventListener('keyup', function(e) { e.stopPropagation(); }, true);
        document.addEventListener('keypress', function(e) { e.stopPropagation(); }, true);

        // 解除 CSS 样式限制
        var css = '* { -webkit-user-select: auto !important; -moz-user-select: auto !important; -ms-user-select: auto !important; user-select: auto !important; }';
        var style = document.createElement('style');
        style.type = 'text/css';
        style.appendChild(document.createTextNode(css));
        document.head.appendChild(style);

        // 处理 body 标签的 oncontextmenu 属性
        if (document.body) {
            document.body.oncontextmenu = null;
        }

        // 处理常见的框架
        var frames = document.getElementsByTagName('iframe');
        for (var i = 0; i < frames.length; i++) {
            try {
                frames[i].contentWindow.document.addEventListener('copy', function(e) { e.stopPropagation(); }, true);
                frames[i].contentWindow.document.addEventListener('cut', function(e) { e.stopPropagation(); }, true);
                frames[i].contentWindow.document.addEventListener('contextmenu', function(e) { e.stopPropagation(); }, true);
                frames[i].contentWindow.document.addEventListener('selectstart', function(e) { e.stopPropagation(); }, true);
                frames[i].contentWindow.document.addEventListener('mousedown', function(e) { e.stopPropagation(); }, true);
                frames[i].contentWindow.document.addEventListener('mouseup', function(e) { e.stopPropagation(); }, true);
                frames[i].contentWindow.document.addEventListener('keydown', function(e) { e.stopPropagation(); }, true);
                frames[i].contentWindow.document.addEventListener('keyup', function(e) { e.stopPropagation(); }, true);
                frames[i].contentWindow.document.addEventListener('keypress', function(e) { e.stopPropagation(); }, true);
            } catch (e) {
                // 忽略跨域 iframe 的错误
            }
        }

        // 添加选中文本事件监听器 - 自动复制选中文本
        document.addEventListener('mouseup', autoCopyHandler, false);
    }

    // 禁用复制功能的函数
    function disableCopy() {
        // 恢复默认事件
        document.removeEventListener('copy', function(e) { e.stopPropagation(); }, true);
        document.removeEventListener('cut', function(e) { e.stopPropagation(); }, true);
        document.removeEventListener('contextmenu', function(e) { e.stopPropagation(); }, true);
        document.removeEventListener('selectstart', function(e) { e.stopPropagation(); }, true);
        document.removeEventListener('mousedown', function(e) { e.stopPropagation(); }, true);
        document.removeEventListener('mouseup', function(e) { e.stopPropagation(); }, true);
        document.removeEventListener('keydown', function(e) { e.stopPropagation(); }, true);
        document.removeEventListener('keyup', function(e) { e.stopPropagation(); }, true);
        document.removeEventListener('keypress', function(e) { e.stopPropagation(); }, true);

        // 移除 CSS 样式限制
        var style = document.querySelector('style');
        if (style) {
            document.head.removeChild(style);
        }

        // 恢复默认 body 标签的 oncontextmenu 属性
        if (document.body) {
            document.body.oncontextmenu = null;
        }

        // 移除选中文本事件监听器
        document.removeEventListener('mouseup', autoCopyHandler, false);
    }

    // 自动复制选中文本的处理函数
    function autoCopyHandler() {
        var selectedText = window.getSelection().toString().trim();
        if (selectedText) {
            var tempTextarea = document.createElement('textarea');
            tempTextarea.style.position = 'fixed';
            tempTextarea.style.top = '0';
            tempTextarea.style.left = '0';
            tempTextarea.style.width = '2em';
            tempTextarea.style.height = '2em';
            tempTextarea.style.padding = '0';
            tempTextarea.style.border = 'none';
            tempTextarea.style.outline = 'none';
            tempTextarea.style.boxShadow = 'none';
            tempTextarea.style.background = 'transparent';
            tempTextarea.value = selectedText;
            document.body.appendChild(tempTextarea);
            tempTextarea.select();
            try {
                var successful = document.execCommand('copy');
                if (successful) {
                    console.log('选中文本已复制: ' + selectedText);
                } else {
                    console.error('复制失败');
                }
            } catch (err) {
                console.error('复制过程中出现异常', err);
            }
            document.body.removeChild(tempTextarea);
        }
    }

})();