Source: XtraUtils.js

/**
 * Adds some utilities to the base classes.
 * Note that this is modular and is able to modify any class it is given.
 * @projectname XtraUtils
 * @author FreezePhoenix
 * @version 1.1.0
 */
/**
 * @namespace
 */
const XtraUtils = {
	/**
	 * Activates all the utilities on the object.
	 * @returns {boolean} Whether is succeded or not.
	 * @method
	 */
	activateAll() {
		try {
			Object.values( this ).filter( i => i instanceof XtraUtils.Utility ).forEach( ( item, index ) => {
				item.activate();
			} );
			return true;
		} catch( e ) {
			return false;
		}
	}
};
/**
 * The base class for XtraUtils
 * @class
 * @classdesc Enables utilities to be added to classes.
 * @property {Function} aidsIn The constructor or class that this Utility expands on
 * @property {Object} utils The functions to be added to the instances of this Utility.
 * @property {Object} methods The functions to be added to the class constructor itself.
 */
XtraUtils.Utility = class {
	/**
	 * Create a new utility
	 * @constructs
	 * @param {Function} ofWhat What class are we extending?
	 * @throws {TypeError} The first argument of Utility must be a class.
	 */
	constructor( ofWhat ) {
		if ( typeof ofWhat === 'function' && ofWhat.prototype ) {
			Object.assign( this, {
				methods: new Map(),
				utils: new Map(),
				Activated: [],
				OverWritten: {},
				isActivated: false
			} );
			Object.defineProperty( this, 'aidsIn', {
				value: ofWhat,
				writable: false
			} );
		} else {
			throw Error( 'new Utility expects a class to be passed as the first argument.' );
		}
	}
	/**
	 * Activates the utilities in this Utility instance.
	 * @returns {boolean} Whether it succeded or not.
	 */
	activate() {
		try {
			if( !this.isActivated ) {
				for ( let [name, func] of this.utils ) {
					this.aidsIn.prototype[name] && ( this.OverWritten[[name, 'util']] = this.aidsIn.prototype[name].valueOf() );
					this.aidsIn.prototype[name] = func;
					this.Activated.push( [name, 'util'] );
				}
				for ( let [name, func] of this.methods ) {
					if ( this.aidsIn[name] ) {
						this.OverWritten[[name, 'method']] = this.aidsIn[name].valueOf();
					}
					this.aidsIn[name] = func;
					this.Activated.push( [name, 'method'] );
				}
				this.isActivated = true;
			}
			return true;
		} catch( e ) {
			return false;
		}
	}
	/**
	 * Deactivates utilities and methods, putting overwritten methods back.
	 * @returns {boolean} Whether it succeded or not.
	 */
	deactivate() {
		try{
			this.Activated.forEach( ( item, _ ) => {
				if( item[1] === 'util' ) {
					if ( this.OverWritten[[item[0],'util']] ) {
						this.aidsIn.prototype[item[0]] = this.OverWritten[item];
					} else {
						delete this.aidsIn.prototype[item[0]];
					}
				} else if( item[1] === 'method' ) {
					if ( this.OverWritten[[item[0],'method']] ) {
						this.aidsIn[item[0]] = this.OverWritten[[item[0],'method']];
					} else {
						delete this.aidsIn[item[0]];
					}
				}
			} );
			this.Activated = [];
			this.isActivated = false;
			return true;
		} catch( e ) {
			return false;
		}
	}
	/**
	 * Add a method, which will be placed as a static method on the class.
	 * @param {string} name The name to register it under.
	 * @param {Function} method The method to register.
	 * @returns {boolean} Success or not.
	 */
	addMethod( name, method ) {
		try {
			this[name] = method;
			this.methods.set( `${name}`, method );
			if( this.isActivated ) {
				if( this.aidsIn[name] ) {
					this.overWritten[name] = this.aidsIn[name].valueOf();
				}
				this.aidsIn[name] = method;
				this.activated.push( [name, 'method'] );
			}
			return true;
		} catch( e ) {
			return false;
		}
	}
	/**
   * Add a utility, which will be placed on class instances.
   * @param {string} name The name to register it by.
   * @param {Function} util The utility to register.
   * @returns {boolean} Success state.
   */
	addUtil( name, util ) {
		try {
			this[name] = util;
			this.utils.set( `${name}`, util );
			if( this.isActivated ) {
				if( this.aidsIn.prototype[name] ) {
					this.overWritten[name] = this.aidsIn.prototype[name].valueOf();
				}
				this.aidsIn.prototype[name] = util;
				this.Activated.push( [name, 'util'] );
			}
			return true;
		} catch( e ) {
			return false;
		}
	}
};