Greasy Fork

Greasy Fork is available in English.

【最强】【重大更新】解除禁止复制和粘贴限制并支持手动粘贴(全网页适用)

⭐学习通⭐pta⭐csdn⭐飞书云文档⭐破解所有网站【禁止复制】和【禁止粘贴】限制,支持【模拟人工输入】。安装后,打开目标网页即可解除限制。若粘贴解锁不生效,可以使用ctrl+m呼出浮动输入框进行模拟人工输入,详情请阅读下方说明。有疑问或者反馈都可以发我邮箱啊:[email protected]

当前为 2024-11-07 提交的版本,查看 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         【最强】【重大更新】解除禁止复制和粘贴限制并支持手动粘贴(全网页适用)
// @namespace    http://jiangning_sama/pojie_cpoy.net/
// @version      7.1.2
// @description  ⭐学习通⭐pta⭐csdn⭐飞书云文档⭐破解所有网站【禁止复制】和【禁止粘贴】限制,支持【模拟人工输入】。安装后,打开目标网页即可解除限制。若粘贴解锁不生效,可以使用ctrl+m呼出浮动输入框进行模拟人工输入,详情请阅读下方说明。有疑问或者反馈都可以发我邮箱啊:[email protected]
// @author       江宁sama
// @match        *://*/*
// @exclude      https://chatgpt.com/*
// @exclude      https://www.bilibili.com/*
// @exclude      https://www.bing.com/*
// @exclude      https://fanyi.*/*
// @grant        none
// @run-at       document-start
// @license      MIT
// ==/UserScript==

/*
 * 免责声明:
 * 本脚本为教育和学习用途而开发,旨在帮助用户了解网页元素的控制与交互操作。
 * 使用本脚本即表示用户同意自行承担由此带来的一切风险和后果,开发者不对因使用本脚本
 * 造成的任何直接或间接损失负责。
 * 
 * 请勿使用本脚本用于任何违反服务条款、侵害他人权益或违反当地法律法规的行为。
 * 建议仅在个人测试环境中使用,不建议用于生产环境或未经授权的网页。
 * 
 * 使用前请务必仔细阅读本免责声明,开发者保留随时更改或终止该脚本的权利。
 */

