summaryrefslogtreecommitdiffstats
path: root/toolkit/jetpack/sdk/util/dispatcher.js
diff options
context:
space:
mode:
authorMatt A. Tobin <email@mattatobin.com>2018-02-09 06:46:43 -0500
committerMatt A. Tobin <email@mattatobin.com>2018-02-09 06:46:43 -0500
commitac46df8daea09899ce30dc8fd70986e258c746bf (patch)
tree2750d3125fc253fd5b0671e4bd268eff1fd97296 /toolkit/jetpack/sdk/util/dispatcher.js
parent8cecf8d5208f3945b35f879bba3015bb1a11bec6 (diff)
downloadUXP-ac46df8daea09899ce30dc8fd70986e258c746bf.tar
UXP-ac46df8daea09899ce30dc8fd70986e258c746bf.tar.gz
UXP-ac46df8daea09899ce30dc8fd70986e258c746bf.tar.lz
UXP-ac46df8daea09899ce30dc8fd70986e258c746bf.tar.xz
UXP-ac46df8daea09899ce30dc8fd70986e258c746bf.zip
Move Add-on SDK source to toolkit/jetpack
Diffstat (limited to 'toolkit/jetpack/sdk/util/dispatcher.js')
-rw-r--r--toolkit/jetpack/sdk/util/dispatcher.js54
1 files changed, 54 insertions, 0 deletions
diff --git a/toolkit/jetpack/sdk/util/dispatcher.js b/toolkit/jetpack/sdk/util/dispatcher.js
new file mode 100644
index 000000000..67d29dfed
--- /dev/null
+++ b/toolkit/jetpack/sdk/util/dispatcher.js
@@ -0,0 +1,54 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+"use strict";
+
+module.metadata = {
+ "stability": "experimental"
+};
+
+const method = require("method/core");
+
+// Utility function that is just an enhancement over `method` to
+// allow predicate based dispatch in addition to polymorphic
+// dispatch. Unfortunately polymorphic dispatch does not quite
+// cuts it in the world of XPCOM where no types / classes exist
+// and all the XUL nodes share same type / prototype.
+// Probably this is more generic and belongs some place else, but
+// we can move it later once this will be relevant.
+var dispatcher = hint => {
+ const base = method(hint);
+ // Make a map for storing predicate, implementation mappings.
+ let implementations = new Map();
+
+ // Dispatcher function goes through `predicate, implementation`
+ // pairs to find predicate that matches first argument and
+ // returns application of arguments on the associated
+ // `implementation`. If no matching predicate is found delegates
+ // to a `base` polymorphic function.
+ let dispatch = (value, ...rest) => {
+ for (let [predicate, implementation] of implementations) {
+ if (predicate(value))
+ return implementation(value, ...rest);
+ }
+
+ return base(value, ...rest);
+ };
+
+ // Expose base API.
+ dispatch.define = base.define;
+ dispatch.implement = base.implement;
+ dispatch.toString = base.toString;
+
+ // Add a `when` function to allow extending function via
+ // predicates.
+ dispatch.when = (predicate, implementation) => {
+ if (implementations.has(predicate))
+ throw TypeError("Already implemented for the given predicate");
+ implementations.set(predicate, implementation);
+ };
+
+ return dispatch;
+};
+
+exports.dispatcher = dispatcher;