Commits

Mathias Panzenböck committed 494d9a0

fixed require a bit but now 'determinism' fails, also added i18n

  • Participants
  • Parent commits cc194c7

Comments (0)

Files changed (3)

+const fs = require('fs');
+
+if (typeof(navigator) == 'undefined') {
+	exports.lang = navigator.language;
+}
+else {
+	const system = require('system');
+	exports.lang = system.env.LANG || system.env.LANGUAGE;
+}
+
+function _load (moduleName, ext) {
+	var resolver = new require.Resolver(moduleName, ext, require.main);
+	var err = null;
+	var data;
+
+	do {
+		try {
+			data = fs.read(resolver.reluri);
+		}
+		catch (e) {
+			err = e;
+		}
+	} while (resolver.next());
+
+	if (err != null) {
+		throw err;
+	}
+
+	return JSON.parse(data);
+}
+
+exports.load = function (moduleName, lang) {
+	if (!lang) {
+		lang = exports.lang;
+	}
+
+	var data;
+
+	try {
+		data = _load(moduleName, '.'+lang+'.i18n');
+	}
+	catch (e) {
+		try {
+			data = _load(moduleName, '.'+lang.split('-')[0]+'.i18n');
+		}
+		catch (e) {
+			try {
+				data = _load(moduleName, '.i18n');
+			}
+			catch (e) {
+				data = _load(moduleName, '.en.i18n');
+			}
+		}
+	}
+	
+	return data;
+};
 		return newpath.join('/');
 	}
 
