Greasy Fork is available in English.
默认禁止网页自动写入剪贴板,可通过脚本菜单允许写入剪贴板
// ==UserScript==
// @name 剪贴板保护控制
// @version 1.1
// @description 默认禁止网页自动写入剪贴板,可通过脚本菜单允许写入剪贴板
// @author Gemini
// @match *://*/*
// @run-at document-start
// @grant GM_registerMenuCommand
// @grant GM_unregisterMenuCommand
// @grant GM_setValue
// @grant GM_getValue
// @namespace http://greasyfork.icu/users/452911
// ==/UserScript==
(function() {
'use strict';
if (window.__GUARD_REINFORCED__) return;
window.__GUARD_REINFORCED__ = true;
// 生成当前域名唯一的存储 Key
const STORAGE_KEY = `cb_protect_${location.hostname}`;
let isUserSelection = false;
// 核心判定逻辑
function canWrite() {
// 读取当前域名的独立设置,如果没有设置过,默认返回 true (开启保护)
const protectionEnabled = GM_getValue(STORAGE_KEY, true);
if (!protectionEnabled) return true; // 已手动信任该域名
return isUserSelection; // 保护中:仅允许用户选中的写入
}
// --- 拦截逻辑 ---
if (navigator.clipboard) {
const originalWriteText = navigator.clipboard.writeText.bind(navigator.clipboard);
Object.defineProperty(navigator.clipboard, 'writeText', {
value: function(text) {
if (canWrite()) return originalWriteText(text);
console.warn(`🛡️ [${location.hostname}] 自动写入被拦截`);
return Promise.resolve();
}, configurable: true
});
if (navigator.clipboard.write) {
const originalWrite = navigator.clipboard.write.bind(navigator.clipboard);
Object.defineProperty(navigator.clipboard, 'write', {
value: async function(data) {
if (canWrite()) return originalWrite(data);
console.warn(`🛡️ [${location.hostname}] 自动写入被拦截`);
return Promise.resolve();
}, configurable: true
});
}
}
const originalExec = document.execCommand.bind(document);
document.execCommand = function(cmd) {
if (cmd === 'copy') {
const text = window.getSelection().toString();
if (canWrite()) return originalExec.apply(document, arguments);
return true;
}
return originalExec.apply(document, arguments);
};
document.addEventListener('copy', (e) => {
const text = window.getSelection().toString();
if (!canWrite()) {
e.stopImmediatePropagation();
e.preventDefault();
}
}, true);
// --- 意图识别 ---
document.addEventListener('selectionchange', () => {
isUserSelection = window.getSelection().toString().trim().length > 0;
}, true);
document.addEventListener('mousedown', () => {
setTimeout(() => {
if (!window.getSelection().toString().trim()) isUserSelection = false;
}, 0);
}, true);
// --- 分域名菜单控制 ---
let menuId;
function updateMenu() {
if (menuId) GM_unregisterMenuCommand(menuId);
const isProtected = GM_getValue(STORAGE_KEY, true);
const statusIcon = isProtected ? "🛡️" : "⚠️";
const actionText = isProtected ? "保护中 (点击在此网站禁用)" : "已信任 (点击开启保护)";
menuId = GM_registerMenuCommand(`${statusIcon} ${location.hostname}: ${actionText}`, () => {
GM_setValue(STORAGE_KEY, !isProtected);
updateMenu();
// 💡 提示:因为逻辑是动态判断 STORAGE_KEY 的,所以切换后立即生效,无需刷新页面
});
}
updateMenu();
})();