getJsEnv

2025/5/12 16:24:41

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, Greasemonkey alebo Violentmonkey.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie, ako napríklad Tampermonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, % alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey alebo Userscripts.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie, ako napríklad Tampermonkey.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie správcu používateľských skriptov.

(Už mám správcu používateľských skriptov, nechajte ma ho nainštalovať!)

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

(Už mám správcu používateľských štýlov, nechajte ma ho nainštalovať!)

// ==UserScript==
// @name        getJsEnv
// @namespace   qchook
// @match       *://*/*
// @grant       none
// @version     1.0
// @author      cthousand
// @license MIT
// @description 2025/5/12 16:24:41
// ==/UserScript==

!function () {
    // 获取原型环境代码
    getProtoEnvCode = function getProtoEnvCode(proto, instanceObj) {
        // proto: 原型函数
        // instanceObj: 实例对象, 可选参数
        let code = "";
        let protoName = proto.name;
        // 添加注释
        code += `// ${protoName}对象\r\n`;
        // 定义原型
        code += `${protoName} = function ${protoName}(){`;
        try {
            new proto;
        } catch (e) {
            code += `return yqvm.toolsFunc.throwError("${e.name}", "${e.message}")`;
        }
        code += `}\r\n`;
        // 保护原型
        code += `yqvm.toolsFunc.safeProto(${protoName}, "${protoName}");\r\n`;
        // 设置原型链
        let protoObj = proto.prototype;
        let proto_protoName = Object.getPrototypeOf(protoObj)[Symbol.toStringTag];
        if (proto_protoName !== undefined) {
            code += `Object.setPrototypeOf(${protoName}.prototype, ${proto_protoName}.prototype);\r\n`;
        }
        // 设置原型的属性
        for (const key in Object.getOwnPropertyDescriptors(proto)) {
            if (key === "arguments" || key === "caller" || key === "length" || key === "name" || key === "prototype") {
                continue;
            }
            let descriptor = getDescriptor(proto, key, protoName, protoName, instanceObj);
            code += `yqvm.toolsFunc.defineProperty(${protoName}, "${key}", ${descriptor});\r\n`;
        }
        // 设置原型对象的属性
        for (const key in Object.getOwnPropertyDescriptors(proto.prototype)) {
            if (key === "constructor") {
                continue;
            }
            let descriptor = getDescriptor(proto.prototype, key, `${protoName}.prototype`, protoName, instanceObj);
            code += `yqvm.toolsFunc.defineProperty(${protoName}.prototype, "${key}", ${descriptor});\r\n`;
        }
        console.log(code);
        copy(code);
        // return code;
    }
    // 获取实例对象的环境代码
    getObjEnvCode = function getObjEnvCode(obj, objName, instanceObj) {
        let code = "";
        // 添加注释
        code += `// ${objName}对象\r\n`;
        // 定义对象
        code += `${objName} = {}\r\n`;
        // 设置原型
        let protoName = Object.getPrototypeOf(obj)[Symbol.toStringTag];
        if (protoName !== undefined) {
            code += `Object.setPrototypeOf(${objName}, ${protoName}.prototype);\r\n`;
        }
        for (const key in Object.getOwnPropertyDescriptors(obj)) {
            let descriptor = getDescriptor(obj, key, objName, objName, instanceObj);
            code += `yqvm.toolsFunc.defineProperty(${objName}, "${key}", ${descriptor});\r\n`;
        }
        console.log(code);
        copy(code);
    }

    // 获取属性描述符
    getDescriptor = function getDescriptor(obj, prop, objName, protoName, instanceObj) {
        let descriptor = Object.getOwnPropertyDescriptor(obj, prop);
        let configurable = descriptor.configurable;
        let enumerable = descriptor.enumerable;
        let code = `{configurable:${configurable}, enumerable:${enumerable}, `;
        if (descriptor.hasOwnProperty("writable")) {
            let writable = descriptor.writable;
            code += `writable:${writable}, `;
        }
        if (descriptor.hasOwnProperty("value")) {
            let value = descriptor.value;
            if (value instanceof Object) {
                if (typeof value === "function") {
                    code += `value:function (){return yqvm.toolsFunc.dispatch(this, ${objName}, "${protoName}", "${prop}", arguments)}`;
                } else {
                    // 需要关注
                    console.log("需要额外关注", value);
                    // JSON.stringify(value);
                    code += `value:{}`
                }
            } else if (typeof value === 'symbol') {
                code += `value:${value.toString()}`;
            } else if (typeof value === "string") {
                code += `value:"${value}"`;
            } else {
                code += `value:${value}`;
            }
        }
        if (descriptor.hasOwnProperty("get")) {
            let get = descriptor.get;
            if (typeof get === "function") {
                let defaultValue;
                try {
                    defaultValue = get.call(instanceObj);
                } catch (e) { }
                if (defaultValue === undefined || defaultValue instanceof Object) {
                    code += `get:function (){return yqvm.toolsFunc.dispatch(this, ${objName}, "${protoName}", "${prop}_get", arguments)}, `;
                } else {
                    if (typeof defaultValue === "string") {
                        code += `get:function (){return yqvm.toolsFunc.dispatch(this, ${objName}, "${protoName}", "${prop}_get", arguments, '${defaultValue}')}, `;
                    } else if (typeof value === 'symbol') {
                        code += `get:function (){return yqvm.toolsFunc.dispatch(this, ${objName}, "${protoName}", "${prop}_get", arguments, ${defaultValue.toString()})}, `;
                    } else {
                        code += `get:function (){return yqvm.toolsFunc.dispatch(this, ${objName}, "${protoName}", "${prop}_get", arguments, ${defaultValue})}, `;
                    }
                }
            } else {
                code += `get:undefined, `
            }
        }
        if (descriptor.hasOwnProperty("set")) {
            let set = descriptor.set;
            if (typeof set === "function") {
                code += `set:function (){return yqvm.toolsFunc.dispatch(this, ${objName}, "${protoName}", "${prop}_set", arguments)}`;
            } else {
                code += `set:undefined`
            }
        }
        code += '}';
        return code;
    }
}()