Last active
December 12, 2022 08:02
-
-
Save Hi7cl4w/817b3a5854dfbf2eabfa16b7bb007cbd to your computer and use it in GitHub Desktop.
EventEmitter.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* Util Class for handling user defined event listeners */ | |
| export default class EventEmitter { | |
| /** | |
| * The constructor function creates an object called callbacks, which has a property called base. | |
| */ | |
| constructor() { | |
| this.callbacks = {}; | |
| this.callbacks.base = {}; | |
| } | |
| /** | |
| * It takes a string of names and a callback function and adds the callback function to an array of | |
| * callbacks for each name | |
| * @param {String} _names - The name of the event you want to listen to. | |
| * @param {() => void} callback - The function to be called when the event is triggered. | |
| * @returns {EventEmitter} The object itself. | |
| */ | |
| on(_names, callback) { | |
| // Errors | |
| if (typeof _names === "undefined" || _names === "") { | |
| console.warn("wrong names"); | |
| return false; | |
| } | |
| if (typeof callback === "undefined") { | |
| console.warn("wrong callback"); | |
| return false; | |
| } | |
| // Resolve names | |
| const names = this.resolveNames(_names); | |
| // Each name | |
| names.forEach((_name) => { | |
| // Resolve name | |
| const name = this.resolveName(_name); | |
| // Create namespace if not exist | |
| if (!(this.callbacks[name.namespace] instanceof Object)) | |
| this.callbacks[name.namespace] = {}; | |
| // Create callback if not exist | |
| if (!(this.callbacks[name.namespace][name.value] instanceof Array)) | |
| this.callbacks[name.namespace][name.value] = []; | |
| // Add callback | |
| this.callbacks[name.namespace][name.value].push(callback); | |
| }); | |
| return this; | |
| } | |
| /** | |
| * It removes a callback from the callbacks object | |
| * @param {String} _names - The name of the event to remove. | |
| * @returns {EventEmitter} The object itself. | |
| */ | |
| off(_names) { | |
| // Errors | |
| if (typeof _names === "undefined" || _names === "") { | |
| console.warn("wrong name"); | |
| return false; | |
| } | |
| // Resolve names | |
| const names = this.resolveNames(_names); | |
| // Each name | |
| names.forEach((_name) => { | |
| // Resolve name | |
| const name = this.resolveName(_name); | |
| // Remove namespace | |
| if (name.namespace !== "base" && name.value === "") { | |
| delete this.callbacks[name.namespace]; | |
| } | |
| // Remove specific callback in namespace | |
| else { | |
| // Default | |
| if (name.namespace === "base") { | |
| // Try to remove from each namespace | |
| for (const namespace in this.callbacks) { | |
| if ( | |
| this.callbacks[namespace] instanceof Object && | |
| this.callbacks[namespace][name.value] instanceof Array | |
| ) { | |
| delete this.callbacks[namespace][name.value]; | |
| // Remove namespace if empty | |
| if (Object.keys(this.callbacks[namespace]).length === 0) | |
| delete this.callbacks[namespace]; | |
| } | |
| } | |
| } | |
| // Specified namespace | |
| else if ( | |
| this.callbacks[name.namespace] instanceof Object && | |
| this.callbacks[name.namespace][name.value] instanceof Array | |
| ) { | |
| delete this.callbacks[name.namespace][name.value]; | |
| // Remove namespace if empty | |
| if (Object.keys(this.callbacks[name.namespace]).length === 0) | |
| delete this.callbacks[name.namespace]; | |
| } | |
| } | |
| }); | |
| return this; | |
| } | |
| /** | |
| * Triggers the Event | |
| * @param {String} _name - The name of the event you want to trigger. | |
| * @param _args - Array of arguments to pass to the callback | |
| * @returns The finalResult variable is being returned. | |
| */ | |
| trigger(_name, _args) { | |
| // Errors | |
| if (typeof _name === "undefined" || _name === "") { | |
| console.warn("wrong name"); | |
| return false; | |
| } | |
| let finalResult = null; | |
| let result = null; | |
| // Default args | |
| const args = !(_args instanceof Array) ? [] : _args; | |
| // Resolve names (should on have one event) | |
| let name = this.resolveNames(_name); | |
| // Resolve name | |
| name = this.resolveName(name[0]); | |
| // Default namespace | |
| if (name.namespace === "base") { | |
| // Try to find callback in each namespace | |
| for (const namespace in this.callbacks) { | |
| if ( | |
| this.callbacks[namespace] instanceof Object && | |
| this.callbacks[namespace][name.value] instanceof Array | |
| ) { | |
| this.callbacks[namespace][name.value].forEach(function (callback) { | |
| result = callback.apply(this, args); | |
| if (typeof finalResult === "undefined") { | |
| finalResult = result; | |
| } | |
| }); | |
| } | |
| } | |
| } | |
| // Specified namespace | |
| else if (this.callbacks[name.namespace] instanceof Object) { | |
| if (name.value === "") { | |
| console.warn("wrong name"); | |
| return this; | |
| } | |
| this.callbacks[name.namespace][name.value].forEach(function (callback) { | |
| result = callback.apply(this, args); | |
| if (typeof finalResult === "undefined") finalResult = result; | |
| }); | |
| } | |
| return finalResult; | |
| } | |
| /** | |
| * It takes a string of names, removes all non-alphanumeric characters, replaces all commas and | |
| * slashes with spaces, and then splits the string into an array of names. | |
| * @param {String} _name - The string of names to be resolved. | |
| * @returns An array of names. | |
| */ | |
| resolveNames(_names) { | |
| let names = _names; | |
| names = names.replace(/[^a-zA-Z0-9 ,/.]/g, ""); | |
| names = names.replace(/[,/]+/g, " "); | |
| names = names.split(" "); | |
| return names; | |
| } | |
| /** | |
| * It takes a string and returns an object with the string split into two parts | |
| * @param name - The name of the variable to be resolved. | |
| * @returns An object with the following properties: | |
| */ | |
| resolveName(name) { | |
| const newName = {}; | |
| const parts = name.split("."); | |
| newName.original = name; | |
| newName.value = parts[0]; | |
| newName.namespace = "base"; // Base namespace | |
| // Specified namespace | |
| if (parts.length > 1 && parts[1] !== "") { | |
| newName.namespace = parts[1]; | |
| } | |
| return newName; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment