Miscellaneous updates

This commit is contained in:
Timothy Warren 2011-10-18 11:08:51 -04:00
parent 5529d98054
commit 038a579554
6 changed files with 1324 additions and 209 deletions

View File

@ -25,21 +25,29 @@ Browser support: IE8+, Latest versions of Firefox, Chrome, Safari, Opera
**functions:** **functions:**
* each: For applying changes to every item matched by a selector * each: For applying changes to every item matched by a selector
Use:
$_(selector).dom.each(callback); $_(selector).dom.each(callback);
Example : $_(".foo").dom.each(function(e){ Example :
$_(".foo").dom.each(function(e){
$_(e).dom.text(value); $_(e).dom.text(value);
}): }):
* ext: For extending the library, adds this.el to the object or function supplied * ext: For extending the library, adds this.el to the object or function supplied
Use: $_.ext("name", functionOrObject);
Example: $_.ext("zip", function(){ //function });
$_.ext("name", functionOrObject);
Example:
$_.ext("zip", function(){ //function });
Adds 'zip' function to $_. Adds 'zip' function to $_.
* type: For getting the type of a variable * type: For getting the type of a variable
Use: $_.type(var);
$_.type(var);
### Ajax: simple, jQuery-like ajax functions ### ### Ajax: simple, jQuery-like ajax functions ###
@ -47,11 +55,11 @@ Browser support: IE8+, Latest versions of Firefox, Chrome, Safari, Opera
functions: functions:
* Get: * Get:
Use:
$_.get(url, data_object, callback); $_.get(url, data_object, callback);
* Post: * Post:
Use:
$_.post(url, data_object, callback); $_.post(url, data_object, callback);
### QS: querystring parsing and serialization for hashbang strings, and pushState urls ### ### QS: querystring parsing and serialization for hashbang strings, and pushState urls ###
@ -59,15 +67,15 @@ functions:
**functions:** **functions:**
* Parse: * Parse:
Use:
$_.qs.parse(hb); $_.qs.parse(hb);
* Set: This function will set the hash url if browser doesn't have history.pushState * Set: This function will set the hash url if browser doesn't have history.pushState
Use:
$_.qs.set(key, value); $_.qs.set(key, value);
* Get: Retrieves the value of the key in the url string * Get: Retrieves the value of the key in the url string
Use:
$_.qs.get(key); $_.qs.get(key);
### Store: localstorage wrapper with automatic data serialization ### ### Store: localstorage wrapper with automatic data serialization ###
@ -75,15 +83,19 @@ functions:
**functions:** **functions:**
* Get: * Get:
Use:
$_.store.get(key); $_.store.get(key);
* Set * Set
Use:
$_.store.set(key, value); $_.store.set(key, value);
* Remove
$_.store.remove(key);
* getALL: Retreives all localstorage data in raw form * getALL: Retreives all localstorage data in raw form
Use:
$_.store.getAll(); $_.store.getAll();
@ -92,11 +104,11 @@ functions:
**functions:** **functions:**
* Add: * Add:
Use:
$_(selector).event.add(event, callback); $_(selector).event.add(event, callback);
* Remove * Remove
Use:
$_(selector).event.remove(event, callback); $_(selector).event.remove(event, callback);
### DOM: Dom manipulation module ### ### DOM: Dom manipulation module ###
@ -104,34 +116,34 @@ functions:
**functions:** **functions:**
* addClass: * addClass:
Use:
$_(selector).dom.addClass(className); $_(selector).dom.addClass(className);
* RemoveClass: * RemoveClass:
Use:
$_(selector).dom.removeClass(className); $_(selector).dom.removeClass(className);
* show: For setting dom elements as visible. Type defaults as "block", can be set with optional second parameter. * show: For setting dom elements as visible. Type defaults as "block", can be set with optional second parameter.
Use:
$_(selector).dom.show([type]); $_(selector).dom.show([type]);
* hide: Hides the elements matching the selector * hide: Hides the elements matching the selector
Use:
$_(selector).dom.hide(); $_(selector).dom.hide();
* attr: Gets, sets, or removes an attribute from a selector. * attr: Gets, sets, or removes an attribute from a selector.
Use:
Set: $_(selector).dom.attr(attributeName, attributeValue); Set: $_(selector).dom.attr(attributeName, attributeValue);
Get: $_(selector).dom.attr(attributeName); Get: $_(selector).dom.attr(attributeName);
Remove: $_(selector).dom.attr(attributeName, null); Remove: $_(selector).dom.attr(attributeName, null);
* text: Gets or sets the text in between an element's tags * text: Gets or sets the text in between an element's tags
Use:
Set: $_(selector).dom.text(text); Set: $_(selector).dom.text(text);
Get: $_(selector).dom.text(); Get: $_(selector).dom.text();
* css: Sets css styles on the selected element(s) * css: Sets css styles on the selected element(s)
Use:
Set: $_(selector).dom.css(property, value); Set: $_(selector).dom.css(property, value);
Get: $_(selector).dom.css(property); Get: $_(selector).dom.css(property);

1036
kis-custom.js Normal file

File diff suppressed because it is too large Load Diff

24
kis-min.js vendored
View File

@ -3,15 +3,15 @@ a.el=f;return a};g=function(a){var c;if(typeof a!=="undefined"){if(typeof Object
{}.toString.call(a).match(/\s([a-z|A-Z]+)/)[1].toLowerCase()};e=window.$_=window.$_||e;e.$=c;if(typeof window.console==="undefined")window.console={log:function(){}};if(typeof String.prototype.trim==="undefined")String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")}}})(); {}.toString.call(a).match(/\s([a-z|A-Z]+)/)[1].toLowerCase()};e=window.$_=window.$_||e;e.$=c;if(typeof window.console==="undefined")window.console={log:function(){}};if(typeof String.prototype.trim==="undefined")String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")}}})();
(function(){var e=e||window.$_;typeof document!=="undefined"&&!("classList"in document.createElement("a"))&&function(c){var c=(c.HTMLElement||c.Element).prototype,g=Object,f=String.prototype.trim||function(){return this.replace(/^\s+|\s+$/g,"")},a=Array.prototype.indexOf||function(d){for(var b=0,a=this.length;b<a;b++)if(b in this&&this[b]===d)return b;return-1},e=function(d,b){this.name=d;this.code=DOMException[d];this.message=b},d=function(d,b){if(b==="")throw new e("SYNTAX_ERR","An invalid or illegal string was specified"); (function(){var e=e||window.$_;typeof document!=="undefined"&&!("classList"in document.createElement("a"))&&function(c){var c=(c.HTMLElement||c.Element).prototype,g=Object,f=String.prototype.trim||function(){return this.replace(/^\s+|\s+$/g,"")},a=Array.prototype.indexOf||function(d){for(var b=0,a=this.length;b<a;b++)if(b in this&&this[b]===d)return b;return-1},e=function(d,b){this.name=d;this.code=DOMException[d];this.message=b},d=function(d,b){if(b==="")throw new e("SYNTAX_ERR","An invalid or illegal string was specified");
if(/\s/.test(b))throw new e("INVALID_CHARACTER_ERR","String contains an invalid character");return a.call(d,b)},b=function(d){for(var b=f.call(d.className),b=b?b.split(/\s+/):[],a=0,i=b.length;a<i;a++)this.push(b[a]);this._updateClassName=function(){d.className=this.toString()}},i=b.prototype=[],l=function(){return new b(this)};e.prototype=Error.prototype;i.item=function(d){return this[d]||null};i.contains=function(b){b+="";return d(this,b)!==-1};i.add=function(b){b+="";d(this,b)===-1&&(this.push(b), if(/\s/.test(b))throw new e("INVALID_CHARACTER_ERR","String contains an invalid character");return a.call(d,b)},b=function(d){for(var b=f.call(d.className),b=b?b.split(/\s+/):[],a=0,i=b.length;a<i;a++)this.push(b[a]);this._updateClassName=function(){d.className=this.toString()}},i=b.prototype=[],l=function(){return new b(this)};e.prototype=Error.prototype;i.item=function(d){return this[d]||null};i.contains=function(b){b+="";return d(this,b)!==-1};i.add=function(b){b+="";d(this,b)===-1&&(this.push(b),
this._updateClassName())};i.remove=function(b){b+="";b=d(this,b);b!==-1&&(this.splice(b,1),this._updateClassName())};i.toggle=function(b){b+="";d(this,b)===-1?this.add(b):this.remove(b)};i.toString=function(){return this.join(" ")};if(g.defineProperty){i={get:l,enumerable:!0,configurable:!0};try{g.defineProperty(c,"classList",i)}catch(j){if(j.number===-2146823252)i.enumerable=!1,g.defineProperty(c,"classList",i)}}else g.prototype.__defineGetter__&&c.__defineGetter__("classList",l)}(self);(function(){function c(d, this._updateClassName())};i.remove=function(b){b+="";b=d(this,b);b!==-1&&(this.splice(b,1),this._updateClassName())};i.toggle=function(b){b+="";d(this,b)===-1?this.add(b):this.remove(b)};i.toString=function(){return this.join(" ")};if(g.defineProperty){i={get:l,enumerable:true,configurable:true};try{g.defineProperty(c,"classList",i)}catch(j){if(j.number===-2146823252)i.enumerable=false,g.defineProperty(c,"classList",i)}}else g.prototype.__defineGetter__&&c.__defineGetter__("classList",l)}(self);(function(){function c(d,
b,a){var c,f;if(typeof d.hasAttribute!=="undefined")d.hasAttribute(b)&&(c=d.getAttribute(b)),f=!0;else if(typeof d[b]!=="undefined")c=d[b],f=!1;else if(b==="class"&&typeof d.className!=="undefined")b="className",c=d.className,f=!1;if(typeof c==="undefined"&&(typeof a==="undefined"||a===null))console.log(a),console.log(d),console.log("Element does not have the selected attribute");else{if(typeof a==="undefined")return c;typeof a!=="undefined"&&a!==null?f===!0?d.setAttribute(b,a):d[b]=a:a===null&&(f=== b,a){var c,f;if(typeof d.hasAttribute!=="undefined")d.hasAttribute(b)&&(c=d.getAttribute(b)),f=true;else if(typeof d[b]!=="undefined")c=d[b],f=false;else if(b==="class"&&typeof d.className!=="undefined")b="className",c=d.className,f=false;if(typeof c==="undefined"&&(typeof a==="undefined"||a===null))console.log(a),console.log(d),console.log("Element does not have the selected attribute");else{if(typeof a==="undefined")return c;typeof a!=="undefined"&&a!==null?f===true?d.setAttribute(b,a):d[b]=a:a===
!0?d.removeAttribute(b):delete d[b]);return typeof a!=="undefined"?a:c}}function g(d){return d.replace(/(\-[a-z])/g,function(b){return b.toUpperCase().replace("-","")})}function f(d,b,a){var c,b=g(b);c={outerHeight:"offsetHeight",outerWidth:"offsetWidth",top:"posTop"};if(typeof a==="undefined"&&d.style[b]!=="undefined")return d.style[b];else if(typeof a==="undefined"&&d.style[c[b]]!=="undefined")return d.style[c[b]];typeof d.style[b]!=="undefined"?d.style[b]=a:d.style[c[b]]?d.style[c[b]]=a:console.log("Property "+ null&&(f===true?d.removeAttribute(b):delete d[b]);return typeof a!=="undefined"?a:c}}function g(d){return d.replace(/(\-[a-z])/g,function(b){return b.toUpperCase().replace("-","")})}function f(d,b,a){var c,b=g(b);c={outerHeight:"offsetHeight",outerWidth:"offsetWidth",top:"posTop"};if(typeof a==="undefined"&&d.style[b]!=="undefined")return d.style[b];else if(typeof a==="undefined"&&d.style[c[b]]!=="undefined")return d.style[c[b]];typeof d.style[b]!=="undefined"?d.style[b]=a:d.style[c[b]]?d.style[c[b]]=
b+" nor an equivalent seems to exist")}var a,h;a=/^([\w\-]+)$/;h=/\.([\w\-]+)$/;e.ext("dom",{addClass:function(d){e.each(function(b){b.classList.add(d)})},removeClass:function(d){e.each(function(b){b.classList.remove(d)})},hide:function(){this.css("display","none")},show:function(d){typeof d==="undefined"&&(d="block");this.css("display",d)},attr:function(d,b){var a=this.el;if(a.length>1&&typeof b==="undefined")console.log(a),console.log("Must be a singular element");else if(a.length>1&&typeof b!== a:console.log("Property "+b+" nor an equivalent seems to exist")}var a,h;a=/^([\w\-]+)$/;h=/\.([\w\-]+)$/;e.ext("dom",{addClass:function(d){e.each(function(b){b.classList.add(d)})},removeClass:function(d){e.each(function(b){b.classList.remove(d)})},hide:function(){this.css("display","none")},show:function(d){typeof d==="undefined"&&(d="block");this.css("display",d)},attr:function(d,b){var a=this.el;if(a.length>1&&typeof b==="undefined")console.log(a),console.log("Must be a singular element");else if(a.length>
"undefined")e.each(function(a){return c(a,d,b)});else return c(a,d,b)},text:function(d){var b,a,c;c=this.el;a=typeof c.innerText!=="undefined"?"innerText":typeof c.textContent!=="undefined"?"textContent":"innerHTML";b=c[a];return typeof d!=="undefined"?c[a]=d:b},css:function(d,b){if(typeof b==="undefined")return f(this.el,d);e.each(function(a){f(a,d,b)})},children:function(d){if(typeof d==="undefined")return e(this.el.children);var b=typeof this.el.children!=="undefined"?this.el.children:this.el; 1&&typeof b!=="undefined")e.each(function(a){return c(a,d,b)});else return c(a,d,b)},text:function(d){var b,a,c;c=this.el;a=typeof c.innerText!=="undefined"?"innerText":typeof c.textContent!=="undefined"?"textContent":"innerHTML";b=c[a];return typeof d!=="undefined"?c[a]=d:b},css:function(d,b){if(typeof b==="undefined")return f(this.el,d);e.each(function(a){f(a,d,b)})},children:function(d){if(typeof d==="undefined")return e(this.el.children);var b=typeof this.el.children!=="undefined"?this.el.children:
if(e.type(d)!=="string")return e(d);else if(d.match(/#([\w\-]+$)/))return e(e.$(d));else{var c,f=b.length,g=[];if(d.match(a))for(c=0;c<f;c++)b[c].tagName.toLowerCase()==d.toLowerCase()&&g.push(b[c]);else if(d.match(h)){d=d.replace(".","");for(c=0;c<f;c++)b[c].classList.contains(d)&&g.push(b[c])}else console.log(d+" is not a valid filter");return e(g.length==1?g[0]:g)}}})})();(function(){e.ext("store",{get:function(c){return JSON.parse(localStorage.getItem(c))},set:function(c,g){typeof g!=="string"&& this.el;if(e.type(d)!=="string")return e(d);else if(d.match(/#([\w\-]+$)/))return e(e.$(d));else{var c,f=b.length,g=[];if(d.match(a))for(c=0;c<f;c++)b[c].tagName.toLowerCase()==d.toLowerCase()&&g.push(b[c]);else if(d.match(h)){d=d.replace(".","");for(c=0;c<f;c++)b[c].classList.contains(d)&&g.push(b[c])}else console.log(d+" is not a valid filter");return e(g.length==1?g[0]:g)}}})})();(function(){e.ext("store",{get:function(c){return JSON.parse(localStorage.getItem(c))},set:function(c,g){typeof g!==
(g=JSON.stringify(g));localStorage.setItem(c,g)},getAll:function(){var c,g,f;g=localStorage.length;f={};for(c=0;c<g;c++){var a=localStorage.key(c),e=localStorage.getItem(a);f[a]=e}return f}})})();(function(){e.hb=history.pushState?!1:!0;e.ext("qs",{parse:function(c){var c=c||e.hb,g,f,a,h;a={};if(c===!0)c=location.hash.split("#!/"),c=c.length>1?c[1]:"";else if(c===!1||c===void 0)c=window.location.search.substring(1);else return!1;g=c.split("&");f=g.length;for(c=0;c<f;c++){h=g[c].split("=");if(h.length< "string"&&(g=JSON.stringify(g));localStorage.setItem(c,g)},getAll:function(){var c,g,f;g=localStorage.length;f={};for(c=0;c<g;c++){var a=localStorage.key(c),e=localStorage.getItem(a);f[a]=e}return f}})})();(function(){e.hb=history.pushState?false:true;e.ext("qs",{parse:function(c){var c=c||e.hb,g,f,a,h;a={};if(c===true)c=location.hash.split("#!/"),c=c.length>1?c[1]:"";else if(c===false||c===void 0)c=window.location.search.substring(1);else return false;g=c.split("&");f=g.length;for(c=0;c<f;c++){h=
2)break;a[h[0]]=h[1]}return a},set:function(c,g,f){var f=f||e.hb,a=this.parse(f);c!==void 0&&g!==void 0&&(a[c]=g);var c=[],h;for(h in a)a.hasOwnProperty(h)&&c.push(h+"="+a[h]);a=c.join("&");if(f===!0)a="!/"+a,location.hash=a;return a},get:function(c,g){var g=g||e.hb,f=this.parse(g);return f[c]?f[c]:""}})})();(function(){var c={_do:function(c,f,a,e){typeof a==="undefined"&&(a=function(){});var d=typeof window.XMLHttpRequest!=="undefined"?new XMLHttpRequest:!1,e=e?"POST":"GET";c+=e==="GET"?"?"+this._serialize(f): g[c].split("=");if(h.length<2)break;a[h[0]]=h[1]}return a},set:function(c,g,f){var f=f||e.hb,a=this.parse(f);c!==void 0&&g!==void 0&&(a[c]=g);var c=[],h;for(h in a)a.hasOwnProperty(h)&&c.push(h+"="+a[h]);a=c.join("&");if(f===true)a="!/"+a,location.hash=a;return a},get:function(c,g){var g=g||e.hb,f=this.parse(g);return f[c]?f[c]:""}})})();(function(){var c={_do:function(c,f,a,e){typeof a==="undefined"&&(a=function(){});var d=typeof window.XMLHttpRequest!=="undefined"?new XMLHttpRequest:false,e=e?"POST":
"";d.open(e,c);d.onreadystatechange=function(){d.readyState===4&&a(d.responseText)};e==="POST"?(d.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),d.send(this._serialize(f))):d.send(null)},_serialize:function(c){var f=[],a;for(a in c)if(c.hasOwnProperty(a)&&typeof c[a]!=="function"){var e=c[a].toString();a=encodeURIComponent(a);e=encodeURIComponent(e);f.push(a+"="+e)}return f.join("&")}};e.ext("get",function(e,f,a){c._do(e,f,a,!1)});e.ext("post",function(e,f,a){c._do(e,f,a,!0)})})(); "GET";c+=e==="GET"?"?"+this._serialize(f):"";d.open(e,c);d.onreadystatechange=function(){d.readyState===4&&a(d.responseText)};e==="POST"?(d.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),d.send(this._serialize(f))):d.send(null)},_serialize:function(c){var f=[],a;for(a in c)if(c.hasOwnProperty(a)&&typeof c[a]!=="function"){var e=c[a].toString();a=encodeURIComponent(a);e=encodeURIComponent(e);f.push(a+"="+e)}return f.join("&")}};e.ext("get",function(e,f,a){c._do(e,f,a,false)});
(function(){var c,g,f,a,h;typeof document.addEventListener!=="undefined"?(c=function(d,b,a){typeof d.addEventListener!=="undefined"&&d.addEventListener(b,a,!1)},g=function(d,b,a){typeof d.removeEventListener!=="undefined"&&d.removeEventListener(b,a,!1)}):typeof document.attachEvent!=="undefined"&&(c=function(d,b,a){var i;function c(){a.apply(arguments)}typeof d.attachEvent!=="undefined"?(g(b,a),d.attachEvent("on"+b,c),i=d.KIS_0_3_0=d.KIS_0_3_0||{},d=i,d.listeners=d.listeners||{},d.listeners[b]=d.listeners[b]|| e.ext("post",function(e,f,a){c._do(e,f,a,true)})})();(function(){var c,g,f,a,h;typeof document.addEventListener!=="undefined"?(c=function(d,b,a){typeof d.addEventListener!=="undefined"&&d.addEventListener(b,a,false)},g=function(d,b,a){typeof d.removeEventListener!=="undefined"&&d.removeEventListener(b,a,false)}):typeof document.attachEvent!=="undefined"&&(c=function(d,b,a){var i;function c(){a.apply(arguments)}typeof d.attachEvent!=="undefined"?(g(b,a),d.attachEvent("on"+b,c),i=d.KIS_0_3_0=d.KIS_0_3_0||
[],d.listeners[b].push({callback:a,listener:c})):console.log("Failed to attach event:"+b+" on "+d)},g=function(a,b,c){if(typeof a.detachEvent!=="undefined"){var e=a.KIS_0_3_0;if(e&&e.listeners&&e.listeners[b])for(var f=e.listeners[b],g=f.length,h=0;h<g;h++)if(f[h].callback===c){a.detachEvent("on"+b,f[h].listener);f.splice(h,1);f.length===0&&delete e.listeners[b];break}}});f=function(a,b,e,h){var j,k;if(typeof a==="undefined")return console.log(arguments),console.log(b),!1;if(b.match(/^([\w\-]+)$/))h=== {},d=i,d.listeners=d.listeners||{},d.listeners[b]=d.listeners[b]||[],d.listeners[b].push({callback:a,listener:c})):console.log("Failed to attach event:"+b+" on "+d)},g=function(a,b,c){if(typeof a.detachEvent!=="undefined"){var e=a.KIS_0_3_0;if(e&&e.listeners&&e.listeners[b])for(var f=e.listeners[b],g=f.length,h=0;h<g;h++)if(f[h].callback===c){a.detachEvent("on"+b,f[h].listener);f.splice(h,1);f.length===0&&delete e.listeners[b];break}}});f=function(a,b,e,h){var j,k;if(typeof a==="undefined")return console.log(arguments),
!0?c(a,b,e):g(a,b,e);else{b=b.split(" ");k=b.length;for(j=0;j<k;j++)f(a,b[j],e,h)}};a=function(a,b,c){f(a,c,function(){a=e.$(a)},!0)};h=function(c,b,e){a(document.documentElement,c,b,e)};e.ext("event",{add:function(a,b){e.each(function(c){f(c,a,b,!0)})},remove:function(a,b){e.each(function(c){f(c,a,b,!1)})},live:function(a,b){e.each(function(c){h(c,a,b)})},delegate:function(c,b,f){e.each(function(e){a(e,c,b,f)})}})})()})(); console.log(b),false;if(b.match(/^([\w\-]+)$/))h===true?c(a,b,e):g(a,b,e);else{b=b.split(" ");k=b.length;for(j=0;j<k;j++)f(a,b[j],e,h)}};a=function(a,b,c){f(a,c,function(){a=e.$(a)},true)};h=function(c,b,e){a(document.documentElement,c,b,e)};e.ext("event",{add:function(a,b){e.each(function(c){f(c,a,b,true)})},remove:function(a,b){e.each(function(c){f(c,a,b,false)})},live:function(a,b){e.each(function(c){h(c,a,b)})},delegate:function(c,b,f){e.each(function(e){a(e,c,b,f)})}})})()})();

