🎉 欢迎访问GreasyFork.Org 镜像站!本镜像站由公众号【爱吃馍】搭建,用于分享脚本。联系邮箱📮

Greasy fork 爱吃馍镜像

Greasy Fork is available in English.

📂 缓存分发状态(共享加速已生效)
🕒 页面同步时间:2026/02/03 03:18:56
🔄 下次更新时间:2026/02/03 04:18:56
手动刷新缓存

Hooks

A JavaScript hook/reply ultility

Este script não deve ser instalado diretamente. Este script é uma biblioteca de outros scripts para incluir com o diretório meta // @require https://update.greasyfork.org/scripts/18715/661566/Hooks.js

Você precisará instalar uma extensão como Tampermonkey, Greasemonkey ou Violentmonkey para instalar este script.

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

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Userscripts para instalar este script.

Você precisará instalar uma extensão como o Tampermonkey para instalar este script.

Você precisará instalar um gerenciador de scripts de usuário para instalar este script.

(Eu já tenho um gerenciador de scripts de usuário, me deixe instalá-lo!)

🚀 安装遇到问题?关注公众号获取帮助

公众号二维码

扫码关注【爱吃馍】

回复【脚本】获取最新教程和防失联地址

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

(Eu já possuo um gerenciador de estilos de usuário, me deixar fazer a instalação!)

🚀 安装遇到问题?关注公众号获取帮助

公众号二维码

扫码关注【爱吃馍】

回复【脚本】获取最新教程和防失联地址

// ==UserScript==
// @name			Hooks
// @namespace		[email protected]
// @description		A JavaScript hook/reply ultility
// @author			xymopen
// @version			1.1.5
// @grant			none
// @license			BSD 2-Clause
// ==/UserScript==

// @updateURL		https://raw.githubusercontent.com/xymopen/JS_Misc/master/Hooks.js

// I was finishing unit test and found there are some bugs about the logic

/**
 * Hooks functions or properties, getters/setters
 * and methods of an object you are intrested in
 */

