is_defined = function(suspect) { return typeof suspect == "undefined" ? false : true; }; is_undefined = function(suspect) { return typeof suspect == "undefined" ? true : false; }; is_typeof = function(type, suspect) { if (is_undefined(type)) { throw new Error("is_typeof(Type, suspect): type is undefined"); } if (is_undefined(suspect)) { throw new Error("is_typeof(Type, suspect): suspect is undefined"); } return suspect.constructor == type ? true : false; }; is_numeric = function(suspect) { if (isNaN(suspect)) { return false; } return !isNaN(parseFloat(suspect)) && isFinite(suspect); }; is_string = function(suspect) { return is_typeof(String, suspect); }; is_array = function(suspect) { return is_typeof(Array, suspect); }; is_number = function(suspect) { return is_typeof(Number, suspect); }; is_date = function(suspect) { return is_typeof(Date, suspect); }; is_bool = function(suspect) { return is_typeof(Boolean, suspect); }; is_regex = function(suspect) { return is_typeof(RegExp, suspect); }; is_empty = function(suspect) { if (is_undefined(suspect)) { return true; } return suspect.length === 0; }; is_not_empty = function(suspect) { return suspect.length >= 1; }; if (!Element.prototype.addEventListener) { var oListeners = {}; function runListeners(oEvent) { if (!oEvent) { oEvent = window.event; } for (var iLstId = 0, iElId = 0, oEvtListeners = oListeners[oEvent.type]; iElId < oEvtListeners.aEls.length; iElId++) { if (oEvtListeners.aEls[iElId] === this) { for (iLstId; iLstId < oEvtListeners.aEvts[iElId].length; iLstId++) { oEvtListeners.aEvts[iElId][iLstId].call(this, oEvent); } break; } } } Element.prototype.addEventListener = function (sEventType, fListener) { if (oListeners.hasOwnProperty(sEventType)) { var oEvtListeners = oListeners[sEventType]; for (var nElIdx = -1, iElId = 0; iElId < oEvtListeners.aEls.length; iElId++) { if (oEvtListeners.aEls[iElId] === this) { nElIdx = iElId; break; } } if (nElIdx === -1) { oEvtListeners.aEls.push(this); oEvtListeners.aEvts.push([fListener]); this["on" + sEventType] = runListeners; } else { var aElListeners = oEvtListeners.aEvts[nElIdx]; if (this["on" + sEventType] !== runListeners) { aElListeners.splice(0); this["on" + sEventType] = runListeners; } for (var iLstId = 0; iLstId < aElListeners.length; iLstId++) { if (aElListeners[iLstId] === fListener) { return; } } aElListeners.push(fListener); } } else { oListeners[sEventType] = { aEls: [this], aEvts: [[fListener]] }; this["on" + sEventType] = runListeners; } }; Element.prototype.removeEventListener = function (sEventType) { if (!oListeners.hasOwnProperty(sEventType)) { return; } var oEvtListeners = oListeners[sEventType]; for (var nElIdx = -1, iElId = 0; iElId < oEvtListeners.aEls.length; iElId++) { if (oEvtListeners.aEls[iElId] === this) { nElIdx = iElId; break; } } if (nElIdx === -1) { return; } for (var iLstId = 0, aElListeners = oEvtListeners.aEvts[nElIdx]; iLstId < aElListeners.length; iLstId++) { aElListeners.splice(iLstId, 1); } }; } var Mod = {}; Mod.DOM = (function() { var timer, queue = []; function DOM() { this.cache = {}; this.is_ready = false; } DOM.prototype.add_event = function(element, type, fn, capture) { if (is_undefined(capture)) { capture = false; } if (is_string(element)) { element = this.cache[element]; } element.addEventListener(type, fn, capture); }; DOM.prototype.remove_event = function(element, type, fn, capture) { if (is_undefined(capture)) { capture = false; } if (is_string(element)) { element = this.cache[element]; } element.removeEventListener(type, fn, capture); }; DOM.prototype.call_when_ready = function(func) { if (this.is_ready) { return func(); } if (timer) { queue.push(func); } else { this.add_event(window, 'load', this.execute_ready_queue); queue.push(func); timer = setInterval(this.execute_ready_queue, 13); } }; DOM.prototype.execute_ready_queue = function() { if (this.is_ready) { return false; } if (document && document.getElementsByTagName && document.getElementById && document.body) { clearInterval(timer); timer = null; for(var i = 0, j = queue.length; i < j; i++) { queue[i](); } queue = []; this.is_ready = true; } }; DOM.prototype.add_elements = function(elements) { for(var key in elements) { if (elements.hasOwnProperty(key)) { this.add_element(key, elements[key]); } } }; DOM.prototype.add_element = function(key, element) { this.cache[key] = element; }; return DOM; })(); Mod.Module = (function() { function Module(name) { if (is_undefined(name)) { throw new Error("Mod.Module(name): name is undefined"); } this.dom = new Mod.DOM; this.data = {}; this.name = name; } Module.prototype.actions = function() {}; Module.prototype.run = function() { var mod = this; this.dom.call_when_ready(function() { mod.execute(); }); }; Module.prototype.execute = function() { this.actions(); }; Module.prototype.elements = function(elements) { if (is_undefined(elements)) { return this.dom.cache; } if (is_string(elements)) { var name = elements; return this.dom.cache[name]; } else { this.dom.add_elements(elements); } }; Module.prototype.set_data = function(key, value) { if (is_undefined(key)) { throw new Error(this.name + '.set_data(key, value): key is undefined'); } if (is_typeof(String, key) && is_undefined(value)) { throw new SyntaxError(this.name + 'Module.set_data(key, value): value is undefined'); } if (is_typeof(String, key)) { this.data[key] = value; } else if (is_typeof(Object, key)) { var data = key; for(var property in data) { this.data[property] = data[property]; } } return this; }; return Module; })(); Mod.Application = (function() { function Application(name) { if (is_undefined(name)) { throw new Error("new Mod.Application(name): name is undefined"); } this.name = name }; Application.prototype.add_module = function(name) { if (is_undefined(name)) { throw new Error("Mod.Application.add_module(name): name is undefined"); } if (is_defined(this[name])) { throw new Error("Mod.Application.add_module('" + name + "'): '" + name + "' already declared"); } if (this.name === name) { throw new Error("Mod.Application.add_module('" + name + "'): a module cannot have the same name as the application. It's bad idea. Do you really want to write " + name + "." + name + "? It's confusing.'"); } return this[name] = new Mod.Module(name); }; return Application; })();