View File

@ -17,6 +17,10 @@
} }
localStorage.setItem(key, value); localStorage.setItem(key, value);
}, },
remove: function (key)
{
localStorage.removeItem(key);
},
getAll: function () getAll: function ()
{ {
var i, var i,

View File

@ -186,6 +186,7 @@
color: #710909; color: #710909;
background-color: #fff; background-color: #fff;
border-left: 26px solid #EE5757; border-left: 26px solid #EE5757;
white-space: pre;
} }
#qunit-tests > li:last-child { #qunit-tests > li:last-child {

View File

@ -15,10 +15,10 @@ var defined = {
sessionStorage: (function() { sessionStorage: (function() {
try { try {
return !!sessionStorage.getItem; return !!sessionStorage.getItem;
} catch(e){ } catch(e) {
return false; return false;
} }
})() })()
}; };
var testId = 0; var testId = 0;
@ -132,7 +132,7 @@ Test.prototype = {
config.moduleStats.all += this.assertions.length; config.moduleStats.all += this.assertions.length;
if ( tests ) { if ( tests ) {
var ol = document.createElement("ol"); var ol = document.createElement("ol");
for ( var i = 0; i < this.assertions.length; i++ ) { for ( var i = 0; i < this.assertions.length; i++ ) {
var assertion = this.assertions[i]; var assertion = this.assertions[i];
@ -275,7 +275,7 @@ var QUnit = {
} }
// is 2nd argument a testEnvironment? // is 2nd argument a testEnvironment?
if ( expected && typeof expected === 'object') { if ( expected && typeof expected === 'object') {
testEnvironmentArg = expected; testEnvironmentArg = expected;
expected = null; expected = null;
} }
@ -400,6 +400,9 @@ var QUnit = {
// A slight delay, to avoid any current callbacks // A slight delay, to avoid any current callbacks
if ( defined.setTimeout ) { if ( defined.setTimeout ) {
window.setTimeout(function() { window.setTimeout(function() {
if (config.semaphore > 0) {
return;
}
if ( config.timeout ) { if ( config.timeout ) {
clearTimeout(config.timeout); clearTimeout(config.timeout);
} }
@ -439,12 +442,18 @@ var config = {
// block until document ready // block until document ready
blocking: true, blocking: true,
// when enabled, show only failing tests
// gets persisted through sessionStorage and can be changed in UI via checkbox
hidepassed: false,
// by default, run previously failed tests first // by default, run previously failed tests first
// very useful in combination with "Hide passed tests" checked // very useful in combination with "Hide passed tests" checked
reorder: true, reorder: true,
noglobals: false, // by default, modify document.title when suite is done
notrycatch: false altertitle: true,
urlConfig: ['noglobals', 'notrycatch']
}; };
// Load paramaters // Load paramaters
@ -462,9 +471,6 @@ var config = {
// allow just a key to turn on a flag, e.g., test.html?noglobals // allow just a key to turn on a flag, e.g., test.html?noglobals
current[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true; current[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true;
urlParams[ current[ 0 ] ] = current[ 1 ]; urlParams[ current[ 0 ] ] = current[ 1 ];
if ( current[ 0 ] in config ) {
config[ current[ 0 ] ] = current[ 1 ];
}
} }
} }
@ -649,6 +655,10 @@ extend(QUnit, {
return window.location.pathname + querystring.slice( 0, -1 ); return window.location.pathname + querystring.slice( 0, -1 );
}, },
extend: extend,
id: id,
addEvent: addEvent,
// Logging callbacks; all receive a single argument with the listed properties // Logging callbacks; all receive a single argument with the listed properties
// run test/logs.html for any related changes // run test/logs.html for any related changes
begin: function() {}, begin: function() {},
@ -670,7 +680,7 @@ if ( typeof document === "undefined" || document.readyState === "complete" ) {
config.autorun = true; config.autorun = true;
} }
addEvent(window, "load", function() { QUnit.load = function() {
QUnit.begin({}); QUnit.begin({});
// Initialize the config, saving the execution queue // Initialize the config, saving the execution queue
@ -680,15 +690,19 @@ addEvent(window, "load", function() {
config.blocking = false; config.blocking = false;
var urlConfigHtml = '', len = config.urlConfig.length;
for ( var i = 0, val; i < len, val = config.urlConfig[i]; i++ ) {
config[val] = QUnit.urlParams[val];
urlConfigHtml += '<label><input name="' + val + '" type="checkbox"' + ( config[val] ? ' checked="checked"' : '' ) + '>' + val + '</label>';
}
var userAgent = id("qunit-userAgent"); var userAgent = id("qunit-userAgent");
if ( userAgent ) { if ( userAgent ) {
userAgent.innerHTML = navigator.userAgent; userAgent.innerHTML = navigator.userAgent;
} }
var banner = id("qunit-header"); var banner = id("qunit-header");
if ( banner ) { if ( banner ) {
banner.innerHTML = '<a href="' + QUnit.url({ filter: undefined }) + '"> ' + banner.innerHTML + '</a> ' + banner.innerHTML = '<a href="' + QUnit.url({ filter: undefined }) + '"> ' + banner.innerHTML + '</a> ' + urlConfigHtml;
'<label><input name="noglobals" type="checkbox"' + ( config.noglobals ? ' checked="checked"' : '' ) + '>noglobals</label>' +
'<label><input name="notrycatch" type="checkbox"' + ( config.notrycatch ? ' checked="checked"' : '' ) + '>notrycatch</label>';
addEvent( banner, "change", function( event ) { addEvent( banner, "change", function( event ) {
var params = {}; var params = {};
params[ event.target.name ] = event.target.checked ? true : undefined; params[ event.target.name ] = event.target.checked ? true : undefined;
@ -711,13 +725,13 @@ addEvent(window, "load", function() {
} }
if ( defined.sessionStorage ) { if ( defined.sessionStorage ) {
if (filter.checked) { if (filter.checked) {
sessionStorage.setItem("qunit-filter-passed-tests", "true"); sessionStorage.setItem("qunit-filter-passed-tests", "true");
} else { } else {
sessionStorage.removeItem("qunit-filter-passed-tests"); sessionStorage.removeItem("qunit-filter-passed-tests");
} }
} }
}); });
if ( defined.sessionStorage && sessionStorage.getItem("qunit-filter-passed-tests") ) { if ( config.hidepassed || defined.sessionStorage && sessionStorage.getItem("qunit-filter-passed-tests") ) {
filter.checked = true; filter.checked = true;
var ol = document.getElementById("qunit-tests"); var ol = document.getElementById("qunit-tests");
ol.className = ol.className + " hidepass"; ol.className = ol.className + " hidepass";
@ -738,7 +752,9 @@ addEvent(window, "load", function() {
if (config.autostart) { if (config.autostart) {
QUnit.start(); QUnit.start();
} }
}); };
addEvent(window, "load", QUnit.load);
function done() { function done() {
config.autorun = true; config.autorun = true;
@ -778,10 +794,13 @@ function done() {
id( "qunit-testresult" ).innerHTML = html; id( "qunit-testresult" ).innerHTML = html;
} }
if ( typeof document !== "undefined" && document.title ) { if ( config.altertitle && typeof document !== "undefined" && document.title ) {
// show ✖ for good, ✔ for bad suite result in title // show ✖ for good, ✔ for bad suite result in title
// use escape sequences in case file gets loaded with non-utf-8-charset // use escape sequences in case file gets loaded with non-utf-8-charset
document.title = (config.stats.bad ? "\u2716" : "\u2714") + " " + document.title; document.title = [
(config.stats.bad ? "\u2716" : "\u2714"),
document.title.replace(/^[\u2714\u2716] /i, "")
].join(" ");
} }
QUnit.done( { QUnit.done( {
@ -828,6 +847,10 @@ function sourceFromStacktrace() {
} else if (e.stack) { } else if (e.stack) {
// Firefox, Chrome // Firefox, Chrome
return e.stack.split("\n")[4]; return e.stack.split("\n")[4];
} else if (e.sourceURL) {
// Safari, PhantomJS
// TODO sourceURL points at the 'throw new Error' line above, useless
//return e.sourceURL + ":" + e.line;
} }
} }
} }
@ -868,9 +891,9 @@ function process() {
break; break;
} }
} }
if (!config.blocking && !config.queue.length) { if (!config.blocking && !config.queue.length) {
done(); done();
} }
} }
function saveGlobal() { function saveGlobal() {
@ -957,170 +980,182 @@ function id(name) {
// Author: Philippe Rathé <prathe@gmail.com> // Author: Philippe Rathé <prathe@gmail.com>
QUnit.equiv = function () { QUnit.equiv = function () {
var innerEquiv; // the real equiv function var innerEquiv; // the real equiv function
var callers = []; // stack to decide between skip/abort functions var callers = []; // stack to decide between skip/abort functions
var parents = []; // stack to avoiding loops from circular referencing var parents = []; // stack to avoiding loops from circular referencing
// Call the o related callback with the given arguments. // Call the o related callback with the given arguments.
function bindCallbacks(o, callbacks, args) { function bindCallbacks(o, callbacks, args) {
var prop = QUnit.objectType(o); var prop = QUnit.objectType(o);
if (prop) { if (prop) {
if (QUnit.objectType(callbacks[prop]) === "function") { if (QUnit.objectType(callbacks[prop]) === "function") {
return callbacks[prop].apply(callbacks, args); return callbacks[prop].apply(callbacks, args);
} else { } else {
return callbacks[prop]; // or undefined return callbacks[prop]; // or undefined
} }
} }
} }
var callbacks = function () { var callbacks = function () {
// for string, boolean, number and null // for string, boolean, number and null
function useStrictEquality(b, a) { function useStrictEquality(b, a) {
if (b instanceof a.constructor || a instanceof b.constructor) { if (b instanceof a.constructor || a instanceof b.constructor) {
// to catch short annotaion VS 'new' annotation of a declaration // to catch short annotaion VS 'new' annotation of a
// e.g. var i = 1; // declaration
// var j = new Number(1); // e.g. var i = 1;
return a == b; // var j = new Number(1);
} else { return a == b;
return a === b; } else {
} return a === b;
} }
}
return { return {
"string": useStrictEquality, "string" : useStrictEquality,
"boolean": useStrictEquality, "boolean" : useStrictEquality,
"number": useStrictEquality, "number" : useStrictEquality,
"null": useStrictEquality, "null" : useStrictEquality,
"undefined": useStrictEquality, "undefined" : useStrictEquality,
"nan": function (b) { "nan" : function(b) {
return isNaN(b); return isNaN(b);
}, },
"date": function (b, a) { "date" : function(b, a) {
return QUnit.objectType(b) === "date" && a.valueOf() === b.valueOf(); return QUnit.objectType(b) === "date"
}, && a.valueOf() === b.valueOf();
},
"regexp": function (b, a) { "regexp" : function(b, a) {
return QUnit.objectType(b) === "regexp" && return QUnit.objectType(b) === "regexp"
a.source === b.source && // the regex itself && a.source === b.source && // the regex itself
a.global === b.global && // and its modifers (gmi) ... a.global === b.global && // and its modifers
a.ignoreCase === b.ignoreCase && // (gmi) ...
a.multiline === b.multiline; a.ignoreCase === b.ignoreCase
}, && a.multiline === b.multiline;
},
// - skip when the property is a method of an instance (OOP) // - skip when the property is a method of an instance (OOP)
// - abort otherwise, // - abort otherwise,
// initial === would have catch identical references anyway // initial === would have catch identical references anyway
"function": function () { "function" : function() {
var caller = callers[callers.length - 1]; var caller = callers[callers.length - 1];
return caller !== Object && return caller !== Object && typeof caller !== "undefined";
typeof caller !== "undefined"; },
},
"array": function (b, a) { "array" : function(b, a) {
var i, j, loop; var i, j, loop;
var len; var len;
// b could be an object literal here // b could be an object literal here
if ( ! (QUnit.objectType(b) === "array")) { if (!(QUnit.objectType(b) === "array")) {
return false; return false;
} }
len = a.length; len = a.length;
if (len !== b.length) { // safe and faster if (len !== b.length) { // safe and faster
return false; return false;
} }
//track reference to avoid circular references // track reference to avoid circular references
parents.push(a); parents.push(a);
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
loop = false; loop = false;
for(j=0;j<parents.length;j++){ for (j = 0; j < parents.length; j++) {
if(parents[j] === a[i]){ if (parents[j] === a[i]) {
loop = true;//dont rewalk array loop = true;// dont rewalk array
} }
} }
if (!loop && ! innerEquiv(a[i], b[i])) { if (!loop && !innerEquiv(a[i], b[i])) {
parents.pop(); parents.pop();
return false; return false;
} }
} }
parents.pop(); parents.pop();
return true; return true;
}, },
"object": function (b, a) { "object" : function(b, a) {
var i, j, loop; var i, j, loop;
var eq = true; // unless we can proove it var eq = true; // unless we can proove it
var aProperties = [], bProperties = []; // collection of strings var aProperties = [], bProperties = []; // collection of
// strings
// comparing constructors is more strict than using instanceof // comparing constructors is more strict than using
if ( a.constructor !== b.constructor) { // instanceof
return false; if (a.constructor !== b.constructor) {
} return false;
}
// stack constructor before traversing properties // stack constructor before traversing properties
callers.push(a.constructor); callers.push(a.constructor);
//track reference to avoid circular references // track reference to avoid circular references
parents.push(a); parents.push(a);
for (i in a) { // be strict: don't ensures hasOwnProperty and go deep for (i in a) { // be strict: don't ensures hasOwnProperty
loop = false; // and go deep
for(j=0;j<parents.length;j++){ loop = false;
if(parents[j] === a[i]) for (j = 0; j < parents.length; j++) {
loop = true; //don't go down the same path twice if (parents[j] === a[i])
} loop = true; // don't go down the same path
aProperties.push(i); // collect a's properties // twice
}
aProperties.push(i); // collect a's properties
if (!loop && ! innerEquiv(a[i], b[i])) { if (!loop && !innerEquiv(a[i], b[i])) {
eq = false; eq = false;
break; break;
} }
} }
callers.pop(); // unstack, we are done callers.pop(); // unstack, we are done
parents.pop(); parents.pop();
for (i in b) { for (i in b) {
bProperties.push(i); // collect b's properties bProperties.push(i); // collect b's properties
} }
// Ensures identical properties name // Ensures identical properties name
return eq && innerEquiv(aProperties.sort(), bProperties.sort()); return eq
} && innerEquiv(aProperties.sort(), bProperties
}; .sort());
}(); }
};
}();
innerEquiv = function () { // can take multiple arguments innerEquiv = function() { // can take multiple arguments
var args = Array.prototype.slice.apply(arguments); var args = Array.prototype.slice.apply(arguments);
if (args.length < 2) { if (args.length < 2) {
return true; // end transition return true; // end transition
} }
return (function (a, b) { return (function(a, b) {
if (a === b) { if (a === b) {
return true; // catch the most you can return true; // catch the most you can
} else if (a === null || b === null || typeof a === "undefined" || typeof b === "undefined" || QUnit.objectType(a) !== QUnit.objectType(b)) { } else if (a === null || b === null || typeof a === "undefined"
return false; // don't lose time with error prone cases || typeof b === "undefined"
} else { || QUnit.objectType(a) !== QUnit.objectType(b)) {
return bindCallbacks(a, callbacks, [b, a]); return false; // don't lose time with error prone cases
} } else {
return bindCallbacks(a, callbacks, [ b, a ]);
}
// apply transition with (1..n) arguments // apply transition with (1..n) arguments
})(args[0], args[1]) && arguments.callee.apply(this, args.splice(1, args.length -1)); })(args[0], args[1])
}; && arguments.callee.apply(this, args.splice(1,
args.length - 1));
};
return innerEquiv; return innerEquiv;
}(); }();
/** /**
* jsDump * jsDump Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com |
* Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com * http://flesler.blogspot.com Licensed under BSD
* Licensed under BSD (http://www.opensource.org/licenses/bsd-license.php) * (http://www.opensource.org/licenses/bsd-license.php) Date: 5/15/2008
* Date: 5/15/2008 *
* @projectDescription Advanced and extensible data dumping for Javascript. * @projectDescription Advanced and extensible data dumping for Javascript.
* @version 1.0.0 * @version 1.0.0
* @author Ariel Flesler * @author Ariel Flesler
@ -1143,11 +1178,11 @@ QUnit.jsDump = (function() {
return pre + post; return pre + post;
return [ pre, inner + arr, base + post ].join(s); return [ pre, inner + arr, base + post ].join(s);
}; };
function array( arr ) { function array( arr, stack ) {
var i = arr.length, ret = Array(i); var i = arr.length, ret = Array(i);
this.up(); this.up();
while ( i-- ) while ( i-- )
ret[i] = this.parse( arr[i] ); ret[i] = this.parse( arr[i] , undefined , stack);
this.down(); this.down();
return join( '[', ret, ']' ); return join( '[', ret, ']' );
}; };
@ -1155,13 +1190,23 @@ QUnit.jsDump = (function() {
var reName = /^function (\w+)/; var reName = /^function (\w+)/;
var jsDump = { var jsDump = {
parse:function( obj, type ) { //type is used mostly internally, you can fix a (custom)type in advance parse:function( obj, type, stack ) { //type is used mostly internally, you can fix a (custom)type in advance
var parser = this.parsers[ type || this.typeOf(obj) ]; stack = stack || [ ];
var parser = this.parsers[ type || this.typeOf(obj) ];
type = typeof parser; type = typeof parser;
var inStack = inArray(obj, stack);
return type == 'function' ? parser.call( this, obj ) : if (inStack != -1) {
type == 'string' ? parser : return 'recursion('+(inStack - stack.length)+')';
this.parsers.error; }
//else
if (type == 'function') {
stack.push(obj);
var res = parser.call( this, obj, stack );
stack.pop();
return res;
}
// else
return (type == 'string') ? parser : this.parsers.error;
}, },
typeOf:function( obj ) { typeOf:function( obj ) {
var type; var type;
@ -1235,11 +1280,13 @@ QUnit.jsDump = (function() {
array: array, array: array,
nodelist: array, nodelist: array,
arguments: array, arguments: array,
object:function( map ) { object:function( map, stack ) {
var ret = [ ]; var ret = [ ];
QUnit.jsDump.up(); QUnit.jsDump.up();
for ( var key in map ) for ( var key in map ) {
ret.push( QUnit.jsDump.parse(key,'key') + ': ' + QUnit.jsDump.parse(map[key]) ); var val = map[key];
ret.push( QUnit.jsDump.parse(key,'key') + ': ' + QUnit.jsDump.parse(val, undefined, stack));
}
QUnit.jsDump.down(); QUnit.jsDump.down();
return join( '{', ret, '}' ); return join( '{', ret, '}' );
}, },
@ -1308,6 +1355,21 @@ function getText( elems ) {
return ret; return ret;
}; };
//from jquery.js
function inArray( elem, array ) {
if ( array.indexOf ) {
return array.indexOf( elem );
}
for ( var i = 0, length = array.length; i < length; i++ ) {
if ( array[ i ] === elem ) {
return i;
}
}
return -1;
}
/* /*
* Javascript Diff Algorithm * Javascript Diff Algorithm
* By John Resig (http://ejohn.org/) * By John Resig (http://ejohn.org/)
@ -1323,14 +1385,14 @@ function getText( elems ) {
* QUnit.diff("the quick brown fox jumped over", "the quick fox jumps over") == "the quick <del>brown </del> fox <del>jumped </del><ins>jumps </ins> over" * QUnit.diff("the quick brown fox jumped over", "the quick fox jumps over") == "the quick <del>brown </del> fox <del>jumped </del><ins>jumps </ins> over"
*/ */
QUnit.diff = (function() { QUnit.diff = (function() {
function diff(o, n){ function diff(o, n) {
var ns = new Object(); var ns = {};
var os = new Object(); var os = {};
for (var i = 0; i < n.length; i++) { for (var i = 0; i < n.length; i++) {
if (ns[n[i]] == null) if (ns[n[i]] == null)
ns[n[i]] = { ns[n[i]] = {
rows: new Array(), rows: [],
o: null o: null
}; };
ns[n[i]].rows.push(i); ns[n[i]].rows.push(i);
@ -1339,7 +1401,7 @@ QUnit.diff = (function() {
for (var i = 0; i < o.length; i++) { for (var i = 0; i < o.length; i++) {
if (os[o[i]] == null) if (os[o[i]] == null)
os[o[i]] = { os[o[i]] = {
rows: new Array(), rows: [],
n: null n: null
}; };
os[o[i]].rows.push(i); os[o[i]].rows.push(i);
@ -1392,7 +1454,7 @@ QUnit.diff = (function() {
}; };
} }
return function(o, n){ return function(o, n) {
o = o.replace(/\s+$/, ''); o = o.replace(/\s+$/, '');
n = n.replace(/\s+$/, ''); n = n.replace(/\s+$/, '');
var out = diff(o == "" ? [] : o.split(/\s+/), n == "" ? [] : n.split(/\s+/)); var out = diff(o == "" ? [] : o.split(/\s+/), n == "" ? [] : n.split(/\s+/));