defuse
Version:
A poor man's module namespacing solution for the browser
104 lines (84 loc) • 2.27 kB
JavaScript
;(function() {
var root;
var defuse;
if (typeof global != 'undefined') {
// node
root = global;
defuse = this;
}
else {
// browser
root = this;
root.defuse = defuse = {};
}
defuse.api = {};
defuse.pending = {};
defuse.registry = {};
defuse.old = null;
// Defines a module.
defuse.api.def = function(name, loader) {
defuse.pending[name] = loader;
defuse.registry[name] = null;
return this;
};
// Undefines a module.
defuse.api.undef = function(name) {
delete defuse.pending[name];
delete defuse.registry[name];
return this;
};
// Returns the exports of a defined module.
defuse.api.use = function(name) {
var mod = defuse.registry[name];
if (typeof mod == 'undefined') {
throw new Error("module '" + name + "' does not exist");
}
if (mod === null) {
mod = {};
defuse.pending[name](mod);
defuse.registry[name] = mod;
delete defuse.pending[name];
}
return mod;
};
// Assigns defuse's api methods to the given object
defuse.assignTo = function(obj) {
var api = defuse.api;
for (var k in api) { obj[k] = api[k]; }
return this;
};
// Assigns defuse's api methods to the global namespace (delegates to `assignTo`)
defuse.pollute = function(obj) {
var old = defuse.old = {};
for (var k in defuse.api) {
if (root.hasOwnProperty(k)) { old[k] = root[k]; }
}
defuse.assignTo(root);
return this;
};
// Restore properties the global object had and remove properties that the
// global object did not have before `pollute`.
defuse.unpollute = function() {
var old = defuse.old;
if (old === null) {
throw new Error("defuse has not been assigned to the global object");
}
for (var j in defuse.api) { delete root[j]; }
for (var k in old) { root[k] = old[k]; }
defuse.old = null;
return this;
};
// Returns a shallow copy of the defuse api. Useful for mixing in
defuse.exports = function() {
var obj = {};
defuse.assignTo(obj);
return obj;
};
// Make the api methods directly accessible
defuse.assignTo(defuse);
}).call(this);
if (typeof exports != 'undefined') {
exports.pollute();
} else {
defuse.pollute();
}