User:Gerbrant/fw.js

From Wikipedia, the free encyclopedia
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
new function()
{
	var pathPrefix = "/w/index.php?title=User:";
	var pathPostfix = ".js&action=raw&ctype=text/javascript&dontcountme=s";
	var interPrefix1 = "http://";
	var interPrefix2 = ".wikipedia.org/w/index.php?title=User:";
	var ownClassName = "Gerbrant.fw";
	var globalScope = window;
	var frameworkFunctionsGlobal = true;

//	-----------------------------------------------------------------------

	this.version = "1.0.1";
	this.revision = 1;

	var loadingModules = {};
	var loadedModules = {};
	var thisModule = globalScope;
	var bootModules = null;

	var ids = ownClassName.split(".");
	for(i in ids)
	{
		id = ids[i];
		if(!defined(thisModule[id]))
		{
			thisModule = null;
			break;
		}
		thisModule = thisModule[id];
	}
	if(thisModule)
	{
		if(defined(thisModule.loadModule)) return;
		if(defined(thisModule.load))
			bootModules = thisModule.load;
	}

	loadingModules[ownClassName] = [];

	function warning(message)
	{
		alert("Framework warning message:\n\n" + message);
	}

	function defined(a)
	{
		return a != undefined;
	}

	function modulePath(moduleName)
	{
		return moduleName.replace(/\./g, "/") + pathPostfix;
	}

	this.loadModule = function(moduleName, callback)
	{
		var p = moduleName.indexOf(":"), inter;
		if(p == -1)
			p = pathPrefix;
		else
		{
			inter = moduleName.slice(0, p);
			moduleName = moduleName.slice(p + 1);
			p = interPrefix1 + inter + interPrefix2;
		}

		var module = loadedModules[moduleName];
		if(defined(module))
		{
			if(defined(callback)) callback(module);
			return;
		}

		module = loadingModules[moduleName];
		if(defined(module))
		{
			if(defined(callback)) module.push(callback);
			return;
		}

		if(defined(callback)) callback = [callback];
		else callback = [];
		loadingModules[moduleName] = callback;
		document.write("<script src='" + p + modulePath(moduleName) + "'></script>");
	}

	this.module = function(moduleName, module)
	{
		var i, ids, id, mid, scope = globalScope;

		if(defined(loadedModules[moduleName]))
			warning("Module " + moduleName + " is loaded more than once.");
		else
		{
			loadedModules[moduleName] = module;

			ids = moduleName.split(".");
			mid = ids.pop();
			for(i in ids)
			{
				id = ids[i];
				if(!defined(scope[id]))
					scope[id] = {};
				scope = scope[id];
			}
			id = scope[mid];
			if(defined(id))
				for(i in module) id[i] = module[i];
			else
				scope[mid] = module;
		}

		var callbacks = loadingModules[moduleName];
		delete loadingModules[moduleName];
		if(defined(callbacks))
			for(i in callbacks)
				if(typeof callbacks[i] == "function")
					callbacks[i](module, moduleName);
				else
					warning("One of the callbacks registered for " +
						moduleName + " is not a function:\n" + callbacks[i]);
		else
			warning("Module " + moduleName + " finished loading without request.");
	}

	this.loadModules = function(moduleNames, callback)
	{
		var n = moduleNames.length, moduleList = {}, f;
		if(defined(callback))
			f = function(module, moduleName)
			{
				moduleList[moduleName] = module;
				if(--n == 0) callback(moduleList);
			};
		for(i in moduleNames) loadModule(moduleNames[i], f);
	}

	if(frameworkFunctionsGlobal)
	{
		module = this.module;
		loadModule = this.loadModule;
		loadModules = this.loadModules;		
	}

	this.module(ownClassName, this);

	if(defined(bootModules)) this.loadModules(bootModules);
};