请不要污染我的剪贴板

保护用户剪贴板内容,允许或禁止网站污染剪贴板。

目前为 2024-12-04 提交的版本。查看 最新版本

// ==UserScript==
// @name         请不要污染我的剪贴板
// @namespace    Violentmonkey Scripts
// @version      0.5
// @description  保护用户剪贴板内容,允许或禁止网站污染剪贴板。
// @license      MIT
// @match        *://*/*
// @grant        none
// ==/UserScript==
/* jshint esversion: 8 */

(function () {
    'use strict';

    let clipboardPermission = null; // null 表示尚未选择,true 表示允许,false 表示拒绝
    let rejectCount = 0; // 拒绝次数计数
    const maxRejectCount = 3; // 最大允许拒绝次数

    function requestPermission(message) {
        if (clipboardPermission === true) {
            return true; // 如果已允许,直接返回
        }

        if (rejectCount >= maxRejectCount) {
            return false; // 超过拒绝次数限制后,直接禁止
        }

        const permission = confirm(message);

        if (permission) {
            clipboardPermission = true; // 用户允许
            return true;
        } else {
            rejectCount++;
            if (rejectCount >= maxRejectCount) {
                clipboardPermission = false; // 超过拒绝次数限制,锁定为禁止
            }
            return false;
        }
    }

    // 阻止网站篡改剪贴板内容,同时询问用户
    document.addEventListener(
        'copy',
        (e) => {
            const selection = window.getSelection().toString();

            if (!requestPermission('此网站试图修改复制到剪贴板的内容,是否允许?')) {
                // 用户拒绝操作,阻止修改
                e.stopImmediatePropagation();
                e.preventDefault();
                e.clipboardData.setData('text/plain', selection); // 保留用户原始内容
            }
        },
        true // 捕获阶段执行,优先阻止其他事件监听器
    );

    document.addEventListener(
        'cut',
        (e) => {
            const selection = window.getSelection().toString();

            if (!requestPermission('此网站试图修改剪切到剪贴板的内容,是否允许?')) {
                // 用户拒绝操作,阻止修改
                e.stopImmediatePropagation();
                e.preventDefault();
                e.clipboardData.setData('text/plain', selection); // 保留用户原始内容

                // 模拟剪切效果
                const range = window.getSelection().getRangeAt(0);
                range.deleteContents();
            }
        },
        true // 捕获阶段执行,优先阻止其他事件监听器
    );

    // 保护 clipboard API
    const originalWriteText = navigator.clipboard.writeText;
    navigator.clipboard.writeText = async function (text) {
        if (requestPermission('此网站试图写入内容到剪贴板,是否允许?')) {
            return originalWriteText.call(navigator.clipboard, text);
        } else {
            return Promise.reject('用户拒绝写入剪贴板');
        }
    };

    Object.defineProperty(navigator, 'clipboard', {
        configurable: false,
        enumerable: true,
        get: function () {
            return {
                writeText: navigator.clipboard.writeText,
            };
        }
    });
})();