summaryrefslogtreecommitdiffstats
path: root/toolkit/jetpack/sdk/core/namespace.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/jetpack/sdk/core/namespace.js')
-rw-r--r--toolkit/jetpack/sdk/core/namespace.js43
1 files changed, 43 insertions, 0 deletions
diff --git a/toolkit/jetpack/sdk/core/namespace.js b/toolkit/jetpack/sdk/core/namespace.js
new file mode 100644
index 000000000..3ceb73b72
--- /dev/null
+++ b/toolkit/jetpack/sdk/core/namespace.js
@@ -0,0 +1,43 @@
+/* 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": "unstable"
+};
+
+const create = Object.create;
+const prototypeOf = Object.getPrototypeOf;
+
+/**
+ * Returns a new namespace, function that may can be used to access an
+ * namespaced object of the argument argument. Namespaced object are associated
+ * with owner objects via weak references. Namespaced objects inherit from the
+ * owners ancestor namespaced object. If owner's ancestor is `null` then
+ * namespaced object inherits from given `prototype`. Namespaces can be used
+ * to define internal APIs that can be shared via enclosing `namespace`
+ * function.
+ * @examples
+ * const internals = ns();
+ * internals(object).secret = secret;
+ */
+function ns() {
+ const map = new WeakMap();
+ return function namespace(target) {
+ if (!target) // If `target` is not an object return `target` itself.
+ return target;
+ // If target has no namespaced object yet, create one that inherits from
+ // the target prototype's namespaced object.
+ if (!map.has(target))
+ map.set(target, create(namespace(prototypeOf(target) || null)));
+
+ return map.get(target);
+ };
+};
+
+// `Namespace` is a e4x function in the scope, so we export the function also as
+// `ns` as alias to avoid clashing.
+exports.ns = ns;
+exports.Namespace = ns;