summaryrefslogtreecommitdiff
path: root/lib/epub.js/src/utils/hook.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/epub.js/src/utils/hook.js')
-rw-r--r--lib/epub.js/src/utils/hook.js82
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;