Greasy Fork

Greasy Fork is available in English.

左键限制解除

左键选中

当前为 2025-02-13 提交的版本,查看 最新版本

// ==UserScript==
// @name              左键限制解除
// @description       左键选中
// @version           1
// @match             *://*/*
// @grant             none
// @run-at            document-start
// @namespace http://greasyfork.icu/users/12375
// ==/UserScript==

(() => {
    // 数值化事件类型 + 视频白名单
    const EV = {
        // 基础限制事件
        select: 1,          // 0b00000001
        selectstart: 2,     // 0b00000010
        copy: 4,            // 0b00000100
        cut: 8,             // 0b00001000
        contextmenu: 16,    // 0b00010000

        // 视频相关事件(白名单)
        mousedown: 32,      // 0b00100000
        mouseup: 64,        // 0b01000000
        mousemove: 128,     // 0b10000000
        click: 256          // 0b100000000
    };

    // 动态元素检测缓存
    const videoElements = new WeakMap();
    const isVideoControl = (target) => {
        while(target) {
            if(videoElements.has(target)) return videoElements.get(target);
            if(target.tagName === 'VIDEO' ||
               target.classList.contains('progress-bar') ||
               target.closest('video, [role="video-controls"]')) {
                videoElements.set(target, true);
                return true;
            }
            target = target.parentElement;
        }
        return false;
    };

    // 原始方法缓存
    const { addEventListener: protoAdd } = EventTarget.prototype;
    const { preventDefault: protoPrevent } = Event.prototype;

    // 智能事件拦截
    EventTarget.prototype.addEventListener = function(type, listener, options) {
        const eventFlag = EV[type] || 0;

        // 基础限制事件 + 非视频相关
        if(eventFlag & 0b00011111 && !isVideoControl(this)) {
            protoAdd.call(
                this,
                type,
                e => e.stopImmediatePropagation(),
                { capture: true, ...options }
            );
        }
        // 视频事件或非限制事件
        else {
            protoAdd.call(this, type, listener, options);
        }
    };

    // 动态默认行为控制
    Event.prototype.preventDefault = function() {
        const eventFlag = EV[this.type] || 0;
        const isVideo = isVideoControl(this.target);

        // 仅阻止:基础限制事件 + 非视频元素
        if((eventFlag & 0b00011111) && !isVideo) {
            return; // 不执行默认阻止
        } else {
            protoPrevent.call(this);
        }
    };

    // 左键解除专用通道
    document.addEventListener('click', e => {
        if(e.button === 0 && e.target.closest('#unlock-button')) {
            // 执行解除逻辑
            e.stopPropagation();
            handleUnlock();
        }
    }, { capture: true, passive: true });
})();