Commits

Mathias Panzenböck committed e6fe0c6

require.js: reference parent module descriptors, system.js may now be evaluated multiple times without problems

Comments (0)

Files changed (2)

+const module = {
+	id: null,
+	uri: window.location.protocol + '://' + location.host + location.pathname,
+	path: location.pathname
+};
 const require = (function (_eval) {
 	var loading = {};
 	var loaded  = {};
 		return newpath.join('/');
 	}
 
-	function _require (moduleName, opts) {
+	function make_require (parent, getters) {
+		function _require (moduleName, opts) {
+			return __require(moduleName, opts, parent);
+		}
+		
+		_require.__proto__ = new Function();
+		_require.__proto__.__defineGetter__('paths', function () {
+			return paths;
+		});
+		_require.__proto__.__defineGetter__('isLoaded', function () {
+			return function (uri) {
+				return uri in loaded; // || uri in loading; ?
+			};
+		});
+
+		if (getters) {
+			for (name in getters) {
+				_require.__proto__.__defineGetter__(name, getters[name]);
+			}
+		}
+
+		return _require;
+	}
+
+	function __require (moduleName, opts, parent) {
 		var location = window.location;
 		var search = false;
 		var pathIndex = 0;
 		else if (moduleName.substring(0,2) == './'
 				|| moduleName.substring(0,3) == '../'
 				|| paths.length == 0) {
-			id = '/' + normpath(location.pathname + '/../' + moduleName);
+			id = '/' + normpath(parent.path + '/../' + moduleName);
 			reluri = id + '.js';
 		}
 		else {
 		if (moduleObj === undefined) {
 			loading[uri] = moduleObj = {};
 	
-			var module = {id: id, uri: uri};
+			var newModule = {id: id, uri: uri, path: reluri, parent: parent};
 			var argnames = ['exports', 'require', 'module'];
-			var args = [moduleObj, _require, module];
+			var args = [moduleObj, make_require(newModule), newModule];
 	
 			if (opts.globals) {
 				for (argname in opts.globals) {
 	
 			function transferError () {
 				if (search && xhr.status == 404 && (pathIndex+1) < paths.length) {
-					reluri = '/' + normpath(paths[++pathIndex] + '/' + id + '.js');
-					module.uri = prefix + reluri;
+					newModule.path = reluri = '/' + normpath(paths[++pathIndex] + '/' + id + '.js');
+					newModule.uri = prefix + reluri;
 					xhr.open('GET', reluri, opts.async);
 					xhr.send(null);
 					return;
 			xhr.send(null);
 	
 			if (err != null) {
+				err.stack = new Error().stack;
 				throw err;
 			}
 		}
 	
 		return moduleObj;
 	}
-
-	_require.__proto__ = new Function();
-	_require.__proto__.__defineGetter__('paths', function () {
-		return paths;
+	
+	return make_require(module, {
+		clear: function () {
+			return function () {
+				loading = {};
+				loaded  = {};
+			};
+		}
 	});
-	
-	return _require;
 	// be careful so that nothing is bound to the closure made by eval:
 })(function (code) { return eval(code); });
 	}
 }
 
-var text = document.createTextNode('');
-var lastWasStdout = true;
-output.appendChild(text);
-
 function illegalWrite () {
 	throw new Error('stream not writeable');
 }
 	print:     print,
 	writeLine: writeLine,
 	write: function (buf, begin, end) {
-		if (!lastWasStdout) {
-			text = document.createTextNode(substr(buf,begin,end));
-			lastWasStdout = true;
-			output.appendChild(text);
+		var node = output.lastChild;
+		if (!node || node.nodeType != 3) {
+			node = document.createTextNode(substr(buf,begin,end));
+			output.appendChild(node);
 		}
 		else {
-			text.textContent += substr(buf,begin,end);
+			node.textContent += substr(buf,begin,end);
 		}
 	},
 	closed:    function () { return false; },
 	print:     print,
 	writeLine: writeLine,
 	write: function (buf, begin, end) {
-		if (lastWasStdout) {
-			var span = document.createElement('span');
-			span.className = 'stderr';
-			text = document.createTextNode(substr(buf,begin,end));
-			lastWasStdout = false;
-			span.appendChild(text);
-			output.appendChild(span);
+		var node = output.lastChild;
+		if (!node || node.nodeType == 3) {
+			node = document.createElement('span');
+			node.className = 'stderr';
+			var text = document.createTextNode(substr(buf,begin,end));
+			node.appendChild(text);
+			output.appendChild(node);
+		}
+		else if (!node.lastChild) {
+			var text = document.createTextNode(substr(buf,begin,end));
+			node.appendChild(text);
 		}
 		else {
-			text.textContent += substr(buf,begin,end);
+			node.lastChild.textContent += substr(buf,begin,end);
 		}
 	},
 	closed:    function () { return false; },
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.