让你的飞书更好用(优化版)

让飞书文档不受权限限制,可以复制任意内容,可以打开右键菜单(复制下载图片)

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください。
// ==UserScript==
// @name         让你的飞书更好用(优化版)
// @license      GPL License
// @namespace    https://bytedance.com
// @version      0.5
// @description  让飞书文档不受权限限制,可以复制任意内容,可以打开右键菜单(复制下载图片)
// @author       NOABC
// @match        *://*.feishu.cn/*
// @match        *://*.larkoffice.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=feishu.cn
// @grant        none
// @run-at       document-start
// ==/UserScript==
(function () {
    // Override addEventListener to handle copy and contextmenu events
    const overrideEventListeners = () => {
        const rawAddEventListener = EventTarget.prototype.addEventListener;
        EventTarget.prototype.addEventListener = function (type, listener, options) {
            if (type === 'copy') {
                rawAddEventListener.call(this, type, event => {
                    event.stopImmediatePropagation();
                    return null;
                }, options);
                return;
            }
            if (type === 'contextmenu') {
                rawAddEventListener.call(this, type, event => {
                    event.stopImmediatePropagation();
                    return listener(event);
                }, options);
                return;
            }
            rawAddEventListener.call(this, type, listener, options);
        };
    };

    // Override XMLHttpRequest to manipulate permission responses
    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);
        };
    };

    // Run overrides immediately and on DOMContentLoaded
    overrideEventListeners();
    overrideXHR();
    document.addEventListener('DOMContentLoaded', () => {
        overrideEventListeners();
        overrideXHR();
    });
})();