123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- /* -*- Mode: js; js-indent-level: 2; -*- */
- /*
- * Copyright 2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE or:
- * http://opensource.org/licenses/BSD-3-Clause
- */
- /**
- * Define a module along with a payload.
- * @param {string} moduleName Name for the payload
- * @param {ignored} deps Ignored. For compatibility with CommonJS AMD Spec
- * @param {function} payload Function with (require, exports, module) params
- */
- function define(moduleName, deps, payload) {
- if (typeof moduleName != "string") {
- throw new TypeError('Expected string, got: ' + moduleName);
- }
- if (arguments.length == 2) {
- payload = deps;
- }
- if (moduleName in define.modules) {
- throw new Error("Module already defined: " + moduleName);
- }
- define.modules[moduleName] = payload;
- };
- /**
- * The global store of un-instantiated modules
- */
- define.modules = {};
- /**
- * We invoke require() in the context of a Domain so we can have multiple
- * sets of modules running separate from each other.
- * This contrasts with JSMs which are singletons, Domains allows us to
- * optionally load a CommonJS module twice with separate data each time.
- * Perhaps you want 2 command lines with a different set of commands in each,
- * for example.
- */
- function Domain() {
- this.modules = {};
- this._currentModule = null;
- }
- (function () {
- /**
- * Lookup module names and resolve them by calling the definition function if
- * needed.
- * There are 2 ways to call this, either with an array of dependencies and a
- * callback to call when the dependencies are found (which can happen
- * asynchronously in an in-page context) or with a single string an no callback
- * where the dependency is resolved synchronously and returned.
- * The API is designed to be compatible with the CommonJS AMD spec and
- * RequireJS.
- * @param {string[]|string} deps A name, or names for the payload
- * @param {function|undefined} callback Function to call when the dependencies
- * are resolved
- * @return {undefined|object} The module required or undefined for
- * array/callback method
- */
- Domain.prototype.require = function(deps, callback) {
- if (Array.isArray(deps)) {
- var params = deps.map(function(dep) {
- return this.lookup(dep);
- }, this);
- if (callback) {
- callback.apply(null, params);
- }
- return undefined;
- }
- else {
- return this.lookup(deps);
- }
- };
- function normalize(path) {
- var bits = path.split('/');
- var i = 1;
- while (i < bits.length) {
- if (bits[i] === '..') {
- bits.splice(i-1, 1);
- } else if (bits[i] === '.') {
- bits.splice(i, 1);
- } else {
- i++;
- }
- }
- return bits.join('/');
- }
- function join(a, b) {
- a = a.trim();
- b = b.trim();
- if (/^\//.test(b)) {
- return b;
- } else {
- return a.replace(/\/*$/, '/') + b;
- }
- }
- function dirname(path) {
- var bits = path.split('/');
- bits.pop();
- return bits.join('/');
- }
- /**
- * Lookup module names and resolve them by calling the definition function if
- * needed.
- * @param {string} moduleName A name for the payload to lookup
- * @return {object} The module specified by aModuleName or null if not found.
- */
- Domain.prototype.lookup = function(moduleName) {
- if (/^\./.test(moduleName)) {
- moduleName = normalize(join(dirname(this._currentModule), moduleName));
- }
- if (moduleName in this.modules) {
- var module = this.modules[moduleName];
- return module;
- }
- if (!(moduleName in define.modules)) {
- throw new Error("Module not defined: " + moduleName);
- }
- var module = define.modules[moduleName];
- if (typeof module == "function") {
- var exports = {};
- var previousModule = this._currentModule;
- this._currentModule = moduleName;
- module(this.require.bind(this), exports, { id: moduleName, uri: "" });
- this._currentModule = previousModule;
- module = exports;
- }
- // cache the resulting module object for next time
- this.modules[moduleName] = module;
- return module;
- };
- }());
- define.Domain = Domain;
- define.globalDomain = new Domain();
- var require = define.globalDomain.require.bind(define.globalDomain);
|