TankTrouble Development Library

Shared library for TankTrouble userscript development

目前為 2023-12-26 提交的版本,檢視 最新版本

此腳本不應該直接安裝,它是一個供其他腳本使用的函式庫。欲使用本函式庫,請在腳本 metadata 寫上: // @require https://update.gf.qytechs.cn/scripts/482092/1301930/TankTrouble%20Development%20Library.js

// ==UserScript==
// @name        TankTrouble Development Library
// @author      commander
// @namespace   https://github.com/asger-finding
// @version     0.0.5
// @license     GPL-3.0
// @description Shared library for TankTrouble userscript development
// @match       *://*.tanktrouble.com/*
// @grant       none
// @run-at      document-start
// @noframes
// ==/UserScript==

/* eslint-disable no-unused-vars */

class Loader {

	/**
	 * Pass a function to a hook with the correct context
	 * @param context Function context (e.g `window`)
	 * @param funcName Function identifier in the context
	 * @param hook Hook to call before the original
	 */
	static hookFunction(context, funcName, hook) {
		const original = Reflect.get(context, funcName);
		if (typeof original !== 'function') throw new Error('Item passed is not typeof function');

		Reflect.defineProperty(context, funcName, {
			/**
			 * Call the hook with the original function bound to its context
			 * and supply with the arguments list
			 * @param args Arguments passed from outside
			 * @returns Original function return value
			 */
			value: (...args) => hook(original.bind(context), ...args)
		});
	}

	/**
	 * Fires when the `main()` function is done on TankTrouble.
	 * @returns Promise that resolves when Content.init() finishes
	 */
	static whenContentInitialized() {
		if (GM.info.script.runAt !== 'document-start') return Loader.#hookContentInit();
		return whenContentLoaded().then(() => Loader.#hookContentInit());
	}

	/**
	 * Fires when the document is readyState `interactive` or `complete`
	 * @returns Promise that resolves upon content loaded
	 */
	static whenContentLoaded() {
		return new Promise(resolve => {
			if (document.readyState === 'interactive' || document.readyState === 'complete') resolve();
			else document.addEventListener('DOMContentLoaded', () => resolve());
		});
	}

	/**
	 * Apply a hook to the Content.init function which resolves when the promise ends
	 * @returns Promise when Content.init has finished
	 * @private
	 */
	static #hookContentInit() {
		return new Promise(resolve => {
			const { init } = Content;
			Reflect.defineProperty(Content, 'init', {
				/**
				 * Resolve after Content.init call finishes
				 * @param args Arguments to pass
				 * @returns Function call return value
				 */
				value: (...args) => {
					const result = init(...args);

					resolve();
					return result;
				}
			});
		});
	}

}

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址