diff --git a/.gitignore b/.gitignore index e5065e8..e1e512b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ kis-custom.js -kis-custom-min.js combine-build.php test.html \ No newline at end of file diff --git a/combine.php b/combine.php index 575402a..0391cd8 100755 --- a/combine.php +++ b/combine.php @@ -8,13 +8,11 @@ //The name of the source folder $folder = "src"; -$src_folder = "{$folder}/modules"; -$core_folder = "{$folder}/core"; $files = array(); //Get all the source files -if($dir = opendir($src_folder)) +if($dir = opendir($folder)) { while(($file = readdir($dir)) !== FALSE) { @@ -28,20 +26,37 @@ if($dir = opendir($src_folder)) closedir($dir); } -//Start with the core -$new_file = file_get_contents($core_folder."/core.js") . "\n"; +//Define files that aren't modules +$special_files = array( + 'core.js', +); +//Filter out special files +$src_files = array_diff($files, $special_files); + +//Start with the core +$new_file = file_get_contents($folder."/core.js") . "\n"; + +//Add the opening of the function for the modules +$new_file .= "\n// --------------------------------------------------------------------------\n\n"; //Add the modules -foreach($files as $f) +foreach($src_files as $f) { - $farray = file($src_folder."/".$f, FILE_IGNORE_NEW_LINES); + $farray = file($folder."/".$f, FILE_IGNORE_NEW_LINES); $flen = count($farray); + //Indent each module 1 tab, for neatness + for($i=0;$i<$flen;$i++) + { + if($farray[$i] == ""){ continue; } + $farray[$i] = "\t".$farray[$i]; + } + $module = implode("\n", $farray); - $new_file .= "\n// --------------------------------------------------------------------------\n\n".$module."\n"; + $new_file .= "\n\t// --------------------------------------------------------------------------\n\n".$module."\n"; } @@ -56,7 +71,7 @@ curl_setopt($ch, CURLOPT_POSTFIELDS, 'output_info=compiled_code&output_format=te $output = curl_exec($ch); curl_close($ch); -file_put_contents("kis-custom-min.js", $output); +file_put_contents("kis-min.js", $output); //Display the output on-screen too diff --git a/kis-all.js b/kis-all.js index 4129637..0ca172a 100644 --- a/kis-all.js +++ b/kis-all.js @@ -185,987 +185,892 @@ // -------------------------------------------------------------------------- -/* - * classList.js: Cross-browser full element.classList implementation. - * 2011-06-15 - * - * By Eli Grey, http://eligrey.com - * Public Domain. - * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. - */ -if (typeof document !== "undefined" && !("classList" in document.createElement("a"))) -{ - (function (view){ - - var classListProp = "classList", - protoProp = "prototype", - elemCtrProto = (view.HTMLElement || view.Element)[protoProp], - objCtr = Object, - strTrim = String[protoProp].trim || - function () - { - return this.replace(/^\s+|\s+$/g, ""); - }, - arrIndexOf = Array[protoProp].indexOf || - function (item) - { - var - i = 0, - len = this.length; - for (; i < len; i++) - { - if (i in this && this[i] === item) - { - return i; - } - } - return -1; - } - // Vendors: please allow content code to instantiate DOMExceptions - , - DOMEx = function (type, message) - { - this.name = type; - this.code = DOMException[type]; - this.message = message; - }, - checkTokenAndGetIndex = function (classList, token) - { - if (token === "") - { - throw new DOMEx("SYNTAX_ERR", "An invalid or illegal string was specified"); - } - if (/\s/.test(token)) - { - throw new DOMEx("INVALID_CHARACTER_ERR", "String contains an invalid character"); - } - return arrIndexOf.call(classList, token); - }, - ClassList = function (elem) - { - var - trimmedClasses = strTrim.call(elem.className), - classes = trimmedClasses ? trimmedClasses.split(/\s+/) : [], - i = 0, - len = classes.length; - for (; i < len; i++) - { - this.push(classes[i]); - } - this._updateClassName = function () - { - elem.className = this.toString(); - }; - }, - classListProto = ClassList[protoProp] = [], - classListGetter = function () - { - return new ClassList(this); - }; - // Most DOMException implementations don't allow calling DOMException's toString() - // on non-DOMExceptions. Error's toString() is sufficient here. - DOMEx[protoProp] = Error[protoProp]; - classListProto.item = function (i) - { - return this[i] || null; - }; - classListProto.contains = function (token) - { - token += ""; - return checkTokenAndGetIndex(this, token) !== -1; - }; - classListProto.add = function (token) - { - token += ""; - if (checkTokenAndGetIndex(this, token) === -1) - { - this.push(token); - this._updateClassName(); - } - }; - classListProto.remove = function (token) - { - token += ""; - var index = checkTokenAndGetIndex(this, token); - if (index !== -1) - { - this.splice(index, 1); - this._updateClassName(); - } - }; - classListProto.toggle = function (token) - { - token += ""; - if (checkTokenAndGetIndex(this, token) === -1) - { - this.add(token); - } - else - { - this.remove(token); - } - }; - classListProto.toString = function () - { - return this.join(" "); - }; - - if (objCtr.defineProperty) - { - var classListPropDesc = { - get: classListGetter, - enumerable: true, - configurable: true - }; - try - { - objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc); - } - catch (ex) - { // IE 8 doesn't support enumerable:true - if (ex.number === -0x7FF5EC54) - { - classListPropDesc.enumerable = false; - objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc); - } - } - } - else if (objCtr[protoProp].__defineGetter__) - { - elemCtrProto.__defineGetter__(classListProp, classListGetter); - } - - }(self)); -} - -// -------------------------------------------------------------------------- - -/** - * Dom manipulation object - * - */ -(function (){ - var d, tag_reg, class_reg; - - tag_reg = /^([\w\-]+)$/; - class_reg = /\.([\w\-]+)$/; - - - //Private function for getting/setting attributes - function _attr(sel, name, value) - { - var oldVal, doAttr; - - //Get the value of the attribute, if it exists - if (typeof sel.hasAttribute !== "undefined") - { - if (sel.hasAttribute(name)) - { - oldVal = sel.getAttribute(name); - } - - doAttr = true; - } - else if (typeof sel[name] !== "undefined") - { - oldVal = sel[name]; - doAttr = false; - } - else if (name === "class" && typeof sel.className !== "undefined") //className attribute - { - name = "className"; - oldVal = sel.className; - doAttr = false; - } - - //Well, I guess that attribute doesn't exist - if (typeof oldVal === "undefined" && (typeof value === "undefined" || value === null)) - { - console.log(value); - console.log(sel); - console.log("Element does not have the selected attribute"); - return; - } - - //No value to set? Return the current value - if (typeof value === "undefined") - { - return oldVal; - } - - //Determine what to do with the attribute - if (typeof value !== "undefined" && value !== null) - { - if(doAttr === true) - { - sel.setAttribute(name, value); - } - else - { - sel[name] = value; - } - } - else if (value === null) - { - if(doAttr === true) - { - sel.removeAttribute(name); - } - else - { - delete sel[name]; - } - } - - return (typeof value !== "undefined") ? value : oldVal; - } - - function _toCamel(s) - { - return s.replace(/(\-[a-z])/g, function($1){ - return $1.toUpperCase().replace('-',''); - }); - } - - function _css(sel, prop, val) - { - var equi; - - //Camel-case - prop = _toCamel(prop); - - //Equivalent properties for 'special' browsers - equi = { - outerHeight: "offsetHeight", - outerWidth: "offsetWidth", - top: "posTop" - }; - - - //If you don't define a value, try returning the existing value - if(typeof val === "undefined" && sel.style[prop] !== "undefined") - { - return sel.style[prop]; - } - else if(typeof val === "undefined" && sel.style[equi[prop]] !== "undefined") - { - return sel.style[equi[prop]]; - } - - //Let's try the easy way first - if(typeof sel.style[prop] !== "undefined") - { - sel.style[prop] = val; - - //Short circuit - return; - } - else if(sel.style[equi[prop]]) - { - sel.style[equi[prop]] = val; - return; - } - - //No matches? Well, lets log it for now - console.log("Property " + prop + " nor an equivalent seems to exist"); - } - // -------------------------------------------------------------------------- - d = { - addClass: function (c) - { - $_.each(function (e){ - e.classList.add(c); - }); - }, - removeClass: function (c) - { - $_.each(function (e){ - e.classList.remove(c); - }); - }, - hide: function () - { - this.css('display', 'none'); - }, - show: function (type) - { - if (typeof type === "undefined") - { - type = "block"; - } + /* + * classList.js: Cross-browser full element.classList implementation. + * 2011-06-15 + * + * By Eli Grey, http://eligrey.com + * Public Domain. + * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. + */ - this.css("display", type); - }, - attr: function (name, value) - { - var sel = this.el; - - //Make sure you don't try to get a bunch of elements - if (sel.length > 1 && typeof value === "undefined") - { - console.log(sel); - console.log("Must be a singular element"); - return; - } - else if (sel.length > 1 && typeof value !== "undefined") //You can set a bunch, though - { - $_.each(function (e){ - return _attr(e, name, value); - }); - } - else //Normal behavior - { - return _attr(sel, name, value); - } - }, - text: function (value) - { - var oldValue, set, type, sel; + if (typeof document !== "undefined" && !("classList" in document.createElement("a"))) + { + (function (view){ - sel = this.el; - - set = (typeof value !== "undefined") ? true : false; - - type = (typeof sel.innerText !== "undefined") - ? "innerText" - : (typeof sel.textContent !== "undefined") - ? "textContent" - : "innerHTML"; - - oldValue = sel[type]; - - if(set) - { - sel[type] = value; - return value; - } - else - { - return oldValue; - } - }, - css: function (prop, val) - { - //Return the current value if a value is not set - if(typeof val === "undefined") - { - return _css(this.el, prop); - } - - $_.each(function (e){ - _css(e, prop, val); - }); - } - }; - - $_.ext('dom', d); - -}()); - -// -------------------------------------------------------------------------- - -/** - * Store object - * - * Wrapper for localstorage data serialization - */ -(function (){ - var store = { - get: function (key) - { - return JSON.parse(localStorage.getItem(key)); - }, - set: function (key, value) - { - if (typeof value !== "string") - { - value = JSON.stringify(value); - } - localStorage.setItem(key, value); - }, - remove: function (key) - { - localStorage.removeItem(key); - }, - getAll: function () - { - var i, - len, - data; - len = localStorage.length; - data = {}; - - for (i = 0; i < len; i++) - { - var name = localStorage.key(i); - var value = localStorage.getItem(name); - data[name] = value; - } - - return data; - } - }; - - $_.ext('store', store); -}()); - -// -------------------------------------------------------------------------- - -/** - * Qs - * - * Object for encoding and decoding querystrings and hashbang strings - */ -(function (){ - - $_.hb = (history.pushState) ? false : true; - - var qs = { - parse: function (hb) - { - hb = hb || $_.hb; - - var h, i, hString, pairs, pLen, data, y; - - data = {}; - - if (hb === true) - { - h = location.hash.split('#!/'); - hString = (h.length > 1) ? h[1] : ''; - } - else if (hb === false || hb === undefined) - { - hString = window.location.search.substring(1); - } - else - { - return false; - } - - pairs = hString.split('&'); - - pLen = pairs.length; - - for (i = 0; i < pLen; i++) - { - y = pairs[i].split('='); - - if (y.length < 2) + var classListProp = "classList", + protoProp = "prototype", + elemCtrProto = (view.HTMLElement || view.Element)[protoProp], + objCtr = Object, + strTrim = String[protoProp].trim || + function () { - return data; - } - - data[y[0]] = y[1]; - } - - return data; - }, - set: function (key, value, hb) - { - hb = hb || $_.hb; - var pairs = this.parse(hb); - - if (key !== undefined && value !== undefined) - { - pairs[key] = value; - } - - var vars = []; - - for (var x in pairs) - { - if (pairs.hasOwnProperty(x)) - { - vars.push(x + '=' + pairs[x]); - } - } - - var qs = vars.join('&'); - - if (hb === true) - { - qs = '!/' + qs; - location.hash = qs; - } - - return qs; - }, - get: function (key, hb) - { - hb = hb || $_.hb; - var pairs = this.parse(hb); - return (pairs[key]) ? pairs[key] : ''; - } - }; - - $_.ext('qs', qs); - -}()); - -// -------------------------------------------------------------------------- - -/** - * Ajax - * - * Object for making ajax requests - */ -(function (){ - - var ajax = { - _do: function (url, data, callback, isPost) - { - if (typeof callback === "undefined") - { - callback = function (){}; - } - - var request = (typeof window.XMLHttpRequest !== "undefined") - ? new XMLHttpRequest() - : false; - - var type = (isPost) ? "POST" : "GET"; - - url += (type === "GET") ? "?"+this._serialize(data) : ''; - - request.open(type, url); - - request.onreadystatechange = function () - { - if (request.readyState === 4) - { - callback(request.responseText); - } - }; - - if (type === "POST") - { - request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); - request.send(this._serialize(data)); - } - else - { - request.send(null); - } - }, - _serialize: function (data) - { - var pairs = []; - - for (var name in data) - { - if (!data.hasOwnProperty(name)) - { - continue; - } - if (typeof data[name] === "function") - { - continue; - } - - var value = data[name].toString(); - - name = encodeURIComponent(name); - value = encodeURIComponent(value); - - pairs.push(name + "=" + value); - } - - return pairs.join("&"); - } - }; - - $_.ext('get', function (url, data, callback){ - ajax._do(url, data, callback, false); - }); - - $_.ext('post', function (url, data, callback){ - ajax._do(url, data, callback, true); - }); -}()); - -// -------------------------------------------------------------------------- - -/** - * Util Object - * - * Various object and string manipulation functions - */ -(function(){ - - "use strict"; - - var u = { - reverse_key_sort: function(o) - { - //Define some variables - var keys = [], - num_keys = 0, - new_o = {}, - i; - - //Extract the keys - keys = this.object_keys(o); - - //Sort the keys - keys.sort(function (b, a) { - var aFloat = parseFloat(a), - bFloat = parseFloat(b), - aNumeric = aFloat + '' === a, - bNumeric = bFloat + '' === b; - - if (aNumeric && bNumeric) - { - return aFloat > bFloat ? 1 : aFloat < bFloat ? -1 : 0; - } - else if (aNumeric && !bNumeric) - { - return 1; - } - else if (!aNumeric && bNumeric) + return this.replace(/^\s+|\s+$/g, ""); + }, + arrIndexOf = Array[protoProp].indexOf || + function (item) { + var + i = 0, + len = this.length; + for (; i < len; i++) + { + if (i in this && this[i] === item) + { + return i; + } + } return -1; } - - return a > b ? 1 : a < b ? -1 : 0; - }); - - //cache object/array size - num_keys = keys.length; - - //Recreate the object/array - for(i=0; i < num_keys; i++) - { - new_o[keys[i]] = o[keys[i]]; - } - - return new_o; - }, - object_keys: function(o) - { - var keys = [], - k; - - for(k in o) - { - if(o.hasOwnProperty(k)) + // Vendors: please allow content code to instantiate DOMExceptions + , + DOMEx = function (type, message) { - keys.push(k); - } - } - - return keys; - }, - object_values: function(o) - { - var vals = [], - prop; - - for(prop in o) - { - vals.push(o[prop]); - } - - return vals; - }, - array_combine: function(keys, vals) - { - var new_object = {}, - num_keys, - i = 0; - - //Extract the keys or values if needed - if($_.type(keys) !== "array") - { - keys = this.object_values(keys); - } - if($_.type(vals) !== "array") - { - vals = this.object_values(vals); - } - - //cache the number of keys - num_keys = keys.length; - - if(num_keys !== vals.length) - { - console.log("Object combine requires two arrays of the same size"); - return false; - } - - //Create and return the new object - for(i = 0; i < num_keys; i++) - { - new_object[keys[i]] = vals[i]; - } - - return new_object; - }, - object_merge: function() - { - var args = Array.prototype.slice.call(arguments), - arg_len = args.length, - new_obj = {}, - arg, - iarg_len = 0, - i, - j, - x, - is_array = true; - - //Check for an array in the arguments - for(i=0; i < arg_len; i++) - { - if($_.type(args[i]) !== "array") + this.name = type; + this.code = DOMException[type]; + this.message = message; + }, + checkTokenAndGetIndex = function (classList, token) { - is_array = false; - break; - } - } - - //If all the arguments are javascript arrays - if(is_array) - { - new_obj = []; - //Let javascript do all the work! - for(i=0; i< arg_len; i++) - { - new_obj = new_obj.contact(args[i]); - } - - //Return early - return new_obj; - } - - //No, there's at least one object - for(i=0, x=0; i < arg_len; i++) - { - arg = args[i]; - - // If the argument is an array, add the array items as - // numeric object properties - if ($_.type(arg) == "array") - { - for (j=0, iarg_len= arg.length; j < iarg_len; j++) + if (token === "") { - new_obj[x++] = arg[j]; + throw new DOMEx("SYNTAX_ERR", "An invalid or illegal string was specified"); } + if (/\s/.test(token)) + { + throw new DOMEx("INVALID_CHARACTER_ERR", "String contains an invalid character"); + } + return arrIndexOf.call(classList, token); + }, + ClassList = function (elem) + { + var + trimmedClasses = strTrim.call(elem.className), + classes = trimmedClasses ? trimmedClasses.split(/\s+/) : [], + i = 0, + len = classes.length; + for (; i < len; i++) + { + this.push(classes[i]); + } + this._updateClassName = function () + { + elem.className = this.toString(); + }; + }, + classListProto = ClassList[protoProp] = [], + classListGetter = function () + { + return new ClassList(this); + }; + // Most DOMException implementations don't allow calling DOMException's toString() + // on non-DOMExceptions. Error's toString() is sufficient here. + DOMEx[protoProp] = Error[protoProp]; + classListProto.item = function (i) + { + return this[i] || null; + }; + classListProto.contains = function (token) + { + token += ""; + return checkTokenAndGetIndex(this, token) !== -1; + }; + classListProto.add = function (token) + { + token += ""; + if (checkTokenAndGetIndex(this, token) === -1) + { + this.push(token); + this._updateClassName(); + } + }; + classListProto.remove = function (token) + { + token += ""; + var index = checkTokenAndGetIndex(this, token); + if (index !== -1) + { + this.splice(index, 1); + this._updateClassName(); + } + }; + classListProto.toggle = function (token) + { + token += ""; + if (checkTokenAndGetIndex(this, token) === -1) + { + this.add(token); } else { - for (j in arg) - { - if(arg.hasOwnProperty(j)) - { - // If the key is numeric, add the property with - // a numeric key - if(parseInt(j, 10) + '' === j) - { - new_obj[x++] = arg[j]; - } - else - { - new_obj[j] = arg[j]; - } - } - } - } - } - - return new_obj; - }, - str_trans: function(string, from, to) - { - - }, - str_replace: function(from, to, string) - { - } - }; - - //Add it to the $_ object - $_.ext('util', u); -}()); - -// -------------------------------------------------------------------------- - -/** - * Event object - * - * Event api wrapper - */ -(function (){ - - // Property name for expandos on DOM objects - var kis_expando = "KIS_0_3_0"; - - var attach, remove, add_remove, e, attach_delegate, attach_live; - - // Define the proper attach and remove functions - // based on browser support - if(typeof document.addEventListener !== "undefined") - { - attach = function (sel, event, callback) - { - if (typeof sel.addEventListener !== "undefined") + this.remove(token); + } + }; + classListProto.toString = function () { - sel.addEventListener(event, callback, false); - } - }; - remove = function (sel, event, callback) - { - if (typeof sel.removeEventListener !== "undefined") + return this.join(" "); + }; + + if (objCtr.defineProperty) { - sel.removeEventListener(event, callback, false); - } - }; - } - //typeof function doesn't work in IE where attachEvent is available: brute force it - else if(typeof document.attachEvent !== "undefined") - { - attach = function (sel, event, callback) - { - function listener () { - // Internet Explorer fails to correctly set the 'this' object - // for event listeners, so we need to set it ourselves. - callback.apply(arguments); - } - - if (typeof sel.attachEvent !== "undefined") - { - remove(event, callback); // Make sure we don't have duplicate listeners - - sel.attachEvent("on" + event, listener); - // Store our listener so we can remove it later - var expando = sel[kis_expando] = sel[kis_expando] || {}; - expando.listeners = expando.listeners || {}; - expando.listeners[event] = expando.listeners[event] || []; - expando.listeners[event].push({ - callback: callback, - listener: listener - }); - } - else - { - console.log("Failed to attach event:"+event+" on "+sel); - } - }; - remove = function (sel, event, callback) - { - if(typeof sel.detachEvent !== "undefined") - { - var expando = sel[kis_expando]; - if (expando && expando.listeners - && expando.listeners[event]) + var classListPropDesc = { + get: classListGetter, + enumerable: true, + configurable: true + }; + try { - var listeners = expando.listeners[event]; - var len = listeners.length; - for (var i=0; i 1 && typeof value === "undefined") + { + console.log(sel); + console.log("Must be a singular element"); + return; + } + else if (sel.length > 1 && typeof value !== "undefined") //You can set a bunch, though + { + $_.each(function (e){ + return _attr(e, name, value); + }); + } + else //Normal behavior + { + return _attr(sel, name, value); + } + }, + text: function (value) + { + var oldValue, set, type, sel; + + sel = this.el; + + set = (typeof value !== "undefined") ? true : false; + + type = (typeof sel.innerText !== "undefined") + ? "innerText" + : (typeof sel.textContent !== "undefined") + ? "textContent" + : "innerHTML"; + + oldValue = sel[type]; + + if(set) + { + sel[type] = value; + return value; + } + else + { + return oldValue; + } + }, + css: function (prop, val) + { + //Return the current value if a value is not set + if(typeof val === "undefined") + { + return _css(this.el, prop); + } + + $_.each(function (e){ + _css(e, prop, val); + }); + } + }; + + $_.ext('dom', d); + + }()); + + // -------------------------------------------------------------------------- + + /** + * Store object + * + * Wrapper for localstorage data serialization + */ + (function (){ + var store = { + get: function (key) + { + return JSON.parse(localStorage.getItem(key)); + }, + set: function (key, value) + { + if (typeof value !== "string") + { + value = JSON.stringify(value); + } + localStorage.setItem(key, value); + }, + remove: function (key) + { + localStorage.removeItem(key); + }, + getAll: function () + { + var i, + len, + data; + len = localStorage.length; + data = {}; + + for (i = 0; i < len; i++) + { + var name = localStorage.key(i); + var value = localStorage.getItem(name); + data[name] = value; + } + + return data; + } + }; + + $_.ext('store', store); + }()); + + // -------------------------------------------------------------------------- + + /** + * Qs + * + * Object for encoding and decoding querystrings and hashbang strings + */ + (function (){ + + $_.hb = (history.pushState) ? false : true; + + var qs = { + parse: function (hb) + { + hb = hb || $_.hb; + + var h, i, hString, pairs, pLen, data, y; + + data = {}; + + if (hb === true) + { + h = location.hash.split('#!/'); + hString = (h.length > 1) ? h[1] : ''; + } + else if (hb === false || hb === undefined) + { + hString = window.location.search.substring(1); + } + else + { + return false; + } + + pairs = hString.split('&'); + + pLen = pairs.length; + + for (i = 0; i < pLen; i++) + { + y = pairs[i].split('='); + + if (y.length < 2) + { + return data; + } + + data[y[0]] = y[1]; + } + + return data; + }, + set: function (key, value, hb) + { + hb = hb || $_.hb; + var pairs = this.parse(hb); + + if (key !== undefined && value !== undefined) + { + pairs[key] = value; + } + + var vars = []; + + for (var x in pairs) + { + if (pairs.hasOwnProperty(x)) + { + vars.push(x + '=' + pairs[x]); + } + } + + var qs = vars.join('&'); + + if (hb === true) + { + qs = '!/' + qs; + location.hash = qs; + } + + return qs; + }, + get: function (key, hb) + { + hb = hb || $_.hb; + var pairs = this.parse(hb); + return (pairs[key]) ? pairs[key] : ''; + } + }; + + $_.ext('qs', qs); + + }()); + + // -------------------------------------------------------------------------- + + //Fix $_ is not defined errors + var $_ = $_ || window.$_; + + // -------------------------------------------------------------------------- + + /** + * Ajax + * + * Object for making ajax requests + */ + (function (){ + + var ajax = { + _do: function (url, data, callback, isPost) + { + if (typeof callback === "undefined") + { + callback = function (){}; + } + + var request = (typeof window.XMLHttpRequest !== "undefined") + ? new XMLHttpRequest() + : false; + + var type = (isPost) ? "POST" : "GET"; + + url += (type === "GET") ? "?"+this._serialize(data) : ''; + + request.open(type, url); + + request.onreadystatechange = function () + { + if (request.readyState === 4) + { + callback(request.responseText); + } + }; + + if (type === "POST") + { + request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); + request.send(this._serialize(data)); + } + else + { + request.send(null); + } + }, + _serialize: function (data) + { + var pairs = []; + + for (var name in data) + { + if (!data.hasOwnProperty(name)) + { + continue; + } + if (typeof data[name] === "function") + { + continue; + } + + var value = data[name].toString(); + + name = encodeURIComponent(name); + value = encodeURIComponent(value); + + pairs.push(name + "=" + value); + } + + return pairs.join("&"); + } + }; + + $_.ext('get', function (url, data, callback){ + ajax._do(url, data, callback, false); + }); + + $_.ext('post', function (url, data, callback){ + ajax._do(url, data, callback, true); + }); + }()); + + // -------------------------------------------------------------------------- + + /** + * Util Object + * + * Various object and string manipulation functions + */ + (function(){ + + var u = { + object_keys: function(o) + { + var keys = [], + k; + + for(k in o) + { + if(o.hasOwnProperty(k)) + { + keys.push(k); + } + } + + return keys; + }, + object_values: function(o) + { + var vals = [], + prop; + + for(prop in o) + { + vals.push(o[prop]); + } + + return vals; + }, + object_merge: function() + { + + }, + reverse_key_sort: function(o) + { + //Define some variables + var keys = [], + num_keys = 0, + new_o = {}, + i, + k, + x; + + //Extract the keys + keys = this.object_keys(o); + + //Sort the keys + keys.sort(function (b, a) { + + var aFloat = parseFloat(a), + bFloat = parseFloat(b), + aNumeric = aFloat + '' === a, + bNumeric = bFloat + '' === b; + + if (aNumeric && bNumeric) + { + return aFloat > bFloat ? 1 : aFloat < bFloat ? -1 : 0; + } + else if (aNumeric && !bNumeric) + { + return 1; + } + else if (!aNumeric && bNumeric) + { + return -1; + } + + return a > b ? 1 : a < b ? -1 : 0; + }); + + //cache object/array size + num_keys = keys.length; + + //Recreate the object/array + for(i=0; i < num_keys; i++) + { + k = keys[i]; + new_o[k] = o[k]; + } + + return new_o; + }, + str_trans: function(string, from, to) + { + + } + }; + + //Add it to the $_ object + $_.ext('util', u); + }()); + + // -------------------------------------------------------------------------- + + /** + * Event object + * + * Event api wrapper + */ + (function (){ + + // Property name for expandos on DOM objects + var kis_expando = "KIS_0_3_0"; + + var attach, remove, add_remove, e, attach_delegate, attach_live; + + // Define the proper attach and remove functions + // based on browser support + if(typeof document.addEventListener !== "undefined") + { + attach = function (sel, event, callback) + { + if (typeof sel.addEventListener !== "undefined") + { + sel.addEventListener(event, callback, false); + } + }; + remove = function (sel, event, callback) + { + if (typeof sel.removeEventListener !== "undefined") + { + sel.removeEventListener(event, callback, false); + } + }; + } + //typeof function doesn't work in IE where attachEvent is available: brute force it + else if(typeof document.attachEvent !== "undefined") + { + attach = function (sel, event, callback) + { + function listener () { + // Internet Explorer fails to correctly set the 'this' object + // for event listeners, so we need to set it ourselves. + callback.apply(arguments); + } + + if (typeof sel.attachEvent !== "undefined") + { + remove(event, callback); // Make sure we don't have duplicate listeners + + sel.attachEvent("on" + event, listener); + // Store our listener so we can remove it later + var expando = sel[kis_expando] = sel[kis_expando] || {}; + expando.listeners = expando.listeners || {}; + expando.listeners[event] = expando.listeners[event] || []; + expando.listeners[event].push({ + callback: callback, + listener: listener + }); + } + else + { + console.log("Failed to attach event:"+event+" on "+sel); + } + }; + remove = function (sel, event, callback) + { + if(typeof sel.detachEvent !== "undefined") + { + var expando = sel[kis_expando]; + if (expando && expando.listeners + && expando.listeners[event]) + { + var listeners = expando.listeners[event]; + var len = listeners.length; + for (var i=0; i1&&typeof a==="undefined")console.log(d),console.log("Must be a singular element");else if(d.length>1&&typeof a!== -"undefined")$_.each(function(d){return b(d,c,a)});else return b(d,c,a)},text:function(c){var a,d,b;b=this.el;d=typeof b.innerText!=="undefined"?"innerText":typeof b.textContent!=="undefined"?"textContent":"innerHTML";a=b[d];return typeof c!=="undefined"?b[d]=c:a},css:function(c,a){if(typeof a==="undefined")return f(this.el,c);$_.each(function(d){f(d,c,a)})}})})(); +"undefined")$_.each(function(d){return b(d,c,a)});else return b(d,c,a)},text:function(c){var a,d,b;b=this.el;d=typeof b.innerText!=="undefined"?"innerText":typeof b.textContent!=="undefined"?"textContent":"innerHTML";a=b[d];return typeof c!=="undefined"?b[d]=c:a},css:function(b,a){if(typeof a==="undefined")return f(this.el,b);$_.each(function(d){f(d,b,a)})}})})(); (function(){$_.ext("store",{get:function(b){return JSON.parse(localStorage.getItem(b))},set:function(b,e){typeof e!=="string"&&(e=JSON.stringify(e));localStorage.setItem(b,e)},remove:function(b){localStorage.removeItem(b)},getAll:function(){var b,e,f;e=localStorage.length;f={};for(b=0;b1?b[1]:"";else if(b===false||b===void 0)b=window.location.search.substring(1);else return false;e=b.split("&");f=e.length;for(b=0;be?1:ca?1:bc?1:ba?1:d 1 && typeof value === "undefined") + { + console.log(sel); + console.log("Must be a singular element"); + return; + } + else if (sel.length > 1 && typeof value !== "undefined") //You can set a bunch, though + { + $_.each(function (e){ + return _attr(e, name, value); + }); + } + else //Normal behavior + { + return _attr(sel, name, value); + } + }, + text: function (value) + { + var oldValue, set, type, sel; + + sel = this.el; + + set = (typeof value !== "undefined") ? true : false; + + type = (typeof sel.innerText !== "undefined") + ? "innerText" + : (typeof sel.textContent !== "undefined") + ? "textContent" + : "innerHTML"; + + oldValue = sel[type]; + + if(set) + { + sel[type] = value; + return value; + } + else + { + return oldValue; + } + }, + css: function (prop, val) + { + //Return the current value if a value is not set + if(typeof val === "undefined") + { + return _css(this.el, prop); + } + + $_.each(function (e){ + _css(e, prop, val); + }); + } + }; + + $_.ext('dom', d); + +}()); diff --git a/src/QS.js b/src/QS.js new file mode 100644 index 0000000..8b9dce1 --- /dev/null +++ b/src/QS.js @@ -0,0 +1,91 @@ +/** + * Qs + * + * Object for encoding and decoding querystrings and hashbang strings + */ +(function (){ + + $_.hb = (history.pushState) ? false : true; + + var qs = { + parse: function (hb) + { + hb = hb || $_.hb; + + var h, i, hString, pairs, pLen, data, y; + + data = {}; + + if (hb === true) + { + h = location.hash.split('#!/'); + hString = (h.length > 1) ? h[1] : ''; + } + else if (hb === false || hb === undefined) + { + hString = window.location.search.substring(1); + } + else + { + return false; + } + + pairs = hString.split('&'); + + pLen = pairs.length; + + for (i = 0; i < pLen; i++) + { + y = pairs[i].split('='); + + if (y.length < 2) + { + return data; + } + + data[y[0]] = y[1]; + } + + return data; + }, + set: function (key, value, hb) + { + hb = hb || $_.hb; + var pairs = this.parse(hb); + + if (key !== undefined && value !== undefined) + { + pairs[key] = value; + } + + var vars = []; + + for (var x in pairs) + { + if (pairs.hasOwnProperty(x)) + { + vars.push(x + '=' + pairs[x]); + } + } + + var qs = vars.join('&'); + + if (hb === true) + { + qs = '!/' + qs; + location.hash = qs; + } + + return qs; + }, + get: function (key, hb) + { + hb = hb || $_.hb; + var pairs = this.parse(hb); + return (pairs[key]) ? pairs[key] : ''; + } + }; + + $_.ext('qs', qs); + +}()); diff --git a/src/ajax.js b/src/ajax.js new file mode 100644 index 0000000..050f649 --- /dev/null +++ b/src/ajax.js @@ -0,0 +1,78 @@ +/** + * Ajax + * + * Object for making ajax requests + */ +(function (){ + + var ajax = { + _do: function (url, data, callback, isPost) + { + if (typeof callback === "undefined") + { + callback = function (){}; + } + + var request = (typeof window.XMLHttpRequest !== "undefined") + ? new XMLHttpRequest() + : false; + + var type = (isPost) ? "POST" : "GET"; + + url += (type === "GET") ? "?"+this._serialize(data) : ''; + + request.open(type, url); + + request.onreadystatechange = function () + { + if (request.readyState === 4) + { + callback(request.responseText); + } + }; + + if (type === "POST") + { + request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); + request.send(this._serialize(data)); + } + else + { + request.send(null); + } + }, + _serialize: function (data) + { + var pairs = []; + + for (var name in data) + { + if (!data.hasOwnProperty(name)) + { + continue; + } + if (typeof data[name] === "function") + { + continue; + } + + var value = data[name].toString(); + + name = encodeURIComponent(name); + value = encodeURIComponent(value); + + pairs.push(name + "=" + value); + } + + return pairs.join("&"); + } + }; + + $_.ext('get', function (url, data, callback){ + ajax._do(url, data, callback, false); + }); + + $_.ext('post', function (url, data, callback){ + ajax._do(url, data, callback, true); + }); +}()); \ No newline at end of file diff --git a/src/core.js b/src/core.js new file mode 100644 index 0000000..be53372 --- /dev/null +++ b/src/core.js @@ -0,0 +1,184 @@ +/** + Kis JS Keep It Simple JS Library + Copyright Timothy J. Warren + License Public Domain + Version 0.3.0 + */ +(function (){ + + "use strict"; + + //Browser requirements check + if (!document.querySelectorAll) + { + return; + } + + var $_, $, dcopy, sel; + + /** + * $ + * + * Simple DOM selector function + */ + $ = function (a) + { + var x; + if (typeof a !== "string" || typeof a === "undefined"){ return a;} + + //Pick the quickest method for each kind of selector + if (a.match(/^#([\w\-]+$)/)) + { + return document.getElementById(a.split('#')[1]); + } + else if (a.match(/^([\w\-]+)$/)) + { + x = document.getElementsByTagName(a); + } + else + { + x = document.querySelectorAll(a); + } + + //Return the single object if applicable + return (x.length === 1) ? x[0] : x; + }; + + /** + * $_ + * + * Constructor function + */ + $_ = function(s) + { + //Have documentElement be default selector, just in case + if(typeof s === "undefined") + { + sel = (typeof $_.el !== "undefined") + ? $_.el + : document.documentElement; + } + else + { + sel = (typeof s !== "object") ? $(s) : s; + } + + // Add the selector to the prototype + $_.prototype.el = sel; + + // Make a copy before adding properties + var self = dcopy($_); + + // Give sel to each extension. + for(var i in self) + { + if(typeof self[i] === "object") + { + self[i].el = sel; + } + } + + self.el = sel; + + return self; + }; + + /** + * Deep copy/prototypical constructor function + */ + dcopy = function(obj) + { + var type, F; + + if(typeof obj === "undefined") + { + return; + } + + if(typeof Object.create !== "undefined") + { + return Object.create(obj); + } + + type = typeof obj; + + if(type !== "object" && type !== "function") + { + return; + } + + F = function(){}; + + F.prototype = obj; + + return new F(); + + }; + + //Function to add to $_ object, and get sel + $_.ext = function(name, obj) + { + obj.el = sel; + $_[name] = obj; + }; + + //Selector iteration + $_.ext('each', function (callback) + { + if(typeof sel.length !== "undefined" && sel !== window) + { + var len = sel.length; + + if (len === 0) + { + return; + } + + var selx; + for (var x = 0; x < len; x++) + { + selx = (sel.item(x)) ? sel.item(x) : sel[x]; + callback(selx); + } + } + else + { + callback(sel); + } + }); + + //Type retriever + $_.type = function(obj) + { + if((function() {return obj && (obj !== this)}).call(obj)) + { + //fallback on 'typeof' for truthy primitive values + return (typeof obj).toLowerCase(); + } + + return ({}).toString.call(obj).match(/\s([a-z|A-Z]+)/)[1].toLowerCase(); + } + + //Set global variables + $_ = window.$_ = window.$_ || $_; + $_.$ = $; + + //console.log polyfill + if(typeof window.console === "undefined") + { + window.console = { + log:function(){} + }; + } + + /** + * String trim function polyfill + */ + if(typeof String.prototype.trim === "undefined") + { + String.prototype.trim = function(){ + return this.replace(/^\s+|\s+$/g, ""); + }; + } + +}()); \ No newline at end of file diff --git a/src/event.js b/src/event.js new file mode 100644 index 0000000..4cc7f11 --- /dev/null +++ b/src/event.js @@ -0,0 +1,177 @@ +/** + * Event object + * + * Event api wrapper + */ +(function (){ + + // Property name for expandos on DOM objects + var kis_expando = "KIS_0_3_0"; + + var attach, remove, add_remove, e, attach_delegate, attach_live; + + // Define the proper attach and remove functions + // based on browser support + if(typeof document.addEventListener !== "undefined") + { + attach = function (sel, event, callback) + { + if (typeof sel.addEventListener !== "undefined") + { + sel.addEventListener(event, callback, false); + } + }; + remove = function (sel, event, callback) + { + if (typeof sel.removeEventListener !== "undefined") + { + sel.removeEventListener(event, callback, false); + } + }; + } + //typeof function doesn't work in IE where attachEvent is available: brute force it + else if(typeof document.attachEvent !== "undefined") + { + attach = function (sel, event, callback) + { + function listener () { + // Internet Explorer fails to correctly set the 'this' object + // for event listeners, so we need to set it ourselves. + callback.apply(arguments); + } + + if (typeof sel.attachEvent !== "undefined") + { + remove(event, callback); // Make sure we don't have duplicate listeners + + sel.attachEvent("on" + event, listener); + // Store our listener so we can remove it later + var expando = sel[kis_expando] = sel[kis_expando] || {}; + expando.listeners = expando.listeners || {}; + expando.listeners[event] = expando.listeners[event] || []; + expando.listeners[event].push({ + callback: callback, + listener: listener + }); + } + else + { + console.log("Failed to attach event:"+event+" on "+sel); + } + }; + remove = function (sel, event, callback) + { + if(typeof sel.detachEvent !== "undefined") + { + var expando = sel[kis_expando]; + if (expando && expando.listeners + && expando.listeners[event]) + { + var listeners = expando.listeners[event]; + var len = listeners.length; + for (var i=0; i bFloat ? 1 : aFloat < bFloat ? -1 : 0; + } + else if (aNumeric && !bNumeric) + { + return 1; + } + else if (!aNumeric && bNumeric) + { + return -1; + } + + return a > b ? 1 : a < b ? -1 : 0; + }); + + //cache object/array size + num_keys = keys.length; + + //Recreate the object/array + for(i=0; i < num_keys; i++) + { + k = keys[i]; + new_o[k] = o[k]; + } + + return new_o; + }, + str_trans: function(string, from, to) + { + + } + }; + + //Add it to the $_ object + $_.ext('util', u); +}()); \ No newline at end of file diff --git a/tests/tests.js b/tests/tests.js index afb6fd7..db9bd8e 100644 --- a/tests/tests.js +++ b/tests/tests.js @@ -214,45 +214,6 @@ }); - test("Array combine", function(){ - - expect(3); - - var keys_5 = ["a", "u", "i", "e", "o"]; - var keys_obj = { - "x": 2, - "a": 4, - "q": 3, - "r": 1, - "p": "q" - }; - - var vals_5 = [1, 5, 3, 2, 4]; - var vals_4 = [3, 6, 2, 7]; - - var obj_combined = { - 2:1, - 4:5, - 3:3, - 1:2, - "q":4 - }; - - var combined = { - "a":1, - "u":5, - "i":3, - "e":2, - "o":4 - }; - - - equal($_.util.array_combine(keys_5, vals_4), false, "Can't combine arrays of different sizes"); - deepEqual($_.util.array_combine(keys_obj, vals_5), obj_combined, "Combine with keys as object"); - deepEqual($_.util.array_combine(keys_5, vals_5), combined, "Properly combines arrays"); - - }); - test("Reverse Key Sort", function(){ expect(2); @@ -276,41 +237,6 @@ deepEqual($_.util.reverse_key_sort(test_o), test_sorted, "Object sort"); deepEqual($_.util.object_values($_.util.reverse_key_sort(test_array)), test_array_sorted, "Array Sort"); }); - - test("Object Merge", function(){ - expect(2); - - var arr1 = { - "color": "red", - 0: 2, - 1: 4 - }, - arr2 = { - 0: "a", - 1: "b", - "color": "green", - "shape": "trapezoid", - 2: 4 - }, - res1 = { - "color": "green", - 0: 2, - 1: 4, - 2: "a", - 3: "b", - "shape": "trapezoid", - 4: 4 - }, - arr3 = [], - arr4 = { - 1:'value', - }, - res2 = {0:'value'}; - - deepEqual($_.util.object_merge(arr1, arr2), res1, "Merge objects with numeric and test keys"); - deepEqual($_.util.object_merge(arr3, arr4), res2, "Merged object has reordered keys"); - - });