Enable Copy-Paste

Force-enables copy, paste, context menu, and keyboard shortcuts by monkey-patching and piercing Shadow DOM.

Bu betiği kurabilmeniz için Tampermonkey, Greasemonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği kurabilmeniz için Tampermonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği kurabilmeniz için Tampermonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği kurabilmeniz için Tampermonkey ya da Userscripts gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

You will need to install an extension such as Tampermonkey to install this script.

Bu komut dosyasını yüklemek için bir kullanıcı komut dosyası yöneticisi uzantısı yüklemeniz gerekecek.

(Zaten bir kullanıcı komut dosyası yöneticim var, kurmama izin verin!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(Zateb bir user-style yöneticim var, yükleyeyim!)

// ==UserScript==
// @name         Enable Copy-Paste
// @version      3.0
// @description  Force-enables copy, paste, context menu, and keyboard shortcuts by monkey-patching and piercing Shadow DOM.
// @description:en Force-enables copy, paste, context menu, and keyboard shortcuts by monkey-patching and piercing Shadow DOM.
// @match        *://*/*
// @grant        GM_addStyle
// @run-at       document-start
// @namespace    http://tampermonkey.net/
// @license      LGPL-2.1
// ==/UserScript==

(function() {
    'use strict';

    // 1. Define CSS rules
    const cssRule = `
        *, *::before, *::after {
            -webkit-user-select: auto !important;
            -moz-user-select: auto !important;
            -ms-user-select: auto !important;
            user-select: auto !important;
            -webkit-touch-callout: auto !important;
        }
    `;

    // 2. Inject CSS (Light DOM)
    GM_addStyle(cssRule);

    // 3. Pierce Shadow DOM
    const originalAttachShadow = Element.prototype.attachShadow;
    Element.prototype.attachShadow = function(options) {
        const shadowRoot = originalAttachShadow.call(this, options);
        const style = document.createElement('style');
        style.textContent = cssRule;
        shadowRoot.appendChild(style);
        return shadowRoot;
    };

    // 4. Block Event Listeners

    // Events to simply block
    const simpleForbiddenEvents = [
        'copy', 'paste', 'cut',
        'selectstart',
        'contextmenu',
        'dragstart'
    ];

    // Keyboard events for smart handling
    const keyboardEvents = ['keydown', 'keyup', 'keypress'];

    // Shortcut detection
    const isShortcut = (e) => {
        return (e.ctrlKey || e.metaKey) &&
               ['c', 'v', 'x', 'a', 'insert'].includes(e.key.toLowerCase());
    };

    // Override addEventListener
    const originalAddEventListener = EventTarget.prototype.addEventListener;

    EventTarget.prototype.addEventListener = function(type, listener, options) {

        if (simpleForbiddenEvents.includes(type)) {
            console.log(`[Anti-Restrict] Blocked ${type} event listener.`);
            return;
        }

        if (keyboardEvents.includes(type)) {
            const wrappedListener = function(event) {
                if (isShortcut(event)) {
                    console.log(`[Anti-Restrict] Bypassed shortcut in ${type} event.`);
                    event.stopImmediatePropagation();
                } else {
                    Reflect.apply(listener, this, arguments);
                }
            };

            originalAddEventListener.call(this, type, wrappedListener, options);
            return;
        }

        originalAddEventListener.call(this, type, listener, options);
    };

    // 5. Clean up on* event handlers
    const clearOnEventHandlers = () => {
        const targets = [window, document, document.body];
        const eventHandlers = [
            'oncontextmenu', 'oncopy', 'oncut', 'onpaste',
            'onselectstart', 'ondragstart',
            'onkeydown', 'onkeyup', 'onkeypress'
        ];

        for (const target of targets) {
            if (!target) continue;
            for (const handler of eventHandlers) {
                try {
                    if (target[handler]) {
                        target[handler] = null;
                    }
                    Object.defineProperty(target, handler, {
                        value: null,
                        writable: true,
                        configurable: true
                    });
                } catch (e) {
                    // Ignore errors
                }
            }
        }
    };

    clearOnEventHandlers();
    window.addEventListener('load', clearOnEventHandlers);
    setTimeout(clearOnEventHandlers, 1500);

})();