var Hooks = ( function () {
	"use strict";

	var Functions = {
		/**
		 * wrapper a function
		 * @param {Function} target
		 * @param {(Function, Object?, Arguments) => void} onApply
		 */
		apply: function apply( target, onApply ) {
			if ( "function" === typeof target && "function" === typeof onApply ) {
				var fn = function () {
					return onApply.call( this, target, this, arguments );
				};

				fn.prototype = target.prototype;

				return fn;
			} else {
				throw new TypeError();
			}
		}
	};

	/**
	 * Hooks functions or properties, getters/setters
	 * and methods of an object you are intrested in
	 */
	var Hooks = {
		/**
		 * hook a property of an object
		 * @param {Object} target				- an object having or to have the property to be hooked
		 * @param {String} propertyName			- the name of the property to be hooked
		 * @param {Function} onGet					- the hook call when about to get the property
		 * @param {Function} onSet					- the hook call when about to set the property
		 */
		property: function property( target, propertyName, onGet, onSet ) {
			var descriptor, oldValue;

			if ( Object.prototype.hasOwnProperty.call( target, propertyName ) ) {
				descriptor = Object.getOwnPropertyDescriptor( target, propertyName );

				if ( Object.prototype.hasOwnProperty.call( descriptor, "value" ) ) {
					oldValue = descriptor.value;

					delete descriptor.value;
					delete descriptor.writable;
				} else if ( Object.prototype.hasOwnProperty.call( descriptor, "get" ) ) {
					oldValue = descriptor.get.call( target );
				} else {
					oldValue = undefined;
				}
			} else {
				descriptor = {
					configurable: true,
					enumerable: true,
				};

				oldValue = undefined;
			}

			descriptor.get = function get() {
				return onGet.call( this, target, propertyName, oldValue );
			};

			descriptor.set = function set( newValue ) {
				oldValue = onSet.call( this, target, propertyName, oldValue, newValue );
			};

			Object.defineProperty( target, propertyName, descriptor );
		},
		/**
		 * the hook call when about to get the property
		 * @callback onGet
		 * @param {object} target				- the object having the property hooked
		 * @param {string} propertyName			- the name of the property hooked
		 * @param {any} oldValue				- the current value of the property
		 */

		/**
		 * the hook call when about to set the property
		 * @callback onSet
		 * @param {object} target				- the object having the property hooked
		 * @param {string} propertyName			- the name of the property hooked
		 * @param {any} oldValue				- the current value of the property
		 * @param {any} newValue				- the value about to be set to the property
		 */

		/**
		 * alias of #property but fill the #onSet automatically
		 * @function get
		 * @param {Object} target				- an object having or to have the property to be hooked
		 * @param {String} propertyName			- he name of the property to be hooked
		 * @param {onGet} onGet					- the hook call when about to get the property
		 */
		get: function get( target, propertyName, onGet ) {
			return Hooks.property( target, propertyName, onGet, function ( target, propertyName, oldValue, newValue ) {
				return Hooks.Reply.set( arguments );
			} );
		},

		/**
		 * alias of #property but fill the #onGet automatically
		 * @function set
		 * @param {Object} target				- an object having or to have the property to be hooked
		 * @param {String} propertyName			- the name of the property to be hooked
		 * @param {onSet} onSet					- the hook call when about to set the property
		 */
		set: function set( target, propertyName, onSet ) {
			return Hooks.property( target, propertyName, function ( target, propertyName, oldValue ) {
				return Hooks.Reply.get( arguments );
			}, onSet );
		},

		/**
		 * hook a getter property of an object
		 * @function getter
		 * @param {object} target				- an object having the getter property to be hooked
		 * @param {string} propertyName			- the name of the getter property to be hooked
		 * @param {onGetter} onGetter				- the hook replace the getter
		 */
		getter: function getter( target, propertyName, onGetter ) {
			var descriptor;

			if ( Object.prototype.hasOwnProperty.call( target, propertyName ) ) {
				descriptor = Object.getOwnPropertyDescriptor( target, propertyName );

				if ( Object.prototype.hasOwnProperty.call( descriptor, "get" ) ) {
					descriptor.get = Functions.apply( descriptor.get, function ( getter, thisArg, args ) {
						return onGetter.call( this, target, propertyName, getter, thisArg, args );
					} );

					Object.defineProperty( target, propertyName, descriptor );
				}
			}
		},
		/**
		 * the hook replace the getter
		 * @callback onSetter
		 * @param {object} target				- the object having the getter property hooked
		 * @param {string} propertyName			- he name of the getter property hooked
		 * @param {function} getter				- the getter replaced
		 * @param {object|undefined} thisArg	- #this reference
		 * @param {arguments} args				- the arguments pass to the getter, should be #undefined
		 */

		/**
		 * hook a setter property of an object
		 * @function setter
		 * @param {object} target				- an object having the setter property to be hooked
		 * @param {string} propertyName			- the name of the setter property to be hooked
		 * @param {onSetter} onSetter				- the hook replace the setter
		 */
		setter: function setter( target, propertyName, onSetter ) {
			var descriptor;

			if ( Object.prototype.hasOwnProperty.call( target, propertyName ) ) {
				descriptor = Object.getOwnPropertyDescriptor( target, propertyName );

				if ( Object.prototype.hasOwnProperty.call( descriptor, "set" ) ) {
					descriptor.set = Functions.apply( descriptor.set, function ( setter, thisArg, args ) {
						onSetter.call( this, target, propertyName, setter, thisArg, args );
					} );

					Object.defineProperty( target, propertyName, descriptor );
				}
			}
		},
		/**
		 * the hook replace the setter
		 * @callback onSetter
		 * @param {object} target				- the object having the setter property hooked
		 * @param {string} propertyName			- he name of the setter property hooked
		 * @param {function} setter				- the setter replaced
		 * @param {object|undefined} thisArg	- #this reference
		 * @param {arguments} args				- the arguments pass to the setter, should be a right value
		 */

		/**
		 * hook a method of an object
		 * @function method
		 * @param {object} target				- an object having or to have the method to be hooked
		 * @param {string} methodName			- the name of the method to be hooked
		 * @param {onApply} onApply				- the hook replace the method
		 */
		method: function method( target, methodName, onApply ) {
			var method = target[ methodName ];

			function hook( method ) {
				return Functions.apply( method, function ( method, thisArg, args ) {
					return onApply.call( this, target, methodName, method, thisArg, args );
				} );
			};

			if ( "function" === typeof method ) {
				target[ methodName ] = hook( method );
			} else if ( !Object.prototype.hasOwnProperty.call( target, methodName ) ) {
				Object.defineProperty( target, methodName, {
					configurable: true,
					enumerable: true,
					set: function ( value ) {
						Object.defineProperty( target, methodName, {
							configurable: true,
							enumerable: true,
							value: typeof value === "function" ? hook( value ) : value,
							writable: true
						} );
					},
					get: function () {
						return undefined;
					}
				} );
			}
		},
		/**
		 * the hook replace the method
		 * @callback onApply
		 * @param {object} target				- the object having the method hooked
		 * @param {string} methodName			- the name of the method hooked
		 * @param {object|undefined} thisArg	- #this reference
		 * @param {arguments} args				- the arguments pass to the method
		 */
	};

	Hooks.Reply = {
		get: function ( param ) {
			var target = param[ 0 ],
				propertyName = param[ 1 ],
				oldValue = param[ 2 ];

			return oldValue;
		},

		set: function ( param ) {
			var target = param[ 0 ],
				propertyName = param[ 1 ],
				oldValue = param[ 2 ],
				newValue = param[ 3 ];

			return newValue;
		},

		getter: function ( param ) {
			var target = param[ 0 ],
				propertyName = param[ 1 ],
				getter = param[ 2 ],
				thisArg = param[ 3 ],
				args = param[ 4 ];

			return getter.apply( thisArg, args );
		},

		setter: function ( param ) {
			var target = param[ 0 ],
				propertyName = param[ 1 ],
				setter = param[ 2 ],
				thisArg = param[ 3 ],
				args = param[ 4 ];

			setter.apply( thisArg, args );
		},

		method: function method( param ) {
			var target = param[ 0 ],
				methodName = param[ 1 ],
				method = param[ 2 ],
				thisArg = param[ 3 ],
				args = param[ 4 ];

			return method.apply( thisArg, args );
		},
	};

	return Hooks;
} )();