From 1237ea511e6591b9ba488f6c5fa13284b99e27e2 Mon Sep 17 00:00:00 2001 From: Timothy Warren Date: Mon, 24 Oct 2011 12:24:10 -0400 Subject: [PATCH] Added object_merge function and tests --- .gitignore | 1 + combine.php | 31 +- kis-all.js | 1801 +++++++++++++++++++++++--------------------- kis-min.js | 17 +- src/DOM.js | 379 ---------- src/QS.js | 91 --- src/ajax.js | 78 -- src/core.js | 184 ----- src/event.js | 177 ----- src/module_vars.js | 2 - src/store.js | 44 -- src/util.js | 97 --- tests/tests.js | 74 ++ 13 files changed, 1040 insertions(+), 1936 deletions(-) delete mode 100644 src/DOM.js delete mode 100644 src/QS.js delete mode 100644 src/ajax.js delete mode 100644 src/core.js delete mode 100644 src/event.js delete mode 100644 src/module_vars.js delete mode 100644 src/store.js delete mode 100644 src/util.js diff --git a/.gitignore b/.gitignore index e1e512b..e5065e8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ 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 0391cd8..575402a 100755 --- a/combine.php +++ b/combine.php @@ -8,11 +8,13 @@ //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($folder)) +if($dir = opendir($src_folder)) { while(($file = readdir($dir)) !== FALSE) { @@ -26,37 +28,20 @@ if($dir = opendir($folder)) closedir($dir); } -//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"; +$new_file = file_get_contents($core_folder."/core.js") . "\n"; -//Add the opening of the function for the modules -$new_file .= "\n// --------------------------------------------------------------------------\n\n"; //Add the modules -foreach($src_files as $f) +foreach($files as $f) { - $farray = file($folder."/".$f, FILE_IGNORE_NEW_LINES); + $farray = file($src_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\t// --------------------------------------------------------------------------\n\n".$module."\n"; + $new_file .= "\n// --------------------------------------------------------------------------\n\n".$module."\n"; } @@ -71,7 +56,7 @@ curl_setopt($ch, CURLOPT_POSTFIELDS, 'output_info=compiled_code&output_format=te $output = curl_exec($ch); curl_close($ch); -file_put_contents("kis-min.js", $output); +file_put_contents("kis-custom-min.js", $output); //Display the output on-screen too diff --git a/kis-all.js b/kis-all.js index 0ca172a..4129637 100644 --- a/kis-all.js +++ b/kis-all.js @@ -185,892 +185,987 @@ // -------------------------------------------------------------------------- +/* + * 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. + */ - // -------------------------------------------------------------------------- - - /* - * 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 () +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++) { - return this.replace(/^\s+|\s+$/g, ""); - }, - arrIndexOf = Array[protoProp].indexOf || - function (item) + 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 === "") { - var + 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 = this.length; - for (; i < len; i++) - { - if (i in this && this[i] === item) - { - return i; - } - } - return -1; + len = classes.length; + for (; i < len; i++) + { + this.push(classes[i]); } - // Vendors: please allow content code to instantiate DOMExceptions - , - DOMEx = function (type, message) + this._updateClassName = function () { - 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); + elem.className = this.toString(); }; - // 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) + }, + classListProto = ClassList[protoProp] = [], + classListGetter = function () { - return this[i] || null; + return new ClassList(this); }; - 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) + // 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) { - 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 this[i] || null; + }; + classListProto.contains = function (token) { - return s.replace(/(\-[a-z])/g, function($1){ - return $1.toUpperCase().replace('-',''); - }); - } - - function _css(sel, prop, val) + token += ""; + return checkTokenAndGetIndex(this, token) !== -1; + }; + classListProto.add = function (token) { - 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") + token += ""; + if (checkTokenAndGetIndex(this, token) === -1) { - 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"; - } - - 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; - - 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); - }); + this.push(token); + this._updateClassName(); } }; - - $_.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") + classListProto.remove = function (token) { - attach = function (sel, event, callback) + token += ""; + var index = checkTokenAndGetIndex(this, token); + if (index !== -1) { - 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 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); + +}()); + +// -------------------------------------------------------------------------- + +/** + * 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 -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)) + { + 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") + { + 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++) + { + new_obj[x++] = arg[j]; + } + } + 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") + { + 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(b,a){if(typeof a==="undefined")return f(this.el,b);$_.each(function(d){f(d,b,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)})}})})(); (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;bc?1:ba?1:de?1:ca?1:b 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 deleted file mode 100644 index 8b9dce1..0000000 --- a/src/QS.js +++ /dev/null @@ -1,91 +0,0 @@ -/** - * 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 deleted file mode 100644 index 050f649..0000000 --- a/src/ajax.js +++ /dev/null @@ -1,78 +0,0 @@ -/** - * 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 deleted file mode 100644 index be53372..0000000 --- a/src/core.js +++ /dev/null @@ -1,184 +0,0 @@ -/** - 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 deleted file mode 100644 index 4cc7f11..0000000 --- a/src/event.js +++ /dev/null @@ -1,177 +0,0 @@ -/** - * 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 db9bd8e..afb6fd7 100644 --- a/tests/tests.js +++ b/tests/tests.js @@ -214,6 +214,45 @@ }); + 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); @@ -237,6 +276,41 @@ 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"); + + });