Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80555 views
1
/* -*- Mode: js; js-indent-level: 2; -*- */
2
/*
3
* Copyright 2011 Mozilla Foundation and contributors
4
* Licensed under the New BSD license. See LICENSE or:
5
* http://opensource.org/licenses/BSD-3-Clause
6
*/
7
8
/**
9
* Define a module along with a payload.
10
* @param {string} moduleName Name for the payload
11
* @param {ignored} deps Ignored. For compatibility with CommonJS AMD Spec
12
* @param {function} payload Function with (require, exports, module) params
13
*/
14
function define(moduleName, deps, payload) {
15
if (typeof moduleName != "string") {
16
throw new TypeError('Expected string, got: ' + moduleName);
17
}
18
19
if (arguments.length == 2) {
20
payload = deps;
21
}
22
23
if (moduleName in define.modules) {
24
throw new Error("Module already defined: " + moduleName);
25
}
26
define.modules[moduleName] = payload;
27
};
28
29
/**
30
* The global store of un-instantiated modules
31
*/
32
define.modules = {};
33
34
35
/**
36
* We invoke require() in the context of a Domain so we can have multiple
37
* sets of modules running separate from each other.
38
* This contrasts with JSMs which are singletons, Domains allows us to
39
* optionally load a CommonJS module twice with separate data each time.
40
* Perhaps you want 2 command lines with a different set of commands in each,
41
* for example.
42
*/
43
function Domain() {
44
this.modules = {};
45
this._currentModule = null;
46
}
47
48
(function () {
49
50
/**
51
* Lookup module names and resolve them by calling the definition function if
52
* needed.
53
* There are 2 ways to call this, either with an array of dependencies and a
54
* callback to call when the dependencies are found (which can happen
55
* asynchronously in an in-page context) or with a single string an no callback
56
* where the dependency is resolved synchronously and returned.
57
* The API is designed to be compatible with the CommonJS AMD spec and
58
* RequireJS.
59
* @param {string[]|string} deps A name, or names for the payload
60
* @param {function|undefined} callback Function to call when the dependencies
61
* are resolved
62
* @return {undefined|object} The module required or undefined for
63
* array/callback method
64
*/
65
Domain.prototype.require = function(deps, callback) {
66
if (Array.isArray(deps)) {
67
var params = deps.map(function(dep) {
68
return this.lookup(dep);
69
}, this);
70
if (callback) {
71
callback.apply(null, params);
72
}
73
return undefined;
74
}
75
else {
76
return this.lookup(deps);
77
}
78
};
79
80
function normalize(path) {
81
var bits = path.split('/');
82
var i = 1;
83
while (i < bits.length) {
84
if (bits[i] === '..') {
85
bits.splice(i-1, 1);
86
} else if (bits[i] === '.') {
87
bits.splice(i, 1);
88
} else {
89
i++;
90
}
91
}
92
return bits.join('/');
93
}
94
95
function join(a, b) {
96
a = a.trim();
97
b = b.trim();
98
if (/^\//.test(b)) {
99
return b;
100
} else {
101
return a.replace(/\/*$/, '/') + b;
102
}
103
}
104
105
function dirname(path) {
106
var bits = path.split('/');
107
bits.pop();
108
return bits.join('/');
109
}
110
111
/**
112
* Lookup module names and resolve them by calling the definition function if
113
* needed.
114
* @param {string} moduleName A name for the payload to lookup
115
* @return {object} The module specified by aModuleName or null if not found.
116
*/
117
Domain.prototype.lookup = function(moduleName) {
118
if (/^\./.test(moduleName)) {
119
moduleName = normalize(join(dirname(this._currentModule), moduleName));
120
}
121
122
if (moduleName in this.modules) {
123
var module = this.modules[moduleName];
124
return module;
125
}
126
127
if (!(moduleName in define.modules)) {
128
throw new Error("Module not defined: " + moduleName);
129
}
130
131
var module = define.modules[moduleName];
132
133
if (typeof module == "function") {
134
var exports = {};
135
var previousModule = this._currentModule;
136
this._currentModule = moduleName;
137
module(this.require.bind(this), exports, { id: moduleName, uri: "" });
138
this._currentModule = previousModule;
139
module = exports;
140
}
141
142
// cache the resulting module object for next time
143
this.modules[moduleName] = module;
144
145
return module;
146
};
147
148
}());
149
150
define.Domain = Domain;
151
define.globalDomain = new Domain();
152
var require = define.globalDomain.require.bind(define.globalDomain);
153
154