Last active
January 5, 2021 05:23
-
-
Save Sominemo/54db02875a6e8a3710b9bf3ca5b9d789 to your computer and use it in GitHub Desktop.
onWord (And OnWordListener) class to react on typing with a callback (minified: https://gist.github.com/Sominemo/ff8d65baf08e7dfaa24a2973f2bca4d6)
This file contains 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
/** | |
* @typedef {Object} OnWordListenerInfo | |
* @property {function[]} callback Callbacks for the listener | |
* @property {boolean} case Case senisvity | |
* @property {boolean} debug Debug mode for the listener | |
* @property {number} stage Symbol number which will be checked on the next keypress | |
* @property {string} string String the item is listening for | |
*/ | |
class OnWordListener { | |
/** | |
* @param {object} data Data to link | |
* @param {number} id ID to save | |
* @param {OnWord} parent Binded OnWord class | |
* @property {number} ID of the listener | |
*/ | |
constructor(id, parent) { | |
this.parent = parent | |
this.id = id | |
} | |
/** | |
* Get listener info by details | |
* @param {number} i ID to get | |
* @returns {OnWordListenerInfo} The listener | |
*/ | |
get info() { | |
return this.parent.getById(this.id) | |
} | |
/** | |
* Disable listener | |
* @param {number} id ID of the listener | |
*/ | |
unset() { | |
this.parent.unset(this.id) | |
} | |
} | |
/** The class for listening words typed on keyboard | |
* @property {boolean} disabled OnWord status | |
* @property {[]} register Contains all listeners | |
* @property {function} listener Binded {@link OnWord.handler} | |
* @example | |
* let v = new OnWord(string, callback, cases = false, debug = false); | |
* @example | |
* let v = new OnWord(); | |
* v.listen(string, callback, cases = false, debug = false); | |
*/ | |
class OnWord { | |
constructor(string = false, callback, cases = false, debug = false) { | |
this.register = [] | |
this.disabled = false | |
this.listener = this.handler.bind(this) | |
document.addEventListener("keypress", this.listener) | |
if (cases) this.listen(string, callback, cases, debug) | |
} | |
/** | |
* Add new listener | |
* Adds new string listener with a callback to the register. | |
* @param {string} string String for listening | |
* @param {function} callback Callback function | |
* @param {boolean} cases=false Case sensivity | |
* @param {boolean} debug=false Debug mode. Provides onkeypress feedback in console | |
* @returns {OnWordListener} Listener object | |
*/ | |
listen(string, callback, cases = false, debug = false) { | |
let id = this.register.findIndex( | |
a => a.string === string | |
&& cases === a.case | |
&& debug === a.debug, | |
) | |
if (id === -1) { | |
this.register.push( | |
{ | |
string: (cases ? string : string.toLowerCase()), | |
stage: 0, | |
callback: [callback], | |
case: cases, | |
debug, | |
}, | |
) | |
} else { | |
this.register[id].callback.push(callback) | |
} | |
id = (id === -1 ? this.register.length - 1 : id) | |
return new OnWordListener(id, this) | |
} | |
/** | |
* Get data by ID | |
* @param {number} id ID of the listener | |
*/ | |
getById(id) { | |
return this.register[id] | |
} | |
/** | |
* Handles onkeypress event | |
* @param {object} event The event | |
*/ | |
handler(event) { | |
if (this.disabled) return | |
const { key } = event | |
const lKey = key.toLowerCase() | |
this.register.forEach((item) => { | |
const r = (item.case ? key : lKey) | |
if (item.string[item.stage] === r) { | |
item.stage++ | |
if (item.debug) console.log(`${r} = ${item.string[item.stage - 1]}`) | |
} else { | |
if (item.debug) console.log(`${r} != ${item.string[item.stage]}`) | |
item.stage = 0 | |
} | |
if (item.stage >= item.string.length) { | |
item.stage = 0 | |
item.callback.forEach(a => a()) | |
} | |
}) | |
} | |
/** | |
* Disable listener | |
* @param {number} id ID of the listener | |
*/ | |
unset(id) { | |
this.register.splice(id, 1) | |
} | |
/** | |
* Disable OnWord fully | |
* @param {boolean} f evaluate removeEventListener too (false by default) | |
*/ | |
disable(f) { | |
this.disabled = true | |
if (f) { | |
document.removeEventListener("keypress", this.listener) | |
this.listener = false | |
} | |
} | |
/** | |
* Bring onWord back to work | |
*/ | |
enable() { | |
this.disabled = false | |
if (!this.listener) { | |
this.listener = this.handler.bind(this) | |
document.addEventListener("keypress", this.listener) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment