Sixtest Wiki:API6/Core

window.$API = (function {	"use strict";	var awaiting = [], extensions = {}, data_input = {};	function API(data) {		this.push(data);		this.extensions = [];	}	function indexOf(needle, haystack) {		var i = 0, len = haystack.length;		for (i; i < len; i += 1) {			if (needle === haystack[i]) {				return i;			}		}		return -1;	}	API.prototype.constructor = API;	API.prototype.extend = function extend(properties) {		var prop;		for (prop in properties) {			if (properties.hasOwnProperty(prop)) {				this.constructor.prototype[prop] = properties[prop];			}		}		return this;	};	API.prototype.extend({ "baseUrl": 'http://sixtest.wikia.com/wiki/', "suffixUrl": '?action=raw', "append": function (data) { if (data !== undefined) { this.push.apply(this, data); }			return this; },		"length": 0, "splice": Array.prototype.splice, "slice": Array.prototype.slice, "push": Array.prototype.push, "clone": function { // TODO TESTIT var obj = new this.constructor; obj.extend(this); obj.length = 0; return obj; },		"sort": function (obj) { var func, sortBy, sortOrder, dataType; obj = obj || {}; sortBy = obj.sortBy || this.sortBy; sortOrder = obj.sortOrder || this.sortOrder || 'ascending'; dataType = obj.dataType || this.dataType || 'string'; func = function { var ret; if (sortOrder === 'ascending') { if (dataType === 'string') { if (sortBy !== undefined) { ret = function (a, b) { return a[sortBy] > b[sortBy]; }; } else { ret = function (a, b) { return a > b; }; }					} else if (dataType === 'number') { if (sortBy !== undefined) { ret = function (a, b) { return a[sortBy] - b[sortBy]; }; } else { ret = function (a, b) { return a - b; }; }					}				} else { if (dataType === 'string') { if (sortBy !== undefined) { ret = function (a, b) { return a[sortBy] < b[sortBy]; }; } else { ret = function (a, b) { return a < b; }; }					} else if (dataType === 'number') { if (sortBy !== undefined) { ret = function (a, b) { return b[sortBy] - a[sortBy]; }; } else { ret = function (a, b) { return b - a; }; }					}				}				return ret; };			return Array.prototype.sort.call(this, func); },		"find": function (arr, limit, param) { // iterate over arr, find 1 var i = 0, j, len = arr.length, leny, done, results = [], v;			if (typeof arr === 'string') { arr = [arr]; len = 1; }			param = param || this.sortBy; limit = (limit === true ? Infinity : (typeof limit === 'number' ? limit : 1)); for (i; i < len; i += 1) { j = 0; leny = this.length; done = false; for (j; j < leny && !done; j += 1) { v = param ? this[j][param] : this[j]; if (v === arr[i]) { results[i] = this[j]; done = true; }				}			}			return this.clone(results); },		"iterate": function (func) { var i = 0, len = this.length, res = []; for (i; i < len; i += 1) { res[res.length] = func(this[i]); }			return this.clone(res); },		"indexOf": function (val, prop) { var i = 0, len = this.length, c;			for (i; i < len; i += 1) { c = prop !== undefined ? this[i][prop] : this[i]; if (c === val) { return i;				} }			return -1; },		"filterValues": function (val, param) { var i = 0, len = this.length, res = [], c; val = val.length !== undefined ? val : [ val ]; for (i; i < len; i += 1) { c = param !== undefined ? this[i][c] : this[i]; if (this.indexOf.call(val, c) === -1) { res[res.length] = this[i]; }			}			return this.clone(res); },		"gt": function (index, param) { return (this.iterate(function (item) { return item[param] > index ? item : false; })).filterValues(false); },		"lt": function (index, param) { return (this.iterate(function (item) { return item[param] < index ? item : false; })).filterValues(false); },		"match": function (find, limit, param) { var i = 0, len = this.length, count = 0, results = [], type = typeof this[0] === 'object', c; param = param || this.sortBy || false; limit = (limit === true ? Infinity : (typeof limit === 'number' ? limit : 1)); if (find !== undefined) { for (i; i < len && count < limit; i += 1) { c = type ? this[i][param] : this[i]; if (c.match(find) !== null) { results[results.length] = this[i]; }				}			}			return this.clone(results); },		"setup": function {}, "load": function (data, input, callbacks) { var baseUrl = this.baseUrl, suffixUrl = this.suffixUrl, counterUpdate, i, len, done, head = document.getElementsByTagName('head')[0], context = this; if (typeof input === 'object' && input.length && typeof input[0] === 'function') { callbacks = input; input = {}; }			function getExtensionData(data) { var i, len, arr = []; for (i = 0, len = data.length; i < len; i += 1) { arr[i] = extensions[data[i]]; }				return arr; }			function counter(start, limit) { var count = start; if (limit === undefined) { throw new Error("Counter limit is undefined."); } return function (num) { count += num !== undefined ? num : 1; if (count >= limit) { return true; }					return false; };			}			counterUpdate = counter(0, awaiting.length); function onLoad(element, src, callback) { if (element.onload === element.onreadystatechange === undefined) { throw new Error("Could not reliably determine onload script method. Update or change your browser."); }				if (element.onload === undefined) { element.onreadystatechange = function { if (!done && (!this.readyState || this.readyState === "loaded" || this.readystate === "complete")) { done = true; // fix memory leak (IE) element.onreadystatechange = function { callback; element.onreadystatechange = null; };						}					};				} else { element.onload = function { // fix any possible reference loop memory leaks callback; element.onload = null; };				}				element.src = src; head.appendChild(element); return; }			function setup { var i, len; if (counterUpdate(1)) { for (i = 0, len = callbacks.length; i < len; i += 1) { if (typeof callbacks[i] === 'function') { callbacks[i].apply(data_input[data[i]] || {}, getExtensionData(data)); }					}				}			}			function loadExtension(extension) { var src = baseUrl + encodeURI(extension) + suffixUrl; onLoad(document.createElement('script'), src, setup); }			for (i = 0, len = data.length; i < len; i += 1) { if (extensions[data[i]] === undefined && indexOf(data[i], awaiting) === -1) { // extensions[data[i]] is being requested awaiting.push(data[i]); data_input[data[i]] = input; loadExtension(data[i]); setup; } else if (extensions[data[i]] === undefined && indexOf(data[i], awaiting) !== -1 && callbacks.length === 1) { // extensions[data[i]] is being assigned (i.e. script is loaded and running) extensions[data[i]] = callbacks[0].apply(null, getExtensionData(data)); setup; } else if (extensions[data[i]] !== undefined) { // extensions[data[i]] is already assigned setup; } else { throw new Error("Invalid load state."); }			}		}	});	return function APIInstance(setup, callback) {		var $API = new API, type = typeof setup, load = [], data = {}, callbacks = [], i = 0, len = arguments.length;		if (type === 'object') {			if (setup.load !== undefined && setup.load.length) {				load = setup.load;			}			if (setup.data !== undefined) {				data = setup.data;			}			return $API.load(load, data, [ callback ]);		}		if (type === 'string') {			// API is being called with:			// $API("Ext1", "Ext2", "Ext3", callback1, callback2, callback3)			while (i < len && typeof arguments[i] !== 'function') {				load[i] = arguments[i];				i += 1;			}			callbacks = Array.prototype.slice.apply(arguments, [i]);			return $API.load(load, callbacks);		}	}; });