您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
一个旨在智能解除网页复制限制的油猴脚本。
// ==UserScript== // @name 解除复制限制 Lift Copy Restrictions // @name:en Lift Copy Restrictions // @name:zh-CN 解除复制限制 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAB2AAAAdgB+lymcgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAALvSURBVHic7Zu7bhNBFIa/oBCaUMe5VbTwElQkAlFyqSmICBHkHeANQKkoeANQkkcgoSAyDR1CioHWkHURJcamGC+yVrvenTlzPEM0v3Qk27NzLr93zpyZnYWEhISEybgCPAUOgR4wDCQ94ADYBOZUIx7DMtBWCkgiR8CSYtyA+edjDD6XTyjfCVsRBFknT9SiBz5aOqONFWC/YPNA02BGXAQArBZsnkgVzkxosw1qki6fKPolsntJ0vkiQJOAdaCDe4LrAGuK/tXC1uEiJMHnctzALxE0c4CvxFinN+UACRIBoR0IjURAaAdCIxEQ2oHQ0CTguwcdHQ86nCGtBNcwlZykCrzVwC8R/sfVoFekHKCoW7IIKkMLeInZp+yNpA28ABZiCEDaf5KuB0zeks+A+7Jw5QFI+1fpeggMGvQZ4JmEGAhoYbc3mWE5HDRzwIxAcmwB82PfT4HnwCLmwcj26Lcc85inWF7gI3FJ8blg41nJNduFa9q+jMcwBIq3f6vEzkLhmswmyFi3xHJdRR3ei61UCIV2IDRmFXVrrA3eAdcxuWCIWS1+A3aB9/hZgf5DDLOAjf0/wFvMFDl145JZoAq3HXwYAr8xT6XECEnAI8w/6jqN9oENx7itA/BNwB1kwY+TILoTQhDQAroegs/lF+XF01QIcMEbB7t1suPqzLQJWAXOHOzWyTnmtFspYtgRynEPuNxAb9XKsQqzwN2qxpgqwZuKuiuTYUwE3FDUfa2qIYbVYN7vFHM4U8NOD7ha1hDTWuCMZgS4YFDVENMQ+Kmo+0dVQ0wEfA2hOyYC9hV177l0mnYhtIIpWjQKIaej9SFK4R0Hu3XyytWZE0tDPrCIWcD4Cr6L4LnhoaUxX1jHLGWlwfcRHrXd9OCE6zDaEJLQBx5LggfzOspRIALA3Akuw6FL+ckSJyxNmYQiWpjE2GR2OAdeo3BWYA7zbs4H7N8ikRKQYxkzLPaALyM/stHnXcztrv4WWUJCwsXDX4QDCPtESJvBAAAAAElFTkSuQmCC // @namespace https://github.com/zhumengstarsandsea/Lift_Copy_Restrictions // @version 1.1 // @description:en A Userscript designed to intelligently bypass copy restrictions on web pages. // @description:zh-CN 一个旨在智能解除网页复制限制的油猴脚本。 // @author zhumengstarsandsea // @license AGPL-3.0-only // @match http://*/* // @match https://*/* // @grant GM_setValue // @grant GM_getValue // @grant GM_registerMenuCommand // @grant GM_unregisterMenuCommand // @grant unsafeWindow // @run-at document-start // @description 一个旨在智能解除网页复制限制的油猴脚本。 // ==/UserScript== 'use strict'; (function (global) { const currentHostname = global.location.hostname; const currentHref = global.location.href; // ================================================================================= // == SECTION 1: 特殊网站名单与专属处理逻辑 // ================================================================================= const SPECIAL_SITES = { 'doc88.com': { regexp: /.*doc88\.com\/.+/, init: function() { global.addEventListener("DOMContentLoaded", () => { const original_html = document.body.innerHTML; setTimeout(() => { document.body.innerHTML = original_html; }, 5000); }); } }, 'segmentfault.com': { regexp: /.*segmentfault\.com\/.+/, init: function() { const body = document.querySelector("body"); if (body) { body.classList.add("_sf_adjust_body"); } } }, 'wk.baidu.com': { regexp: /.*wk\.baidu\.com\/view\/.+/, init: function() { if (unsafeWindow.sf) { unsafeWindow.sf.canCopy = 1; } } }, 'zhihu.com': { regexp: /.*zhihu\.com\/.*/, init: function() { const observer = new MutationObserver((mutationsList) => { for (const mutation of mutationsList) { for (const node of mutation.addedNodes) { if (node.nodeType === 1 && node.querySelector('.Modal-wrapper')) { node.remove(); } } } }); observer.observe(document.body, { childList: true, subtree: true }); } }, 'docs.qq.com': { regexp: /.*docs\.qq\.com\/(doc|sheet|slide)\/.+/, init: function() { document.addEventListener('DOMContentLoaded', () => { if(unsafeWindow.pad?.editor){ unsafeWindow.pad.editor.isCopyable = () => true; } }); } }, 'wenku.baidu.com': { regexp: /wenku.baidu.com/, init: function() { // 使用一个内部变量来存储 pageData,防止无限循环 let _internalPageData = undefined; Object.defineProperty(unsafeWindow, 'pageData', { set: (v) => { _internalPageData = v; }, get: () => { if (_internalPageData && _internalPageData.vipInfo) { _internalPageData.vipInfo.global_svip_status = 1; _internalPageData.vipInfo.isVip = 1; } return _internalPageData; }, configurable: true }); } }, 'kdocs.cn': { regexp: /.*kdocs\.cn\/.*/, init: function() { let _APP = undefined; if (unsafeWindow.APP) { unsafeWindow.APP.canCopy = () => true; } else { Object.defineProperty(unsafeWindow, "APP", { set: (v) => { _APP = v; if(v) v.canCopy = () => true; }, get: () => _APP, configurable: true }); } } } }; // ================================================================================= // == SECTION 2: 通用解除限制功能 (白名单网站使用) // ================================================================================= function applyUniversalMode() { enhancerModule.log(`通用模式已为 ${currentHostname} 激活`, 'success'); const style = 'body, body *{-webkit-user-select:auto!important;-moz-user-select:auto!important;-ms-user-select:auto!important;user-select:auto!important}'; const styleNode = document.createElement('style'); styleNode.textContent = style; document.head ? document.head.appendChild(styleNode) : document.addEventListener('DOMContentLoaded', () => document.head.appendChild(styleNode)); const events = ['copy', 'contextmenu', 'selectstart', 'dragstart', 'mousedown', 'keydown']; const stopPropagation = e => e.stopPropagation(); const removeEventListeners = () => { events.forEach(event => { document.addEventListener(event, stopPropagation, true); }); document.oncontextmenu = document.oncopy = document.onselectstart = null; }; let attempts = 0; const intervalId = setInterval(() => { removeEventListeners(); if (++attempts >= 5) clearInterval(intervalId); }, 500); } // ================================================================================= // == SECTION 3: 菜单命令与主逻辑 // ================================================================================= const enhancerModule = { log(message, type = 'info') { const style = { info: 'color: #03a9f4;', success: 'color: #28a745; font-weight: bold;', warn: 'color: #ffc107;', error: 'color: #dc3545; font-weight: bold;',} [type]; console.log(`%c[Copying Lifted] ${message}`, style); }, async getWhitelist() { return (await GM_getValue('whitelist', [])); }, async setWhitelist(list) { await GM_setValue('whitelist', list); }, async addToWhitelist() { const list = await this.getWhitelist(); if (!list.includes(currentHostname)) { list.push(currentHostname); await this.setWhitelist(list); this.log(`${currentHostname} 已加入白名单`, 'success'); global.location.reload(); } }, async removeFromWhitelist() { let list = await this.getWhitelist(); if (list.includes(currentHostname)) { list = list.filter(item => item !== currentHostname); await this.setWhitelist(list); this.log(`${currentHostname} 已移出白名单`, 'warn'); global.location.reload(); } }, async registerMenuCommands(isWhitelisted) { if (global.menuIds) { global.menuIds.forEach(id => GM_unregisterMenuCommand(id)); } global.menuIds = []; if (isWhitelisted) { global.menuIds.push(GM_registerMenuCommand('❌ 移出解除名单', this.removeFromWhitelist.bind(this))); } else { global.menuIds.push(GM_registerMenuCommand('✅ 加入解除名单', this.addToWhitelist.bind(this))); } }, async run() { // **【v1.1 核心修复】检查是否为特殊网站 for (const key in SPECIAL_SITES) { if (currentHostname.includes(key)) { this.log(`检测到特殊网站: ${key},执行专属方案`, 'success'); if (SPECIAL_SITES[key].init) { try { SPECIAL_SITES[key].init.call(this); } catch (e) { this.log(`在 ${key} 上执行专属方案时出错: ${e}`, 'error'); } } // **【v1.1 核心修复】执行完专属方案后,立即返回,不再执行通用逻辑 return; } } // 如果不是特殊网站,则继续走白名单逻辑 const whitelist = await this.getWhitelist(); const isWhitelisted = whitelist.includes(currentHostname); this.registerMenuCommands(isWhitelisted); if (isWhitelisted) { applyUniversalMode(); } else { this.log(`当前网站 ${currentHostname} 未在白名单中,脚本待命中`, 'info'); } } }; enhancerModule.run(); }(window));