(function () {
    'use strict';
    const isFeishuPage = /feishu\.cn|larkoffice\.com/.test(window.location.hostname);

    // 飞书专用功能
    function feishuScript() {
        const overrideEventListeners = () => {
            const rawAddEventListener = EventTarget.prototype.addEventListener;
            EventTarget.prototype.addEventListener = function (type, listener, options) {
                if (type === 'copy') {
                    rawAddEventListener.call(this, type, event => event.stopImmediatePropagation(), options);
                    return;
                }
                if (type === 'contextmenu') {
                    rawAddEventListener.call(this, type, event => {
                        event.stopImmediatePropagation();
                        return listener(event);
                    }, options);
                    return;
                }
                rawAddEventListener.call(this, type, listener, options);
            };
        };

        const overrideXHR = () => {
            const rawOpen = XMLHttpRequest.prototype.open;
            XMLHttpRequest.prototype.open = function (method, url, ...rest) {
                this.addEventListener('readystatechange', function () {
                    if (this.readyState === 4 && url.includes('space/api/suite/permission/document/actions/state/')) {
                        let response = this.responseText;
                        try {
                            response = JSON.parse(response);
                            if (response.data && response.data.actions && response.data.actions.copy !== 1) {
                                response.data.actions.copy = 1;
                                Object.defineProperty(this, 'responseText', { value: JSON.stringify(response) });
                                Object.defineProperty(this, 'response', { value: response });
                            }
                        } catch (e) {
                            console.error('Failed to modify response:', e);
                        }
                    }
                }, false);
                rawOpen.call(this, method, url, ...rest);
            };
        };

        overrideEventListeners();
        overrideXHR();
    }

    // 通用功能
    function universalUnlockScript() {
        const unlockCopyPaste = () => {
            document.body.removeAttribute('onselectstart');
            document.body.style.userSelect = 'auto';
            document.documentElement.style.userSelect = 'auto';
            const elements = document.querySelectorAll('*');
            elements.forEach((el) => {
                el.style.userSelect = 'auto';
                el.style.pointerEvents = 'auto';
                el.removeAttribute('oncopy');
                el.removeAttribute('oncut');
                el.removeAttribute('onpaste');
                el.removeAttribute('oncontextmenu');
                el.removeAttribute('onmousedown');
                el.removeAttribute('onselectstart');
            });

            const eventTypes = ['copy', 'cut', 'paste', 'contextmenu', 'selectstart', 'mousedown'];
            eventTypes.forEach((eventType) => {
                document.addEventListener(eventType, (e) => e.stopPropagation(), true);
            });
        };

        document.addEventListener('DOMContentLoaded', unlockCopyPaste);
    }

    // 判断
    if (isFeishuPage) {
        feishuScript();  
    } else {
        universalUnlockScript(); 
    }

    function removeVipMask() {
        const vipMask = document.querySelector('div.hide-article-box.hide-article-pos.text-center');
        if (vipMask) {
            vipMask.remove();
        }
    }

    // 优化:使用 MutationObserver 监听 DOM 变化,避免轮询
    function observeVipMask() {
        const observer = new MutationObserver(removeVipMask);
        observer.observe(document.body, { childList: true, subtree: true });
    }

    // 初始化时移除遮罩层并开始监听
    document.addEventListener('DOMContentLoaded', () => {
        removeVipMask();
        observeVipMask();
    });

    // 手动粘贴功能
    let targetElement = null;
    document.addEventListener('keydown', function(event) {
        if (event.ctrlKey && event.key === 'm') {
            event.preventDefault();
            targetElement = document.activeElement;
            createFloatingInputBox();
        }
    });

    // 创建浮动输入框
    function createFloatingInputBox() {
        if (document.getElementById('floatingInputBox')) return;

        const floatingBox = document.createElement('div');
        floatingBox.id = 'floatingInputBox';
        floatingBox.style.position = 'fixed';
        floatingBox.style.top = '20px';
        floatingBox.style.right = '20px';
        floatingBox.style.width = '300px';
        floatingBox.style.padding = '10px';
        floatingBox.style.backgroundColor = 'white';
        floatingBox.style.border = '1px solid black';
        floatingBox.style.zIndex = '10000';

        const textarea = document.createElement('textarea');
        textarea.style.width = '100%';
        textarea.style.height = '80px';
        textarea.placeholder = '在此粘贴内容,然后按 Enter';
        textarea.addEventListener('keydown', function(e) {
            if (e.key === 'Enter') {
                e.preventDefault();
                const text = textarea.value;
                document.body.removeChild(floatingBox);
                if (targetElement) {
                    typeTextSlowly(targetElement, text);
                }
            }
        });

        floatingBox.appendChild(textarea);
        document.body.appendChild(floatingBox);
        textarea.focus();
    }

    // 输出
    function typeTextSlowly(element, text) {
        let i = 0;

        function typeChar() {
            if (i < text.length) {
                insertChar(element, text[i]);
                i++;
                requestAnimationFrame(typeChar);
            }
        }
        typeChar();
    }

    function insertChar(element, char) {
        if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA') {
            const start = element.selectionStart;
            const end = element.selectionEnd;
            const value = element.value;
            element.value = value.substring(0, start) + char + value.substring(end);
            element.selectionStart = element.selectionEnd = start + 1;

            const inputEvent = new Event('input', { bubbles: true });
            element.dispatchEvent(inputEvent);
        } else if (element.isContentEditable) {
            const textNode = document.createTextNode(char);
            const selection = window.getSelection();
            const range = selection.getRangeAt(0);

            range.insertNode(textNode);
            range.setStartAfter(textNode);
            selection.removeAllRanges();
            selection.addRange(range);
        }
    }

})();