+	function Resolver (moduleName, ext, parent) {
+		var search = false;
+		var pathIndex = 0;
+		var prefix =  location.protocol + '//' + location.host;
+		var resolvePaths;
+
+		if (moduleName[0] == '/') {
+			this.id = '/' + normpath(moduleName);
+			this.reluri = this.id + ext;
+		}
+		else if (moduleName.substring(0,2) == './'
+				|| moduleName.substring(0,3) == '../') {
+			this.id = '/' + normpath(parent.path + '/../' + moduleName);
+			this.reluri = this.id + ext;
+		}
+		else {
+			search = true;
+			resolvePaths = paths.slice();
+			resolvePaths.splice(0,0,parent.path+'/..');
+			this.id = '/' + normpath(resolvePaths[0] + '/' + moduleName);
+			this.reluri = this.id + ext;
+		}
+			
+		this.uri = prefix + this.reluri;
+
+		this.next = function () {
+			if (search && (pathIndex+1) < resolvePaths.length) {
+				this.id = '/' + normpath(resolvePaths[++pathIndex] + '/' + moduleName);
+				this.reluri = this.id + ext;
+				this.uri = prefix + this.reluri;
+				return true;
+			}
+			else {
+				return false;
+			}
+		};
+
+		this.reset = function () {
+			if (search) {
+				pathIndex = 0;
+				this.id = '/' + normpath(resolvePaths[0] + '/' + moduleName);
+				this.reluri = this.id + ext;
+				this.uri = prefix + this.reluri;
+			}
+		};
+	}
+
 	function make_require (parent, getters) {
 		function _require (moduleName, opts) {
 			return __require(moduleName, opts, parent);
 			return paths;
 		});
 		property(_require, 'isLoaded', function () {
-			return function (uri) {
-				return uri in loaded; // || uri in loading; ?
+			return function (id) {
+				var resolver = new Resolver(id, '.js', parent);
+
+				do {
+					if (resolver.id in loaded) { // || id in loading; ?
+						return true;
+					}
+				} while (resolver.next());
+
+				return false;
 			};
 		});
+		property(_require, 'Resolver', function () {
+			return Resolver;
+		});
 
 		if (getters) {
 			for (name in getters) {
 	}
 
 	function __require (moduleName, opts, parent) {
-		var search = false;
-		var pathIndex = 0;
-		var prefix =  location.protocol + '//' + location.host;
-		var id;
-		var reluri;
-		var uri;
-			
-		if (moduleName[0] == '/') {
-			id = '/' + normpath(moduleName);
-			reluri = id + '.js';
-		}
-		else if (moduleName.substring(0,2) == './'
-				|| moduleName.substring(0,3) == '../'
-				|| paths.length == 0) {
-			id = '/' + normpath(parent.path + '/../' + moduleName);
-			reluri = id + '.js';
-		}
-		else {
-			search = true;
-			id = normpath(moduleName);
-			reluri = '/' + normpath(paths[0] + '/' + id + '.js');
-		}
-			
-		var uri = prefix + reluri;
+		var resolver = new Resolver(moduleName, '.js', parent);
 
 		if (opts === undefined) {
 			opts = {};
 		if (opts.async === undefined) {
 			opts.async = false;
 		}
+
+		var exports = loaded[resolver.id];
 	
-		var moduleObj = loaded[uri];
-	
-		if (moduleObj === undefined) {
-			moduleObj = loading[uri];
+		if (exports === undefined) {
+			exports = loading[resolver.id];
 		}
 	
-		if (moduleObj === undefined) {
-			loading[uri] = moduleObj = new Module();
+		if (exports === undefined) {
+			loading[resolver.id] = exports = new Module();
 	
-			var newModule = new ModuleInfo(id, uri, reluri, parent);
+			var newModule = new ModuleInfo(
+				resolver.id,
+				resolver.uri,
+				resolver.reluri,
+				parent);
 			var globals = {
-				exports: moduleObj,
+				exports: exports,
 				include: include,
 				require: make_require(newModule),
 				module:  newModule,
 			var err = null;
 	
 			xhr.addEventListener('abort', function () {
-				delete loading[uri];
+				delete loading[resolver.id];
 				err = new Error(
-					'Error loading module: ' + id +
-					'\nTransfer aborted by user.');
+					'Error loading module: ' + resolver.id + ' (' + resolver.uri +
+					')\nTransfer aborted by user.');
 				if (opts.onError) {
 					opts.onError(err);
 				}
 			}, false);
 	
 			function transferError () {
-				if (search && xhr.status == 404 && (pathIndex+1) < paths.length) {
-					reluri = '/' + normpath(paths[++pathIndex] + '/' + id + '.js');
-					uri = prefix + reluri;
-					globals.module = newModule = new ModuleInfo(id, uri, reluri, parent);
-					globals.require = make_require(newModule);
-					xhr.open('GET', reluri, opts.async);
-					xhr.send(null);
+				delete loading[resolver.id];
+
+				if (xhr.status == 404 && resolver.next()) {
+					if (resolver.id in loading && loading[resilver.id] != exports) {
+						exports = loading[resolver.id];
+					}
+					else if (resolver.id in loaded) {
+						exports = loaded[resolver.id];
+					}
+					else {
+						loading[resolver.id] = exports;
+						globals.module = newModule = new ModuleInfo(
+							resolver.id,
+							resolver.uri,
+							resolver.reluri,
+							parent);
+						globals.require = make_require(newModule);
+						xhr.open('GET', resolver.reluri, opts.async);
+						xhr.send(null);
+					}
 					return;
 				}
-
-				delete loading[uri];
+				
 				err = new Error(
-					'Error loading module: ' + id +
-					'\nHTTP Status: ' + xhr.status + ' ' + xhr.statusText);
+					'Error loading module: ' + resolver.id + ' (' + resolver.uri +
+					')\nHTTP Status: ' + xhr.status + ' ' + xhr.statusText);
 				if (opts.onError) {
 					opts.onError(err);
 				}
 						'(function (globals) { with (globals) { ' +
 						xhr.responseText+' }})')(globals);
 							
-					delete loading[uri];
-					loaded[uri] = moduleObj;
+					delete loading[resolver.id];
+					loaded[resolver.id] = exports;
 				}
 				catch (e) {
-					delete loading[uri];
+					delete loading[resolver.id];
 					err = e;
 					if (opts.onError) {
 						opts.onError(err);
 				}
 	
 				if (opts.onLoad) {
-					opts.onLoad(moduleObj);
+					opts.onLoad(exports);
 				}
 			}, false);
 	
-			xhr.open('GET', reluri, opts.async);
+			xhr.open('GET', resolver.reluri, opts.async);
 			xhr.send(null);
 	
 			if (err != null) {
 			}
 		}
 		else if (opts.onLoad) {
-			opts.onLoad(moduleObj);
+			opts.onLoad(exports);
 		}
 	
-		return moduleObj;
+		return exports;
 	}
 	
 	return make_require(main, {
 
 	for (name in test) {
 		if (name.substring(0,4) = 'test') {
-			startup();
 			try {
+				startup();
 				test[name]();
+				teardown();
+				console.info(name, 'OK');
 			}
 			catch (e) {
 				if (e instanceof assert.AssertionError) {
-					console.error(e.message);
+					console.error(name, e.message);
 				}
 				else {
-					console.error('Got unwanted exception: '+e);
+					console.error(name, 'Got unwanted exception:', e);
 				}
 				++ count;
 			}
-			teardown();
 		}
 	}