diff options
Diffstat (limited to 'lib/epub.js/src/utils/hook.js')
-rw-r--r-- | lib/epub.js/src/utils/hook.js | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/lib/epub.js/src/utils/hook.js b/lib/epub.js/src/utils/hook.js new file mode 100644 index 0000000..ea1b901 --- /dev/null +++ b/lib/epub.js/src/utils/hook.js @@ -0,0 +1,82 @@ +/** + * Hooks allow for injecting functions that must all complete in order before finishing + * They will execute in parallel but all must finish before continuing + * Functions may return a promise if they are asycn. + * @param {any} context scope of this + * @example this.content = new EPUBJS.Hook(this); + */ +class Hook { + constructor(context){ + this.context = context || this; + this.hooks = []; + } + + /** + * Adds a function to be run before a hook completes + * @example this.content.register(function(){...}); + */ + register(){ + for(var i = 0; i < arguments.length; ++i) { + if (typeof arguments[i] === "function") { + this.hooks.push(arguments[i]); + } else { + // unpack array + for(var j = 0; j < arguments[i].length; ++j) { + this.hooks.push(arguments[i][j]); + } + } + } + } + + /** + * Removes a function + * @example this.content.deregister(function(){...}); + */ + deregister(func){ + let hook; + for (let i = 0; i < this.hooks.length; i++) { + hook = this.hooks[i]; + if (hook === func) { + this.hooks.splice(i, 1); + break; + } + } + } + + /** + * Triggers a hook to run all functions + * @example this.content.trigger(args).then(function(){...}); + */ + trigger(){ + var args = arguments; + var context = this.context; + var promises = []; + + this.hooks.forEach(function(task) { + try { + var executing = task.apply(context, args); + } catch (err) { + console.log(err); + } + + if(executing && typeof executing["then"] === "function") { + // Task is a function that returns a promise + promises.push(executing); + } + // Otherwise Task resolves immediately, continue + }); + + + return Promise.all(promises); + } + + // Adds a function to be run before a hook completes + list(){ + return this.hooks; + } + + clear(){ + return this.hooks = []; + } +} +export default Hook; |