Builder

Create your own Jessie

Minification settings

Development options

addClass

Choose the most suitable rendition for your project.

Cutting edge only

/*global html,isHostObjectProperty,isHostMethod */

/*
Description:
Cutting edge only
*/

/*
Degrades:
IE9, IE8, IE7, IE6, IE5.5, IE5, IE4, IE3 Chrome 7, FF3.5, Safari 5.0, Opera 11.1, IOS Safari 4.3, Opera Mini 6.0, Opera Mobile 11.0, Android Safari 2.3
*/

/*
Author:
Adam Silver
*/

var addClass;

if (html && isHostObjectProperty(html, "classList") && isHostMethod(html.classList, "add") ) {
	addClass = function(el, className) {
		return el.classList.add(className);
	};
}

Cutting edge and wide support

/*global html,isHostObjectProperty,isHostMethod */

/*
Description:
Cutting edge and wide support
*/

/*
Degrades:
IE4, IE3, NN4
*/

/*
Author:
Adam Silver
*/

var addClass;

if (html && isHostObjectProperty(html, "classList") && isHostMethod(html.classList, "add") ) {
	addClass = function(el, className) {
		return el.classList.add(className);
	};
} else if (html && "string" === typeof html.className ) {
    addClass = function(el, className) {
		var re;
		if (!el.className) {
			el.className = className;
		}
		else {
			re = new RegExp('(^|\\s)' + className + '(\\s|$)');
			if (!re.test(el.className)) { el.className += ' ' + className; }
		}
    };
}

hasClass

Choose the most suitable rendition for your project.

Cutting edge

/*global html,isHostObjectProperty,isHostMethod */

/*
Description:
Cutting edge
*/

/*
Degrades:
IE9, IE8, IE7, IE6, IE5.5, IE5, IE4, IE3, Chrome 7, FF3.5, Safari 5.0, Opera 11.1, IOS Safari 4.3, Opera Mini 6.0, Opera Mobile 11.0, Android Safari 2.3
*/

/*
Author:
Adam Silver
*/

var hasClass;

if (html && isHostObjectProperty(html, "classList") && isHostMethod(html.classList, "contains") ) {
	hasClass = function(el, className) {
		return el.classList.contains(className);
	};
}

Cutting edge where possible, wide support

/*global html,isHostObjectProperty,isHostMethod */

/*
Description:
Cutting edge where possible, wide support
*/

/*
Author:
Adam Silver
*/

var hasClass;

if (html && isHostObjectProperty(html, "classList") && isHostMethod(html.classList, "contains") ) {
	hasClass = function(el, className) {
		return el.classList.contains(className);
	};
} else if(html && 'string' == typeof html.className) {
	hasClass = function(el, className) {
		return (new RegExp('(^|\\s)' + className + '(\\s|$)')).test(el.className);
	};
}

removeClass

Choose the most suitable rendition for your project.

Cutting edge only

/*global isHostObjectProperty,isHostMethod,html */

/*
Description:
Cutting edge only
*/

/*
Degrades:
Chrome 7, FF3.5, IE9, Safari 5.0, Opera 11.1, IOS Safari 4.3, Opera Mini 6.0, Opera Mobile 11.0, Android Safari 2.3
*/

/*
Author:
Adam Silver
*/

var removeClass;

if (html && isHostObjectProperty(html, "classList") && isHostMethod(html.classList, "remove") ) {
    removeClass = function(el, className) {
			return el.classList.remove(className);
    };
}

Cutting edge where possible, wide support

/*global isHostObjectProperty,isHostMethod,html */

/*
Description:
Cutting edge where possible, wide support
*/

/*
Author:
Adam Silver
*/

var removeClass;

if (html && isHostObjectProperty(html, "classList") && isHostMethod(html.classList, "remove") ) {
    removeClass = function(el, className) {
		return el.classList.remove(className);
    };
} else if(html && "string" == typeof html.className) {
	removeClass = function(el, className) {
		var re, m;
		if (el.className) {
			if (el.className == className) {
				el.className = '';
			} else {
				re = new RegExp('(^|\\s)' + className + '(\\s|$)');
				m = el.className.match(re);
				if (m && m.length == 3) {
					el.className = el.className.replace(re, (m[1] && m[2])?' ':'');
				}
			}
		}
	};
}

toggleClass

Relies on the jessie.hasClass && jessie.addClass && jessie.removeClass

/*global hasClass,addClass,removeClass */

/*
 Description:
 Relies on the `jessie.hasClass` && `jessie.addClass` && `jessie.removeClass`
 */

/*
 Author:
 Ben Chidgey
 */

var toggleClass;

if (hasClass && addClass && removeClass) {
	toggleClass = function(el, className) {
		var toggle = hasClass(el, className) ? 'remove' : 'add';
		jessie[toggle + 'Class'](el, className);
	};
}

ajaxGet

Relies on jessie.xhrCreate and jessie.xhrGet

/*global xhrCreate,xhrGet */

/*
Description:
Relies on `jessie.xhrCreate` and `jessie.xhrGet`
*/

/*
Author:
Adam Silver
*/

var ajaxGet;

if(xhrCreate && xhrGet) {
	ajaxGet = function(url, options) {
		var xhr = xhrCreate();
		return xhrGet(xhr, url, options);
	};
}

ajaxPost

Relies on jessie.xhrCreate and jessie.xhrPost

/*global xhrCreate,xhrPost */

/*
Description:
Relies on `jessie.xhrCreate` and `jessie.xhrPost`
*/

/*
Author:
Adam Silver
*/

var ajaxPost;

if(xhrCreate && xhrPost) {
	ajaxPost = function(url, options) {
		var xhr = xhrCreate();
		return xhrPost(xhr, url, options);
	};
}

jsonGet

Relies on jessie.ajaxGet and jessie.parseJson

/*global ajaxGet,parseJson,bind*/

/*
Description:
Relies on `jessie.ajaxGet` and `jessie.parseJson`
*/

/*
Degrades:
*/

/*
Author:
Adam Silver, Graham Veal
*/

var jsonGet;

if(ajaxGet && parseJson && bind) {
	jsonGet = function(url, options) {
		options = options || {};
		var	originalFunction = options.success;

		if(originalFunction) {

			options.success = function(response, xhr) {

				var json;

				options.thisObject = options.thisObject || xhr;
				originalFunction = bind(originalFunction, options.thisObject);

				try {

					json = parseJson(response);

				} catch( e ){

					json = null;
				}

				originalFunction(json, xhr);
			};
		}

		return ajaxGet(url, options);
	};
}

xhrAbort

Todo

var xhrAbort;

/*
Description:
Todo
*/

/*
Degrades:
In browsers without xhr support
*/

/*
Author:
Adam Silver
*/

xhrAbort = function(xhr) {
	xhr.abort();
	return xhr;
};

xhrCreate

Choose the most suitable rendition for your project.

Relies on W3C window.XMLHttpRequest.

NOTE: IE7+ native version does not support overrideMimeType or local file requests

/*global global,isHostMethod*/

/*
Description:
Relies on W3C `window.XMLHttpRequest`.

NOTE: IE7+ native version does not support overrideMimeType or local file
requests
*/

/*
Degrades:
IE6, IE5.5, IE5, IE4, IE3
*/

/*
Author:
David Mark
*/

var xhrCreate;

if(isHostMethod(global, "XMLHttpRequest")) {
	try {
		if(new global.XMLHttpRequest()) {
			xhrCreate = function() {
				return new XMLHttpRequest();
			};
		}
	}
	catch(e) {}
}

Cutting edge (W3 compliant) where possible, falling back to Microsoft implementations (ActiveXObject) providing wide support.

/*global isHostMethod,global */

/*
Description:
Cutting edge (W3 compliant) where possible, falling back to Microsoft implementations (ActiveXObject) providing wide support.
*/

/*
Degrades:
IE4, IE3, NN4
*/

/*
Author:
David Mark
*/

var createXhrFunctions = [
		function() {
          return new global.ActiveXObject("Microsoft.XMLHTTP");
        },
        // for fully patched Win2k SP4 and up
        function() {
          return new global.ActiveXObject("Msxml2.XMLHTTP.3.0");
        },
        // IE 6 users that have updated their msxml dll files.
        function() {
          return new global.ActiveXObject("Msxml2.XMLHTTP.6.0");
        }
	],
	i,
	xhrCreate;

if(isHostMethod(global, "XMLHttpRequest")) {
	try {
		if(new global.XMLHttpRequest()) {
			xhrCreate = function() {
				return new XMLHttpRequest();
			};
		}
	}
	catch(e) {}
} else if(isHostMethod(global, 'ActiveXObject')) {
	for (i=createXhrFunctions.length; i--; ) {
		try {
			if (createXhrFunctions[i]()) {
				xhrCreate = createXhrFunctions[i];
			}
		}
		catch (e) {}
	}
}

xhrGet

For making XHR get HTTP requests.

/*global xhrCreate,bind,mixin,isOwnProperty */

/*
Description:
For making XHR get HTTP requests.
*/

/*
Author:
Adam Silver
*/

var xhrGet;

// if you can't create one then you certainly can't send one
if (xhrCreate && bind && mixin && isOwnProperty) {
	xhrGet = function(xhr, url, options) {

		options = options || {};
		options.thisObject = options.thisObject || xhr;

		var successFn,
			failFn,
			completeFn,
			headers = {
				'X-Requested-With' : 'XMLHttpRequest'
			};

		if (options.headers) {
			mixin(headers, options.headers);
		}

		if (options.success) {
			successFn = bind(options.success, options.thisObject);
		}

		if (options.fail) {
			failFn = bind(options.fail, options.thisObject);
		}

		if (options.complete) {
			completeFn = bind(options.complete, options.thisObject);
		}

		function isSuccessfulResponse(xhr) {
			var success = false,
				status = xhr.status,
				between200and300 = (status >= 200 && status < 300),
				notModified = (status === 304);

			if (between200and300 || notModified || (status === 0 && xhr.responseText)) {
				success = true;
			}
			return success;
		}

		function handleReadyStateChange() {
			if (xhr.readyState === 4) {
				if (isSuccessfulResponse(xhr)) {
					if (successFn) {
						successFn(xhr.responseText, xhr);
					}
				}
				else if (failFn) {
					failFn(xhr);
				}
				if (completeFn) {
					completeFn(xhr);
				}
			}
		}

		xhr.open('GET', url);

		for (var key in headers) {
			if (isOwnProperty( headers, key )){
				xhr.setRequestHeader(key, headers[key]);
			}
		}

		xhr.onreadystatechange = handleReadyStateChange;
		xhr.send(null);

		return xhr;
	};
}

xhrPost

For making XHR post requests

/*global xhrCreate,bind,mixin,isOwnProperty */

/*
Description:
For making XHR post requests
*/

/*
Author:
Adam Silver
*/

var xhrPost;

// if you can't create one then you certainly can't send one
if(xhrCreate && bind && mixin && isOwnProperty) {


	xhrPost = function(xhr, url, options) {

		options = options || {};
		options.thisObject = options.thisObject || xhr;

		var data = options.data || null,
			successFn,
			failFn,
			completeFn,
			headers = {
				'Content-Type' : 'application/x-www-form-urlencoded',
				'X-Requested-With' : 'XMLHttpRequest'
			};

		if(options.headers){
			mixin(headers, options.headers);
		}

		if(options.success) {
			successFn = bind(options.success, options.thisObject);
		}

		if(options.fail) {
			failFn = bind(options.fail, options.thisObject);
		}

		if(options.complete) {
			completeFn = bind(options.complete, options.thisObject);
		}

		function isSuccessfulResponse(xhr) {
			var success = false,
				status = xhr.status,
				between200and300 = (status >= 200 && status < 300),
				notModified = (status === 304);

			if(between200and300 || notModified || (status === 0 && xhr.responseText)) {
				success = true;
			}
			return success;
		}

		function handleReadyStateChange() {
			if(xhr.readyState === 4) {
				if(isSuccessfulResponse(xhr)) {
					if(successFn) {
						successFn(xhr.responseText, xhr);
					}
				}
				else if(failFn) {
					failFn(xhr);
				}
				if(completeFn) {
					completeFn(xhr);
				}
			}
		}

		xhr.open('POST', url);

		for(var key in headers) {
			if(isOwnProperty( headers, key )){
				xhr.setRequestHeader(key, headers[key]);
			}
		}

		xhr.onreadystatechange = handleReadyStateChange;
		xhr.send(data);

		return xhr;
	};
}

appendChild

Relies on el.appendChild

/*global html,isHostMethod */

/*
Description:
Relies on `el.appendChild`
*/

/*
Author:
Adam Silver
*/

var appendChild;

if(html && isHostMethod(html, 'appendChild')) {
	appendChild = function(el, appendEl) {
		return el.appendChild(appendEl);
	};
}

appendHtml

Choose the most suitable rendition for your project.

Relies on el.insertAdjacentHTML IE6 el.insertAdjacentHtml` does not work on table, tbody, thead, tr elements

/*global html*/

/*
 Description:
 Relies on `el.insertAdjacentHTML
 IE6 `el.insertAdjacentHtml` does not work on table, tbody, thead, tr elements
 */

/*
 Degrades:
 IE3, Firefox 7, Safari 3, Opera 7
 */

/*
 Author:
 Ben Chidgey
 */

var appendHtml;

if (html && isHostMethod(html, 'insertAdjacentHTML')) {
	appendHtml = function (el, html) {
		el.insertAdjacentHTML('beforeEnd', html);
	};
}

Relies on el.innerHTML which degrades in IE3 and el.appendChild and el.firstChild and createElement and setHtml

/*global html,createElement,setHtml*/

/*
 Description:
 Relies on `el.innerHTML` which degrades in IE3
 and `el.appendChild`
 and `el.firstChild`
 and `createElement`
 and `setHtml`
 */

/*
 Degrades:
 IE3
 */

/*
 Author:
 Ben Chidgey
 */

var appendHtml;

if (html && isHostObjectProperty(html, 'firstChild') && isHostMethod(html, 'appendChild') && createElement && setHtml) {
	appendHtml = function (el, html) {
		var fragment = createElement('div'),
			child;

		setHtml(fragment, html);

		while ((child = fragment.firstChild)) {
			el.appendChild(child);
		}
	};
}

createElement

Relies on document.createElement

/*global globalDocument,isHostMethod*/

/*
Description:
Relies on `document.createElement`
*/

/*
Author:
David Mark
*/

var createElement;

if(globalDocument && isHostMethod(globalDocument, "createElement")) {
	createElement = function(tagName, doc) {
		return (doc || document).createElement(tagName);
	};
}

findProprietaryStyle

Wide support

/*global html,isHostObjectProperty */

/*
Description:
Wide support
*/

var findProprietaryStyle;

if(html && isHostObjectProperty(html, "style")){
	findProprietaryStyle = function (style, el) {
		if ('string' != typeof el.style[style]) {
			var prefixes = ['Moz', 'O', 'Khtml', 'Webkit', 'Ms'],
			i = prefixes.length;
			style = style.charAt(0).toUpperCase() + style.substring(1);
			while ( i-- ) {
				if ('undefined' != typeof el.style[prefixes[i] + style]) {
					return prefixes[i] + style;
				}
			}
			return null;
		}
		return style;
	};
}

getAncestorByClassName

Relies on el.className property, jessie.getElementParentElement and jessie.hasClass

/*global html,getElementParentElement,hasClass */

/*
Description:
Relies on `el.className` property, `jessie.getElementParentElement` and `jessie.hasClass`
*/

var getAncestorByClassName;

if(html && 'string' == typeof html.className && getElementParentElement && hasClass) {
	getAncestorByClassName = function(el, className) {
		el = getElementParentElement(el);
		while (el && !hasClass(el, className)) {
			el = getElementParentElement(el);
		}
		return el;
	};
}

getAncestorByTagName

Relies on jessie.getElementParentElement and jessie.getElementTagName

/*global getElementParentElement,getElementTagName */

/*
Description:
Relies on `jessie.getElementParentElement` and `jessie.getElementTagName`
*/

var getAncestorByTagName;

if(getElementParentElement && getElementTagName){
	getAncestorByTagName = function(el, tagName) {
		el = getElementParentElement(el);
		while (el && tagName && getElementTagName(el) != tagName) {
			el = getElementParentElement(el);
		}
		return el;
	};
}

getDescendantsByClassName

Choose the most suitable rendition for your project.

Relies on 'document.getElementsByClassName'

/*global globalDocument,isHostMethod,toArray */

/*
Description:
Relies on 'document.getElementsByClassName'
*/

var getDescendantsByClassName;

if (globalDocument && isHostMethod(globalDocument, "getElementsByClassName") && toArray) {
	getDescendantsByClassName = function(el, className) {
		return toArray((el || document).getElementsByClassName(className));
	};
}

Relies on jessie.getDescendantsByTagName and jessie.hasClass

/*global getDescendantsByTagName,hasClass */

/*
Description:
Relies on `jessie.getDescendantsByTagName` and `jessie.hasClass`
*/

var getDescendantsByClassName;

if (getDescendantsByTagName && hasClass) {
	getDescendantsByClassName = function(el, className) {
		var elements = getDescendantsByTagName(el, '*'),
			element,
			i,
			elementsWithClassName = [];
		for(i = 0; i < elements.length; i++) {
			element = elements[i];
			if(hasClass(element, className)) {
				elementsWithClassName.push(element);
			}
		}
		return elementsWithClassName;
	};
}

getDescendantsByTagName

Relies on 'document.getElementsByTagName'

/*global globalDocument,toArray,isHostMethod */

/*
Description:
Relies on 'document.getElementsByTagName'
*/

var getDescendantsByTagName;

if(globalDocument && isHostMethod(globalDocument, "getElementsByTagName") && toArray) {
	getDescendantsByTagName = function(el, tagName) {
		return toArray((el || document).getElementsByTagName(tagName));
	};
}

getElement

Basic rendition which relies on valid markup i.e. forms with unique names and ids

/*global isHostMethod */

/*
Description:
Basic rendition which relies on valid markup i.e. forms with unique names and ids
*/

/*
See: <a href="https://groups.google.com/forum/#!starred/comp.lang.javascript/fVp-DWAIGnc">Article</a>

That's the most basic rendition: no allowance for screwy markup like this:

<input name="test">
<input id="test">
*/

/*
Degrades:
IE4, IE3, NN4
*/

/*
Author:
David Mark
*/

var getElement;

if (isHostMethod(document, 'getElementById')) {
	getElement = function(id, doc) {
		return (doc || document).getElementById(id);
	};
}

<a href="https://groups.google.com/forum/#!starred/comp.lang.javascript/fVp-DWAIGnc">Article</a> That's the most basic rendition: no allowance for screwy markup like this: <input name="test"> <input id="test">

getElementData

Choose the most suitable rendition for your project.

Relies on el.dataset

/*global html,isHostObjectProperty */

/*
 Description:
 Relies on el.dataset
 */

/*
 Degrades:
 IE11-, FF5-, Chrome 6-, Safari 5.0-, Opera 11.0-, iOS 4.3-, Android 2.3-
 */

/*
 Author:
 Graham Veal
 */

var getElementData;

if( html && isHostObjectProperty( html, "dataset" ) ){

	(function(){

		var reGetDashAndLetter = /-([a-z])/g;

		function convertDataName( match, letter ){

			return letter.toUpperCase();
		}

		getElementData = function( el, dataName ){

			//convert the dataName to lowercase
			//then remove the dash and replace the character next to the dash with the upper case version
			dataName = dataName.toLowerCase().replace( reGetDashAndLetter, convertDataName );

			return el.dataset[ dataName ];
		};
	}());
}

Relies on el.getAttribute

/*global html,isHostMethod */

/*
 Description:
 Relies on el.getAttribute
 */

/*
 Degrades:
 IE5-
 */

/*
 Author:
 Graham Veal
 */

var getElementData;

if( html && isHostMethod( html, "getAttribute" ) ){

	getElementData = function( el, dataName ){

		return el.getAttribute( 'data-' + dataName );
	};
}

Relies on el.dataset or el.getAttribute for the most support

/*global html,isHostObjectProperty,isHostMethod */

/*
 Description:
 Relies on el.dataset or el.getAttribute for the most support
 */

/*
 Degrades:
 IE5-
 */

/*
 Author:
 Graham Veal
 */

var getElementData;

if( html && isHostObjectProperty( html, "dataset" ) ){

	(function(){

		var reGetDashAndLetter = /-([a-z])/g;

		function convertDataName( match, letter ){

			return letter.toUpperCase();
		}

		getElementData = function( el, dataName ){

			//convert the dataName to lowercase
			//then remove the dash and replace the character next to the dash with the upper case version
			dataName = dataName.toLowerCase().replace( reGetDashAndLetter, convertDataName );

			return el.dataset[ dataName ];
		};

	}());

} else if( html && isHostMethod( html, "getAttribute" ) ){

	getElementData = function( el, dataName ){

		return el.getAttribute( 'data-' + dataName );
	};
}

getElementDocument

Choose the most suitable rendition for your project.

Relies on document.documentElement.ownerDocument

var getElementDocument;

/*
Description:
Relies on document.documentElement.ownerDocument
*/

if (isHostObjectProperty(html, 'ownerDocument')) {
    getElementDocument = function(el) {
        return el.ownerDocument;
    };
}

Wide support.

var getElementDocument;

/*
Description:
Wide support.
*/

getElementDocument = function(el) {
    if (el.parentNode) {
        while (el.parentNode) {
            el = el.parentNode;
        }
        if (el.nodeType == 9 || (!el.nodeType && !el.tagName)) {
            return el;
        }
    }

    return null;
}

Wide support. Cutting edge where possible.

var getElementDocument;

/*
Description:
Wide support. Cutting edge where possible.
*/

if (isHostObjectProperty(html, 'ownerDocument')) {
    getElementDocument = function(el) {
        return el.ownerDocument;
    };
} else {
    getElementDocument = function(el) {
        if (el.parentNode) {
            while (el.parentNode) {
                el = el.parentNode;
            }
            if (el.nodeType == 9 || (!el.nodeType && !el.tagName)) {
                return el;
            }
        }

        return null;
    }
}

getElementParentElement

Choose the most suitable rendition for your project.

Relies on el.parentNode

/*global html, globalDocument, isHostObjectProperty*/

var getElementParentElement;

/*
Description:
Relies on `el.parentNode`
*/

/* 
Degrades:
IE5, IE4, IE3
*/

if (html && isHostObjectProperty(html, 'parentNode')) {
	getElementParentElement = function(el) {
		var parentNode = el.parentNode,
			parentElement = null;

		if (parentNode && (parentNode.tagName || parentNode.nodeType == 1)) {
			parentElement = parentNode;
		}
		return parentElement;
	};
}

Relies on 'el.parentElement' and 'jessie.getDescendantsByTagName'

/*global html, isHostObjectProperty, getDescendantsByTagName*/

var getElementParentElement;

/*
Description:
Relies on 'el.parentElement' and 'jessie.getDescendantsByTagName'
*/

/*
Degrades:
IE3
*/

if (getDescendantsByTagName && isHostObjectProperty(getDescendantsByTagName('head')[0], 'parentElement')) {
	getElementParentElement = function(el) {
		return el.parentElement;
	};
}

Relies on 'el.parentNode' or 'el.parentElement' Relies on 'jessie.getDescendantsByTagName'

/*global html, isHostObjectProperty, getDescendantsByTagName*/

var getElementParentElement;

/*
Description:
Relies on 'el.parentNode' or 'el.parentElement'
Relies on 'jessie.getDescendantsByTagName'
*/

/*
Degrades:
IE3
*/

if (html && isHostObjectProperty(html, 'parentNode')) {
    getElementParentElement = function(el) {
        var parentNode = el.parentNode,
            parentElement = null;

        if (parentNode && (parentNode.tagName || parentNode.nodeType == 1)) {
            parentElement = parentNode;
        }
        return parentElement;
    };
} else if (getDescendantsByTagName && isHostObjectProperty(getDescendantsByTagName('head')[0], 'parentElement')) {
	getElementParentElement = function(el) {
		return el.parentElement;
	};
}

getElementPositionStyles

Relies on jessie.getElement, el.style and el.offsetLeft

/*global html,getElement,isHostObjectProperty */

/*
Description:
Relies on `jessie.getElement`, `el.style` and `el.offsetLeft`
*/

// Taken from primer

var getElementPositionStyles;

if(html && getElement && isHostObjectProperty(html, 'style') &&
	'number' == typeof html.offsetLeft && 'string' == typeof html.style.left ) {
	
	getElementPositionStyles = (function() {
		var result,
			sides = ['left', 'top', 'right', 'bottom'],
			inlineStyles = {},
			findPosition;
			
		findPosition = function(el, sides) {
			var i,
				offsetLeft,
				offsetTop;
				
			offsetLeft = el.offsetLeft;
			offsetTop = el.offsetTop;
			el.style[sides[2]] = 'auto';
			el.style[sides[3]] = 'auto';
			
			if (offsetLeft != el.offsetLeft) {
				result[sides[0]] = null;
			}

			if (offsetTop != el.offsetTop) {
				result[sides[1]] = null;
			}

			offsetLeft = el.offsetLeft;
			offsetTop = el.offsetTop;

			el.style[sides[0]] = offsetLeft + 'px';
			el.style[sides[1]] = offsetTop + 'px';

			if (result[sides[0]] !== null && el.offsetLeft != offsetLeft) {
				if (sides[0] == 'left') {
					result[sides[0]] = offsetLeft - el.offsetLeft + offsetLeft;
				}
				else {
					result[sides[0]] = el.offsetLeft;
				}
			}

			if (result[sides[1]] !== null && el.offsetTop != offsetTop) {
				if (sides[1] == 'top') {
					result[sides[1]] = offsetTop - el.offsetTop + offsetTop;
				}
				else {
					result[sides[1]] = el.offsetTop;
				}
			}
			
			for (i = 4; i--;) {
				el.style[sides[i]] = inlineStyles[sides[i]];
			}
		};

		return function(el) {
			var i,
				side,
				otherSide;

			result = {};

			for (i = 2; i--;) {
				side = sides[i];
				otherSide = sides[i + 2];
				result[side] = result[otherSide] = el['offset' + side.charAt(0).toUpperCase() + side.substring(1)];
			}

			for (i = 4; i--;) {
				side = sides[i];
				inlineStyles[side] = el.style[side];
			}

			findPosition(el, sides);
			findPosition(el, sides.slice(2).concat(sides.slice(0, 2)));

			return result;
		};
		
	}());
}

getElementTagName

Relies on el.tagName or el.nodeName

var getElementTagName;

/*
Description:
Relies on `el.tagName` or `el.nodeName`
*/

getElementTagName = function (el) {
	var tagName = (el.tagName || el.nodeName).toLowerCase();
	return tagName.indexOf('html:') > -1 ? tagName.substring(5) : tagName;
};

getHtml

Relies on el.innerHTML

/*global html */

/*
Description:
Relies on `el.innerHTML`
*/

// See: https://groups.google.com/forum/#!search/david$20mark$20innerHTML/comp.lang.javascript/QQ9ClOT6igQ/LIZ5QXmmuw0J

/*
Degrades:
IE3
*/

/*
Author:
David Mark
*/

var getHtml;

if(html && "string" == typeof html.innerHTML) {
	getHtml = function(el) {
		return el.innerHTML;
	};
}

getInnerSize

Relies on el.clientWidth/Height

/*global html */

/*
Description:
Relies on `el.clientWidth/Height`
*/

/*
Degrades:
IE3
*/

/*
Author:
David Mark
*/

var getInnerSize;

if(html && typeof html.clientWidth == 'number') {
	getInnerSize = function(el) {
		return [el.clientHeight, el.clientWidth];
	};
}

getOuterSize

Relies on el.offsetWidth/Height

/*global html */

/*
Description:
Relies on `el.offsetWidth/Height`
*/

/*
Degrades:
IE3
*/

/*
Author:
David Mark
*/

var getOuterSize;

if(html && typeof html.offsetWidth == 'number') {
	getOuterSize = function(el) {
		return [el.offsetHeight, el.offsetWidth];
	};
}

getOwnerDocument

Relies on el.ownerDocument

/*global html,isHostObjectProperty*/

/*
Description:
Relies on `el.ownerDocument`
*/

/*
Author:
David Mark
*/

var getOwnerDocument;

if(html && isHostObjectProperty(html, 'ownerDocument')) {
	getOwnerDocument = function(el) {
		return el.ownerDocument;
	};
}

getPositionRelativeToDocument

Note: no borders on the HTML element as that can add cross-browser complications (part of the chrome in IE and other MSHTML-based browsers, not so in others) and no quirks mode (as the BODY then becomes outermost element in the layout in IE and the BODY should be allowed to have borders).

/*global getPositionRelativeToViewport,getViewportScrollPosition*/

/*
Description:

Note: no borders on the HTML element as that can add cross-browser complications (part of the chrome in IE and other MSHTML-based browsers, not so in others) and no quirks mode (as the BODY then becomes outermost element in the layout in IE and the BODY should be allowed to have borders).
*/

/*
Degrades:
*/

/*
Author:
Adam Silver
*/

var getPositionRelativeToDocument;

if(getPositionRelativeToViewport && getViewportScrollPosition) {
	getPositionRelativeToDocument = function(el) {
		var position = getPositionRelativeToViewport(el),
			scrollPosition = getViewportScrollPosition(),
			x = position[0]+scrollPosition[0],
			y = position[1]+scrollPosition[1];

		return [x, y];
	};
}

getPositionRelativeToViewport

Relies on el.getBoundingClientRect

/*global html,isHostMethod */

/*
Description:
Relies on `el.getBoundingClientRect`
*/

//https://groups.google.com/group/comp.lang.javascript/browse_thread/thread/cd625a14ce603084?hl=en&noredirect=true

/*
Author:
David Mark
*/

var getPositionRelativeToViewport;

if(html && isHostMethod(html, 'getBoundingClientRect')) {
	getPositionRelativeToViewport = function(el) {
		var rect = el.getBoundingClientRect();
		return [rect.left, rect.top];
	};
}

getStyleComputed

Relies on document.defaultView.getComputedStyle which degrades in IE8- and compatibility modes. No float styles with this one and camel-case names.

/*global isHostObjectProperty,globalDocument,isHostMethod */

/*
Description:
Relies on `document.defaultView.getComputedStyle` which degrades in IE8-
and compatibility modes. No float styles with this one and camel-case
names.
*/

/*
Degrades:
IE8, IE7, IE6, IE5.5, IE5, IE4, IE3
*/

/*
Author:
David Mark
*/

var getStyleComputed;

if (isHostObjectProperty(globalDocument, 'defaultView') &&
	isHostMethod(globalDocument.defaultView, 'getComputedStyle')) {
	getStyleComputed = function(el, style) {
		
		/*SCAFFOLDING:Start*/
		if (style.indexOf('-') != -1) {
			throw new Error('Camel-case style names, please.');
		}

		if (style == 'float') {
			throw new Error('The "float" style is not supported by this rendition.');
		}
		
		if (el.style.display == 'none') {
			throw new Error('Element not in layout. Cannot compute styles.');
		}
		/*SCAFFOLDING:End*/
		
		return document.defaultView.getComputedStyle(el, null)[style];
	};
}

getText

Choose the most suitable rendition for your project.

Relies on el.textContent

/*global html */

/*
Description:
Relies on `el.textContent`
*/

var getText;

if(html && "string" == typeof html.textContent) {
	getText = function(el) {
		return el.textContent;
	};
}

Relies on el.innerText

/*global html */

/*
Description:
Relies on `el.innerText`
*/

var getText;

if(html && "string" == typeof html.innerText) {
	getText = function(el) {
		return el.innerText;
	};
}

Relies on el.textContent or el.innerText providing widest browser support.

/*global html */

/*
Description:
Relies on `el.textContent` or `el.innerText` providing widest browser support.
*/

var getText;

if(html && "string" == typeof html.textContent) {
	getText = function(el) {
		return el.textContent;
	};
} else if(html && "string" == typeof html.innerText) {
	getText = function(el) {
		return el.innerText;
	};
}

isAncestor

Choose the most suitable rendition for your project.

Relies on el.parentNode which has very good support

/*global html */

/*
Description:
Relies on `el.parentNode` which has very good support
*/

/*
Degrades:
In browsers without `el.parentNode`
*/

/*
Author:
Adam Silver
*/

var isAncestor;

if(html && 'undefined' != typeof html.parentNode) {
	isAncestor = function(el, elAncestor) {
		var parent = el.parentNode;
		while(parent && parent != elAncestor) {
			parent = parent.parentNode;
		}
		return parent == elAncestor;
	};
}

/*global html,isHostMethod */

/*
Author:
Adam Silver
*/

var isAncestor;

if(isHostMethod(html, 'contains')) {
	isAncestor = function(el, elAncestor) {
		return elAncestor.contains(el);
	};
}

Relies on el.parentNode or el.contains

/*global html,isHostMethod */

/*
Description:
Relies on `el.parentNode` or `el.contains`
*/

/*
Degrades:
In browsers without `el.parentNode` and `el.contains`
*/

/*
Author:
Adam Silver
*/

var isAncestor;

if(isHostMethod(html, 'contains')) {
	isAncestor = function(el, elAncestor) {
		return elAncestor.contains(el);
	};
} else if(html && 'undefined' != typeof html.parentNode) {
	isAncestor = function(el, elAncestor) {
		var parent = el.parentNode;
		while(parent && parent != elAncestor) {
			parent = parent.parentNode;
		}
		return parent == elAncestor;
	};
}

isDescendant

Choose the most suitable rendition for your project.

Relies on el.parentNode which has very good support

/*global html */

/*
Description:
Relies on `el.parentNode` which has very good support
*/

/*
Degrades:
In browsers without `el.parentNode`
*/

var isDescendant;

if(html && 'undefined' != typeof html.parentNode) {
	isDescendant = function(el, elDescendant) {
		var parent = elDescendant.parentNode;
		while(parent && parent != el) {
			parent = parent.parentNode;
		}
		return parent == el;
	};
}

/*global html,isHostMethod */

/*
Author:
Adam Silver
*/

var isDescendant;

if(isHostMethod(html, 'contains')) {
	isDescendant = function(el, elDescendant) {
		return el.contains(elDescendant);
	};
}

Relies on el.parentNode or el.contains

/*global html,isHostMethod */

/*
Description:
Relies on `el.parentNode` or `el.contains`
*/

/*
Degrades:
In browsers without `el.parentNode` and `el.contains`
*/

var isDescendant;

if(isHostMethod(html, 'contains')) {
	isDescendant = function(el, elDescendant) {
		return el.contains(elDescendant);
	};
} else if(html && 'undefined' != typeof html.parentNode) {
	isDescendant = function(el, elDescendant) {
		var parent = elDescendant.parentNode;
		while(parent && parent != el) {
			parent = parent.parentNode;
		}
		return parent == el;
	};
}

isInQuery

Relies on jessie.isNodeInNodeList, jessie.query

/*global isNodeInNodeList,query */

/*
Description:
Relies on `jessie.isNodeInNodeList`, `jessie.query`
*/

/*
Author:
Graham Veal
*/

var isInQuery;

if(isNodeInNodeList && query) {
	isInQuery = function(el, selector) {
		
		return isNodeInNodeList( el, query(selector) );
	};
}

isNodeInNodeList

Iterates a node list to see if any of the nodes match the passed in node.

/*global */

/*
Description:
Iterates a node list to see if any of the nodes match the passed in node.
*/

/*
Author:
Graham Veal
*/

var isNodeInNodeList;

isNodeInNodeList = function( node, nodeList ){

	var isInNodeList = false,
		i = 0,
		l = nodeList.length;

	// could use Array.prototype.indexOf in another rendition
	for( ; i < l; i++ ) {
		if(nodeList[i] === node) {
			isInNodeList = true;
			break;
		}
	}

	return isInNodeList;
};

prependChild

Relies on el.firstChild, el.insertBefore, jessie.appendChild

/*global isHostMethod,isHostObjectProperty,html,appendChild*/

/*
 Description:
 Relies on `el.firstChild`, `el.insertBefore`, `jessie.appendChild`
 */

/*
 Degrades:

 */

/*
 Author:
Graham Veal
 */

var prependChild;

if (html && isHostMethod(html, 'insertBefore') && isHostObjectProperty(html, 'firstChild') && appendChild) {

	prependChild = function(container, node){

		var firstChild = container.firstChild;

		if( firstChild ){

			container.insertBefore( node, firstChild );

		} else {

			appendChild( container, node );
		}
	};
}

prependHtml

Choose the most suitable rendition for your project.

Relies on el.insertAdjacentHTML IE6 el.insertAdjacentHtml` does not work on table, tbody, thead, tr elements

/*global html*/

/*
 Description:
 Relies on `el.insertAdjacentHTML
 IE6 `el.insertAdjacentHtml` does not work on table, tbody, thead, tr elements
 */

/*
 Degrades:
 IE3, Firefox 7, Safari 3, Opera 7
 */

/*
 Author:
 Ben Chidgey
 */

var prependHtml;

if (html && isHostMethod(html, 'insertAdjacentHTML')) {
	prependHtml = function (el, html) {
		el.insertAdjacentHTML('afterBegin', html);
	};
}

Relies on el.innerHTML which degrades in IE3 and el.insertBefore and el.firstChild and createElement and setHtml

/*global createElement,setHtml*/

/*
 Description:
 Relies on `el.innerHTML` which degrades in IE3
 and `el.insertBefore`
 and `el.firstChild`
 and `createElement`
 and `setHtml`
 */

/*
 Degrades:
 IE3
 */

/*
 Author:
 Ben Chidgey
 */

var prependHtml;

if (html && isHostObjectProperty(html, 'firstChild') && isHostMethod(html, 'insertBefore') && createElement && setHtml) {
    prependHtml = function (el, html) {
        var fragment = createElement('div'),
            child;

        setHtml(fragment, html);

        while ((child = fragment.firstChild)) {
            el.insertBefore(child, el.firstChild);
        }
    };
}

query

Relies on document.querySelectorAll and jessie.toArray

/*global globalDocument,isHostMethod,toArray */

/*
Description:
Relies on `document.querySelectorAll` and `jessie.toArray`
*/

/*
Author:
David Mark
*/

var query;

if(globalDocument && isHostMethod(globalDocument, 'querySelectorAll') && toArray) {
	query = function(selector, doc) {
		return toArray((doc || document).querySelectorAll(selector));
	};
}

queryOne

Relies on document.querySelector

/*global globalDocument,isHostMethod */

/*
Description:
Relies on `document.querySelector`
*/

/*
Author:
Christopher Thorn
*/

var queryOne;

if(globalDocument && isHostMethod(globalDocument, 'querySelector')) {
    queryOne = function(selector, doc) {
        return (doc || document).querySelector(selector);
    };
}

removeChild

Relies on el.removeChild

/*global html,isHostMethod */

/*
Description:
Relies on `el.removeChild`
*/

/*
Author:
Adam Silver
*/

var removeChild;

if(html && isHostMethod(html, "removeChild")) {
	removeChild = function(el, childNode) {
		return el.removeChild(childNode);
	};
}

setAriaAttribute

Wide support

/*
Description:
Wide support
*/

var setAriaAttribute;

setAriaAttribute = function(el, attribute, value) {
    el.setAttribute('aria-' + attribute, value);
};

setElementData

Choose the most suitable rendition for your project.

Relies on el.dataset

/*global html,isHostObjectProperty */

/*
 Description:
 Relies on el.dataset
 */

/*
 Degrades:
 IE11-, FF5-, Chrome 6-, Safari 5.0-, Opera 11.0-, iOS 4.3-, Android 2.3-
 */

/*
 Author:
 Graham Veal
 */

var setElementData;

if( html && isHostObjectProperty( html, "dataset" ) ){

	(function(){

		var reGetDashAndLetter = /-([a-z])/g;

		function convertDataName( match, letter ){

			return letter.toUpperCase();
		}

		setElementData = function( el, dataName, dataValue ){

			//convert the dataName to lowercase
			//then remove the dash and replace the character next to the dash with the upper case version
			dataName = dataName.toLowerCase().replace( reGetDashAndLetter, convertDataName );

			el.dataset[ dataName ] = dataValue;
		};
	}());
}

Relies on el.setAttribute, <string>.replace, <string>.toLowerCase

/*global html,isHostMethod */

/*
 Description:
 Relies on el.setAttribute, <string>.replace, <string>.toLowerCase
 */

/*
 Degrades:
 IE5-
 */

/*
 Author:
 Graham Veal
 */

var setElementData;

if( html && isHostMethod( html, "setAttribute" ) ){

	setElementData = function( el, dataName, dataValue ){

		el.setAttribute( 'data-' + dataName, dataValue );
	};
}

Relies on el.dataset or el.setAttribute

/*global html,isHostObjectProperty,isHostMethod */

/*
 Description:
 Relies on el.dataset or el.setAttribute
 */

/*
 Degrades:
 IE5-
 */

/*
 Author:
 Graham Veal
 */

var setElementData;

if( html && isHostObjectProperty( html, "dataset" ) ){

	(function(){

		var reGetDashAndLetter = /-([a-z])/g;

		function convertDataName( match, letter ){

			return letter.toUpperCase();
		}

		setElementData = function( el, dataName, dataValue ){

			//convert the dataName to lowercase
			//then remove the dash and replace the character next to the dash with the upper case version
			dataName = dataName.toLowerCase().replace( reGetDashAndLetter, convertDataName );

			el.dataset[ dataName ] = dataValue;
		};

	}());

} else if( html && isHostMethod( html, "setAttribute" ) ){

	setElementData = function( el, dataName, dataValue ){

		el.setAttribute( 'data-' + dataName, dataValue );
	};
}

setHtml

Relies on el.innerHTML which degrades in IE3

/*global html */

/*
Description:
Relies on `el.innerHTML` which degrades in IE3
*/

/*
See: <a href="https://groups.google.com/forum/#!search/david$20mark$20innerHTML/comp.lang.javascript/QQ9ClOT6igQ/LIZ5QXmmuw0J">Related article</a>
NOTE: Don't use this rendition with anything but DIV's
*/

/*
Degrades:
IE3
*/

/*
Author:
David Mark
*/

var setHtml;

if(html && "string" == typeof html.innerHTML) {
	setHtml = function(el, html) {
		el.innerHTML = html;
	};
}

<a href="https://groups.google.com/forum/#!search/david$20mark$20innerHTML/comp.lang.javascript/QQ9ClOT6igQ/LIZ5QXmmuw0J">Related article</a> NOTE: Don't use this rendition with anything but DIV's

setPosition

Wide support

/*global html,isHostObjectProperty */

/*
Description:
Wide support
*/

var setPosition;
if(html && isHostObjectProperty(html, "style")){
  setPosition = (function(el) {
    var px = (typeof html.style.top == 'number') ? 0 : 'px';
    return function(el, x, y) {
      if (x !== null) { el.style.left = x + px; }
      if (y !== null) { el.style.top = y + px; }
    };
  }());
}

setSize

Wide support

/*global html,isHostObjectProperty */

var setSize;

/*
Description:
Wide support
*/

if(html && isHostObjectProperty(html, "style")){
  setSize = (function() {
    var px = (typeof html.style.top == 'number') ? 0 : 'px';
    return function(el, h, w) {
      if (h !== null && h >= 0) { el.style.height = h + px; }
      if (w !== null && w >= 0) { el.style.width = w + px; }
    };
  }());
}

setText

Choose the most suitable rendition for your project.

Relies on el.textContent

/*global html */

/*
Description:
Relies on `el.textContent`
*/

var setText;

if(html && "string" == typeof html.textContent) {
	setText = function(el, text) {
		el.textContent = text;
	};
}

Relies on el.innerText

/*global html */

/*
Description:
Relies on `el.innerText`
*/

var setText;

if(html && "string" == typeof html.innerText) {
	setText = function(el, text) {
		el.innerText = text;
	};
}

Relies on el.textContent or el.innerText providing widest browser support.

/*global html */

/*
Description:
Relies on `el.textContent` or `el.innerText` providing widest browser support.
*/

var setText;

if(html && "string" == typeof html.textContent) {
	setText = function(el, text) {
		el.textContent = text;
	};
} else if(html && "string" == typeof html.innerText) {
	setText = function(el, text) {
		el.innerText = text;
	};
}

attachDocumentListener

Choose the most suitable rendition for your project.

Cutting edge (W3 compliant)

/*global global,globalDocument,isHostMethod,attachListener */

/*
Description:
Cutting edge (W3 compliant)
*/

/*
Degrades:
IE8, IE7, IE6, IE5.5, IE5, IE4, IE3
*/

var attachDocumentListener;

if(globalDocument && isHostMethod(globalDocument, 'addEventListener') && attachListener) {
	attachDocumentListener = function(eventType, fn) {

		var listener = function(e) {
			fn.call(document, e);
		};

		return attachListener(document, eventType, fn);
	};
}

Cutting edge (W3 compliant) and handles Microsoft event model. Wide support.

/*global global,globalDocument,isHostMethod,attachListener */

/*
Description:
Cutting edge (W3 compliant) and handles Microsoft event model. Wide support.
*/

/*
Degrades:
IE4, IE3
*/

var attachDocumentListener;

if(globalDocument && isHostMethod(globalDocument, 'addEventListener') && attachListener) {
	attachDocumentListener = function(eventType, fn) {

		var listener = function(e) {
			fn.call(document, e);
		};

		return attachListener(document, eventType, fn);
	};
} else if(globalDocument && isHostMethod(globalDocument, 'attachEvent') && attachListener) {
	attachDocumentListener = function(eventType, fn) {

		var listener = function(e) {
			fn.call(document, e);
		};

		return attachListener(document, eventType, fn);
	};
}

attachListener

Choose the most suitable rendition for your project.

Cutting edge

/*global html,isHostMethod */
/*
Description:
Cutting edge
*/

/*
Degrades:
IE8, IE7, IE6, IE5.5, IE5, IE4, IE3, Opera 7.6
*/

/*
Author:
David Mark
*/

var attachListener;

if(html && isHostMethod(html, 'addEventListener')) {
	attachListener = function(el, eventType, fn) {
		el.addEventListener(eventType, fn, false);
		return fn;
	};
}

Widest support down to IE5.

/*global html,isHostMethod,canCall*/

/*
Description:
Widest support down to IE5.
*/

/*
Degrades:
IE5, NN4
*/

/*
Author:
David Mark
*/

var attachListener;

if(html && isHostMethod(html, 'addEventListener')) {
	attachListener = function(el, eventType, fn) {
		el.addEventListener(eventType, fn, false);
		return fn;
	};
}
else if(html && isHostMethod(html, 'attachEvent') && canCall) {
	// The "theseObjects" variable must be global
	// or a property of a global object (e.g. a "namespace" object).
	// Stores references to objects used for - this - object in listeners
	jessie.theseObjects = [];

	var theseObjectsIndex = 0;

	attachListener = function(el, eventType, fn) {
		var thisObjectIndex = theseObjectsIndex++;

		// Store reference to object used for - this - in listener
		jessie.theseObjects[thisObjectIndex] = el;

		var listener = function() {
			var e = window.event;
			fn.call(jessie.theseObjects[thisObjectIndex], e);
		};

		el.attachEvent('on'+eventType, listener);

		// Discard unneeded references
		// Prevents circular references with host objects (e.g. the element)
		// Prevents IE leaks related to such circular references
		// No unload event cleanup required
		el = null;

		return listener;
	};
}

attachWindowListener

Choose the most suitable rendition for your project.

Cutting edge. No frames.

/*global window,isHostMethod */

/*
Description:
Cutting edge. No frames.
*/

/*
Degrades:
IE8, IE7, IE6, IE5.5, IE5, IE4, IE3, Opera 7.6
*/

/*
Author:
David Mark
*/

var attachWindowListener;

if(window && isHostMethod(window, 'addEventListener')) {
	attachWindowListener = function(eventType, fn) {

		/*SCAFFOLDING:Start*/
		if (!(/^(load|scroll|resize|orientationchange|unload|beforeunload)$/.test(eventType))) {
			throw new Error('Use attachListener with an element.');
		}
		/*SCAFFOLDING:End*/

		var listener = function(e) {
			fn.call(window, e);
		};

		window.addEventListener(eventType, listener, false);

		return listener;
	};
}

Cutting edge (W3) and Microsoft event model handled. No frames.

/*global global,isHostMethod */

/*
Description:
Cutting edge (W3) and Microsoft event model handled. No frames.
*/

/*
Degrades:
IE4, NN4
*/

/*
Author:
Adam Silver
*/

var attachWindowListener;

if(window && isHostMethod(window, 'addEventListener')) {
	attachWindowListener = function(eventType, fn) {

		/*SCAFFOLDING:Start*/
		if (!(/^(load|scroll|resize|orientationchange|unload|beforeunload)$/.test(eventType))) {
			throw new Error('Use attachListener with an element.');
		}
		/*SCAFFOLDING:End*/

		var listener = function(e) {
			fn.call(window, e);
		};

		window.addEventListener(eventType, listener, false);

		return listener;
	};
} else if(window && isHostMethod(window, 'attachEvent')) {
	attachWindowListener = function(eventType, fn) {

		/*SCAFFOLDING:Start*/
		if (!(/^(load|scroll|resize|orientationchange|unload|beforeunload)$/.test(eventType))) {
			throw new Error('Use attachListener with an element.');
		}
		/*SCAFFOLDING:End*/

		var listener = function() {
			var e = window.event;
			fn.call(window, e);
		};

		window.attachEvent('on'+eventType, listener);

		return listener;
	};
}

cancelDefault

Choose the most suitable rendition for your project.

Cutting edge only

/*global html,isHostMethod */

/*
Description:
Cutting edge only
*/

/*
Degrades:
IE8, IE7, IE6, IE5.5, IE5, IE4, IE3, Opera 7.6
*/

/*
Author:
Adam Silver
*/

var cancelDefault;

if(html && isHostMethod(html, 'addEventListener')) {
	cancelDefault = function(e) {
		e.preventDefault();
	};
}

Cutting edge (W3 compliant) and handles Microsoft event model providing wide support.

/*global isHostMethod,html */

/*
Description:
Cutting edge (W3 compliant) and handles Microsoft event model providing wide support.
*/

/*
Degrades:
IE4, IE3, NN4
*/

/*
Author:
Adam Silver
*/

var cancelDefault;

if(html && isHostMethod(html, 'addEventListener')) {
	cancelDefault = function(e) {
		e.preventDefault();
	};
}
else if(html && isHostMethod(html, 'attachEvent')) {
	cancelDefault = function(e) {
		e.returnValue = false;
	};
}

cancelPropagation

Choose the most suitable rendition for your project.

Cutting edge (W3 compliant)

/*global html,isHostMethod */

/*
Description:
Cutting edge (W3 compliant)
*/

/*
Degrades:
IE8, IE7, IE6, IE5.5, IE5, IE4, IE3, Opera 7.6
*/

/*
Author:
Adam Silver
*/

var cancelPropagation;

if(html && isHostMethod(html, 'addEventListener')) {
	cancelPropagation = function(e) {
		e.stopPropagation();
	};
}

Cutting edge (W3 compliant) and Microsoft event model providing the widest support.

/*global html,isHostMethod */

/*
Description:
Cutting edge (W3 compliant) and Microsoft event model providing the widest support.
*/

/*
Degrades:
IE4, IE3, NN4
*/

/*
Author:
Adam Silver
*/

var cancelPropagation;

if(html && isHostMethod(html, 'addEventListener')) {
	cancelPropagation = function(e) {
		e.stopPropagation();
	};
}
else if(html && isHostMethod(html, 'attachEvent')) {
	cancelPropagation = function(e) {
		e.cancelBubble = true;
	};
}

deferUntilReady

Choose the most suitable rendition for your project.

Cutting edge (W3 compliant). Best used with asset-light documents. No frames or other alternate windows

/*global isHostMethod,global */

/*
Description:
Cutting edge (W3 compliant). Best used with asset-light documents. No frames or other alternate windows
*/

/*
Degrades:
IE8, IE7, IE6, IE5.5, IE5, IE4, IE3
*/

/*
Author:
David Mark
*/

var deferUntilReady;

var readyListenerAttached;

if(isHostMethod(global, "addEventListener")) {
	deferUntilReady = function(fn) {

		/*SCAFFOLDING:Start*/
		if(readyListenerAttached) {
			throw new Error("One too many ready listeners. Use a queue!");
		}
		/*SCAFFOLDING:End*/

		readyListenerAttached = true;

		// Production function starts (and ends) here
		window.addEventListener('load', fn, false);
	};
}

Relies on window.addEventListener and document.addEventListener

Note: No frames or other alternate windows.

Uses DOMContentLoaded as bonus so better for asset-heavy documents

Can use following to get IE8- to work when document is parsed:

	<script type="text/javascript">
		if ('function' == typeof readyListener) {
			window.setTimeout(readyListener, 1);
		}
	</script>
</body>
/*global isHostMethod,global,globalDocument */

/*
Description:
Relies on `window.addEventListener` and `document.addEventListener`

Note: No frames or other alternate windows.

Uses `DOMContentLoaded` as bonus so better for asset-heavy documents

Can use following to get IE8- to work when document is parsed:

		<script type="text/javascript">
			if ('function' == typeof readyListener) {
				window.setTimeout(readyListener, 1);
			}
		</script>
	</body>

*/

/*
Degrades:
IE8, IE7, IE6, IE5.5, IE5, IE4, IE3, Opera 7.6
*/

/*
Author:
David Mark
*/

var deferUntilReady;

var readyListener,
	readyListenerAttached,
	documentIsReady;

if (isHostMethod(global, "addEventListener") && globalDocument && isHostMethod(globalDocument, "addEventListener")) {
	deferUntilReady = function(fn) {

		/*SCAFFOLDING:Start*/
		if (readyListenerAttached) {
			throw new Error('One too many ready listeners. Use a queue!');
		}
		/*SCAFFOLDING:End*/

		readyListenerAttached = true;

		// Production function starts here

		// Run on first fired event
		readyListener = function() {
			if (!documentIsReady) {
				documentIsReady = true;
				fn();
			}
		};

		global.window.addEventListener('load', readyListener, false);
		global.document.addEventListener('DOMContentLoaded', readyListener, false);
	};
}

Handles Microsoft event model

/*global global,isHostMethod */
/*
Description:
Handles Microsoft event model
*/

/*
Degrades:
IE10, IE9, IE4, IE3, NN4, Opera 8+,Chrome, FF, Safari
*/

/*
Author:
David Mark
*/

var deferUntilReady;

var readyListenerAttached;

if(isHostMethod(global, "attachEvent")) {
	deferUntilReady = function(fn) {

		/*SCAFFOLDING:Start*/
		if(readyListenerAttached) {
			throw new Error("One too many ready listeners. Use a queue!");
		}
		/*SCAFFOLDING:End*/
		readyListenerAttached = true;

		// Production function starts (and ends) here
		window.attachEvent('load', fn, false);
	};
}

delegateBlurListener

Choose the most suitable rendition for your project.

For browsers that support focusout i.e. not Firefox

/*global delegateListener,isEventSupported*/

/*
Description:
For browsers that support focusout i.e. not Firefox
*/

/*
Author:
Adam Silver
*/

var delegateBlurListener;

if(delegateListener && isEventSupported('focusout')) {
	delegateBlurListener = function(el, fn, fnDelegate) {
		return delegateListener(el, 'focusout', fn, fnDelegate);
	};
}

For browsers that support focusout i.e. not Firefox, or browsers that can capture (W3 compliant). Wide support.

/*global html,isHostMethod,getEventTarget,delegateListener,isEventSupported */

/*
Description:
For browsers that support focusout i.e. not Firefox, or browsers that can capture (W3 compliant). Wide support.
*/


var delegateBlurListener;


if(delegateListener && isEventSupported('focusout', html)) {
	delegateBlurListener = function(el, fn, fnDelegate) {
		return delegateListener(el, 'focusout', fn, fnDelegate);
	};
} else if(html && isHostMethod(html, 'addEventListener')){
	delegateBlurListener = function(el, fn, fnDelegate) {
		var listener = function(e) {
			var currentTarget = fnDelegate(el, getEventTarget(e));
			if(currentTarget) {
				fn.call(currentTarget, e, currentTarget, el);
			}
		};
		el.addEventListener('blur', listener, true);
		return listener;
	};
}

For browsers that support focusout i.e. not Firefox, or browsers that can capture (W3 compliant). Wide support.

/*global html,isHostMethod,getEventTarget,delegateListener,isEventSupported */

/*
Description:
For browsers that support focusout i.e. not Firefox, or browsers that can capture (W3 compliant). Wide support.
*/


var delegateBlurListener;


if(delegateListener && isEventSupported('focusout', html)) {
	delegateBlurListener = function(el, fn, fnDelegate) {
		return delegateListener(el, 'focusout', fn, fnDelegate);
	};
} else if(html && isHostMethod(html, 'addEventListener')){
	delegateBlurListener = function(el, fn, fnDelegate) {
		var listener = function(e) {
			var currentTarget = fnDelegate(el, getEventTarget(e));
			if(currentTarget) {
				fn.call(currentTarget, e, currentTarget, el);
			}
		};
		el.addEventListener('blur', listener, true);
		return listener;
	};
}

delegateBoundClassNameListener

Relies on jessie.delegateBoundListener, jessie.hasClass, and jessie.getElementParentElement

/*global global,isHostMethod,delegateBoundListener,hasClass,getElementParentElement*/

/*
Description:
Relies on `jessie.delegateBoundListener`, `jessie.hasClass`, and `jessie.getElementParentElement`
*/

/*
Author:
Adam Silver
*/

var delegateBoundClassNameListener;

if(delegateBoundListener && hasClass && getElementParentElement) {
	delegateBoundClassNameListener = function(el, eventType, className, fn, thisObject) {

		var fnDelegate = function(el, target) {
			var currentTarget = target;

			if(el === currentTarget) {
				currentTarget = null;
			}

			// traverse up the tree until we find an element with the class or until we find the delegate/el
			while(currentTarget && (currentTarget !== el) && !hasClass(currentTarget, className)) {
				// if we clicked on the delegate/container/el then set to null
				currentTarget = getElementParentElement(currentTarget);
				if(el === currentTarget) {
					currentTarget = null;
				}
			}

			return currentTarget;
		};

		return delegateBoundListener(el, eventType, fn, fnDelegate, thisObject);
	};
}

delegateBoundListener

Relies on jessie.attachListener and jessie.getEventTarget and Function.prototype.call

/*global attachListener,getEventTarget,canCall */

/*
Description:
Relies on `jessie.attachListener` and `jessie.getEventTarget` and `Function.prototype.call`
*/

/*
Author:
Adam Silver
*/

var delegateBoundListener;

if(attachListener && getEventTarget && canCall) {
	delegateBoundListener = function(el, eventType, fn, fnDelegate, thisObject) {

		var listener = function(e) {

			var currentTarget = fnDelegate(el, getEventTarget(e));

			if(currentTarget) {
				fn.call(thisObject, e, currentTarget);
			}
		};

		return attachListener(el, eventType, listener);
	};
}

delegateBoundQueryListener

Relies on jessie.delegateBoundListener, jessie.query, jessie.isInQuery and jessie.isDecendant

/*global query,delegateBoundListener,isDescendant,isInQuery */

/*
Description:
Relies on `jessie.delegateBoundListener`, `jessie.query`, `jessie.isInQuery` and `jessie.isDecendant`
*/

/*
Author:
Adam Silver
*/

var delegateBoundQueryListener;

if(delegateBoundListener && query && isDescendant) {
	delegateBoundQueryListener = function(el, eventType, selector, fn, thisObject) {

		var fnDelegate = function(el, target) {
			if(isInQuery(target, selector)) {
				return target;
			}
				
			// its not in query so loop through by selector
			// if the target is a child of the element then
			// return that element
			var elements = jessie.query(selector);
			for(var i = 0; i < elements.length; i++) {
				if( isDescendant(elements[i], target) ) {
					return elements[i];
				}
			}
		};

		return delegateBoundListener(el, eventType, fn, fnDelegate, thisObject);
	};
}

delegateListener

Relies on jessie.attachListener and jessie.getEventTarget Function.prototype.call

/*global attachListener,getEventTarget,canCall */

/*
Description:
Relies on `jessie.attachListener` and `jessie.getEventTarget` `Function.prototype.call`
*/

/*
Author:
Adam Silver
*/

var delegateListener;

if(attachListener && getEventTarget && canCall) {
	delegateListener = function(el, eventType, fn, fnDelegate) {
			
		var listener = function(e) {
			var currentTarget = fnDelegate(el, getEventTarget(e));
			if(currentTarget) {
				fn.call(currentTarget, e, currentTarget, el);
			}
		};
		
		return attachListener(el, eventType, listener);
	};
}

delegateQueryListener

Relies on jessie.isNodeInNodeList, jessie.delegateListener, jessie.query and jessie.isDescendant

/*global query,isDescendant,delegateListener,isInQuery */

/*
Description:
Relies on `jessie.isNodeInNodeList`, `jessie.delegateListener`, `jessie.query` and `jessie.isDescendant`
*/

/*
Author:
Adam Silver, Graham Veal
*/

var delegateQueryListener;

if(isNodeInNodeList && delegateListener && query && isDescendant) {
	
	delegateQueryListener = function(el, eventType, selector, fn) {

		function fnDelegate(target) {

			var elements = query(selector),
				i = 0,
				l,
				el;

			if(isNodeInNodeList(target, elements)) {
				return target;
			}

			// its not in query so loop through by selector
			// if the target is a child of the element then
			// return that element

			for( l = elements.length ; i < l; i++ ) {

				el = elements[i];

				if( isDescendant(el, target) ) {
					return el;
				}
			}
		}

		return delegateListener(el, eventType, fn, fnDelegate);
	};
}

delegateTagNameListener

Relies on jessie.delegateListener and jessie.getElementTagName and jessie.getElementParentElement

/*global delegateListener,getElementTagName,getElementParentElement */

/*
Description:
Relies on `jessie.delegateListener` and `jessie.getElementTagName` and `jessie.getElementParentElement`
*/

/*
Author:
Adam Silver
*/

var delegateTagNameListener;

if(delegateListener && getElementTagName) {
	delegateTagNameListener = function(el, eventType, tagName, fn) {

		var fnDelegate = function(el, target) {
			var sourceNode,
				descendant;

			if(getElementTagName(target) === tagName) {
				sourceNode = target;
			} else {
				descendant = getElementParentElement(target);

				while (null !== descendant && descendant !== el) {
					if (getElementTagName(descendant) === tagName) {
						sourceNode = descendant;
						break;
					}
					descendant = getElementParentElement(descendant);
				}
			}
			return sourceNode;
		};

		return delegateListener(el, eventType, fn, fnDelegate);
	};
}

detachBoundListener

Relies on jessie.detachListener

/*global detachListener */

/*
Description:
Relies on `jessie.detachListener`
*/

// could have simply used detachListener
// but this reinforces  that this function
// expects a bound listener

/*
Author:
David Mark
*/

var detachBoundListener;

if(detachListener) {
	detachBoundListener = function(el, eventType, boundListener) {
		return detachListener(el, eventType, boundListener);
	};
}

detachListener

Choose the most suitable rendition for your project.

Cutting edge (W3 compliant)

/*global html,isHostMethod */

/*
Description:
Cutting edge (W3 compliant)
*/

/*
Degrades:
IE8, IE7, IE6, IE5.5, IE5, IE4, IE3, NN4, Opera 7.6
*/

/*
Author:
David Mark
*/

var detachListener;

if(html && isHostMethod(html, 'removeEventListener')) {
	detachListener = function(el, eventType, fn) {
		el.removeEventListener(eventType, fn, false);
	};
}

Cutting egde (W3 compliant) and Microsoft event model handled.

/*global html,isHostMethod */

/*
Description:
Cutting egde (W3 compliant) and Microsoft event model handled.
*/

/*
Degrades:
IE5, NN4
*/

/*
Author:
Adam Silver
*/

var detachListener;

if(html && isHostMethod(html, 'removeEventListener')) {
	detachListener = function(el, eventType, fn) {
		el.removeEventListener(eventType, fn, false);
	};
} else if(html && isHostMethod(html, 'detachEvent')) {
	detachListener = function(el, eventType, fn) {
		el.detachEvent('on'+eventType, fn);
	};
}

detachWindowListener

Choose the most suitable rendition for your project.

Cutting edge (W3 compliant)

/*global window,isHostMethod */

/*
Description:
Cutting edge (W3 compliant)
*/

/*
Degrades:
IE8, IE7, IE6, IE5.5, IE5, IE4, IE3, NN4, Opera 7.6
*/

/*
Author:
David Mark
*/

var detachWindowListener;

if(window && isHostMethod(window, 'removeEventListener')) {
	detachWindowListener = function(eventType, fn) {
		return window.removeEventListener(eventType, fn);
	};
}

Cutting edge (W3 compliant), and handles Microsoft event model

/*global window,isHostMethod */

/*
Description:
Cutting edge (W3 compliant), and handles Microsoft event model
*/

/*
Degrades:
NN4, IE4, IE3
*/

/*
Author:
Adam Silver
*/

var detachWindowListener;

if(window && isHostMethod(window, 'removeEventListener')) {
	detachWindowListener = function(eventType, fn) {
		return window.removeEventListener(eventType, fn);
	};
} else if(window && isHostMethod(window, 'detachEvent')) {
	detachWindowListener = function(eventType, fn) {
		return window.detachEvent('on'+eventType, fn);
	};
}

getEventTarget

Choose the most suitable rendition for your project.

Cutting edge (W3 compliant)

/*global html,isHostMethod */

/*
Description:
Cutting edge (W3 compliant)
*/

/*
Degrades:
IE8, IE7, IE6, IE5.5, IE5, IE4, IE3, Opera 7.6
*/

var getEventTarget;

if(html && isHostMethod(html, 'addEventListener')) {
	getEventTarget = function(e) {
		var target = e.target;
		// Check if not an element (e.g. a text node)
		if (1 != target.nodeType) {
			// Set reference to parent node (which must be an element)
			target = target.parentNode;
		}
		return target;
	};
}

Cutting edge (W3 compliant) where possible, also handles Microsoft event model. Widest support.

/*
Description:
Cutting edge (W3 compliant) where possible, also handles Microsoft event model. Widest support.
*/

/*
See: <a href="https://groups.google.com/forum/#!starred/comp.lang.javascript/uUsSVH7Vcvg">Article</a>
If you will be using a forked rendition to support IE 8-
*/

/*
Degrades:
IE4, IE3, NN4
*/

var getEventTarget;

if(html && isHostMethod(html, 'addEventListener')) {
	getEventTarget = function(e) {
		var target = e.target;
		// Check if not an element (e.g. a text node)
		if (1 != target.nodeType) {
			// Set reference to parent node (which must be an element)
			target = target.parentNode;
		}
		return target;
	};
} else if(html && isHostMethod(html, 'attachEvent')) {
	getEventTarget = function(e) {
		return e.srcElement;
	};
}

<a href="https://groups.google.com/forum/#!starred/comp.lang.javascript/uUsSVH7Vcvg">Article</a> If you will be using a forked rendition to support IE 8-

getEventTargetRelated

Choose the most suitable rendition for your project.

Cutting edge (W3 compliant) Relies on W3C e.relatedTarget

/*global html,isHostMethod */

/*
Description:
Cutting edge (W3 compliant)
Relies on W3C `e.relatedTarget`
*/

/*
Degrades:
IE8, IE7, IE6, IE5.5, IE5, IE4, IE3, Opera 7.6
*/

/*
Author:
David Mark
*/

var getEventTargetRelated;

if(html && isHostMethod(html, 'addEventListener')) {
	getEventTargetRelated = function(e) {
		var target = e.relatedTarget;
		// Check if not an element (e.g. a text node)
		if (1 != target.nodeType) {
			// Set reference to parent node (which must be an element)
			target = target.parentNode;
		}
		return target;
	};
}

Cutting edge (W3 compliant) where possible, also handles Microsoft event model. Wide support.

/*global html,isHostMethod */

/*
Description:
Cutting edge (W3 compliant) where possible, also handles Microsoft event model. Wide support.
*/

/*
Degrades:
IE4, IE3, NN4
*/

/*
Author:
David Mark
*/

var getEventTargetRelated;

if(html && isHostMethod(html, 'addEventListener')) {
	getEventTargetRelated = function(e) {
		var target = e.relatedTarget;
		// Check if not an element (e.g. a text node)
		if (1 != target.nodeType) {
			// Set reference to parent node (which must be an element)
			target = target.parentNode;
		}
		return target;
	};
} else if(html && isHostMethod(html, 'attachEvent')) {
	getEventTargetRelated = function(e) {
		if (e.srcElement == e.fromElement) { return e.toElement; }
		if (e.srcElement == e.toElement) { return e.fromElement; }
		return target;
	};
}

bind

Choose the most suitable rendition for your project.

Relies on Function.prototype.bind

/*global canCall */

/*
Description:
Relies on `Function.prototype.bind`
*/

/*
Degrades:
IE8, IE7, IE6, IE5.5, IE5, IE4, IE3, Chrome 6, Firefox 3.6, Safari 5.1, Opera 11.5
*/

/*
Author:
David Mark
*/

var bind;

if(Function.prototype.bind){
    bind = function(fn, thisObject) {
        return fn.bind.apply(fn, Array.prototype.slice.call(arguments, 1));
    };
}

Relies on Function.prototype.bind and Function.prototype.apply and Array.prototype.slice

/*global canCall */

/*
Description:
Relies on `Function.prototype.bind` and `Function.prototype.apply` and `Array.prototype.slice`
*/

/*
Degrades:
IE5, IE4, IE3
*/

var bind;

if (Function.prototype.bind) {
	bind = function(fn, thisObject) {
		return fn.bind.apply(fn, Array.prototype.slice.call(arguments, 1));
	};
}
else if (canCall && Array.prototype.slice) {
	bind = function(fn, context) {
		var prependArgs = Array.prototype.slice.call(arguments, 2);

		if (prependArgs.length) {
			return function() {
				return fn.apply(context, Array.prototype.concat.apply(prependArgs, arguments));
			};
		}
		return function() {
			return fn.apply(context, arguments);
		};
	};

}

bindDeferred

Relies on Function.prototype.apply, Array.prototype.slice, Array,prototype.concat, window.setTimeOut and window.clearTimeout

/*global canCall,bind,global,isHostMethod */

/*
Description:
Relies on `Function.prototype.apply`, `Array.prototype.slice`,
`Array,prototype.concat`, `window.setTimeOut` and `window.clearTimeout`
*/

/*
Author:
David Mark
*/

var bindDeferred;

if(canCall && Array.prototype.slice && Array.prototype.concat && isHostMethod(global, 'setTimeout')) {
  bindDeferred = function(fn, context, delay) {
    var timeout;
    fn = bind.apply(this, [fn, context].concat(Array.prototype.slice.call(arguments, 3)));
      return function() {
        if (timeout) {
            global.clearTimeout(timeout);
            timeout = 0;
        }
        var args = Array.prototype.slice(arguments, 0);
        timeout = global.setTimeout(function() {
            fn.apply(this, args);
        }, delay);
      };
  };
}

capitalize

Choose the most suitable rendition for your project.

Relies on chartAt

/*
Description:
Relies on `chartAt`
*/

/*
Author:
David Mark
*/

var capitalize;

capitalize = function(text) {
	return text.charAt[0].toUpperCase() + text.slice(1);
};

Avoids string concantenation (for what that's worth). Relies on String.prototype.replace that accepts Function object reference for second argument

/*
Description:
Avoids string concantenation (for what that's worth). Relies on `String.prototype.replace` that accepts Function object reference for second argument
*/

/*
Degrades in:
IE4, NN4
*/

/*
Author:
David Mark
*/

var capitalize;

// Create function scope to hide variables that are exclusive to this function
(function() {

	// Create test function

	var fn = function(n) { return n; };

	// Override String.prototype.toString to return 'n'

	fn.toString = function() {
		return 'n';
	};

	// Ancient browsers will call toString method on second parameter if not a string

	// If...

	if ('n' != 'y'.replace(/./, fn)) {
		capitalize = function(text) {
			return text.replace(/^(.)/, function(s, m) { return m.toUpperCase() });
		};
	}
})();

cloneObject

Needs documenting

/*
Description:
Needs documenting
*/

/*
Author:
David Mark
*/

var cloneObject;

cloneObject = (function() {
	var Fn = function() {};

	return function(o) {
		Fn.prototype = o;
		return new Fn();
	};
})();

createVideo

Browsers taht support HTML5 video

// At very least, need this host method...

/*
Description:
Browsers taht support HTML5 video
*/

if ( 'undefined' != typeof document.createElement ) {

	var video_errored, enhanceVideo = function( elContainer, options ) {

		// Test MIME type (plus optional Codecs)

    	function testType( el, mimeType ) {

    		// Test the MIME type + codec(s)

      		var result = el.canPlayType( mimeType );

      		// If only MIME type specified...

      		if ( -1 == mimeType.indexOf( ';' ) ) {

          		// Empty string or "no" indicates failure

          		return result && result != 'no';
      		}

      		// Codec(s) specified, so require a "probably" to proceed ("maybe" not good enough)

  			return result == 'probably';
    	}


    	// Reduce original VIDEO structure to fallback content

    	function degradeVideo( el ) {

    		// Create array of child nodes

    		var elChildNodes = Array.prototype.slice.call( el.childNodes, 0 );

    		// Loop through child nodes

    		for ( var i = elChildNodes.length; i--; ) {

    			// If a SOURCE element...

    			if ( elChildNodes.tagName.toLowerCase() == 'SOURCE' ) {

    				// Remove it

    				el.removeChild( elChildNodes[i] );

    			} else {

    				// Put it in the container, above the VIDEO element

    				el.parentNode.insertBefore( elChildNodes[i], el )
    			}
    		}

    		// Finally, remove the VIDEO element

    		el.parentNode.removeChild( el );
    	}

    	// Convert plain text to HTML

    	function text2html( text )
    	{
    		return text.replace('&', '&').replace('<', '<').replace('>', '>').replace('"', '"');
    	}

    	// Try to create video element

    	var	el = document.createElement( 'video' );

    	// If created and container features "innerHTML" string property and original structure likely not to work
    	// Or if original structure definitely errored (per the "video_errored" flag)

    	if ( video_errored || ( 'string' == typeof elContainer.innerHTML && ( !el || 'undefined' == typeof el.canPlayType || ( !testType( el, 'video/mp4' ) && !testType( el, 'video/ogg; codecs="theora, vorbis"' ) ) ) ) ) {

    		// Replace the original structure with a Flash object, wrapping a lesser VIDEO element, wrapping an image linked to the MP4 format
			// TODO: Get rid of that OBJECT ID (not used by anything)

    		var html = '<object id="testplayer_api" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="' + options.width + '" height="' + options.height + '" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0" title="' + text2html( options.text ) + '"><param name="movie" value="/video/flowplayer-3.2.7.swf"><param name="allowfullscreen" value="true"><param name="allowscriptaccess" value="always"><param name="quality" value="high"><param name="cachebusting" value="false"><param name="bgcolor" value="#000000"><param name="flashvars" value="config={"playerId":"player","clip":{"url":"/video/' + encodeURIComponent( options.name ) + '.flv", "autoPlay": false },"playlist":[{"url":"/video/test.flv" }]}"><!--[if !IE]>--><object type="application/x-shockwave-flash" data="/video/flowplayer-3.2.7.swf" width="' + options.width + '" height="' + options.height + '" title="' + text2html( options.text ) + '"><param name="allowfullscreen" value="true"><param name="allowscriptaccess" value="always"><param name="quality" value="high"><param name="cachebusting" value="false"><param name="bgcolor" value="#000000"><param name="flashvars" value="config={"playerId":"player","clip":{"url":"/video/test.flv", "autoPlay": false },"playlist":[{"url":"/video/test.flv" }]}"><!--<![endif]-->';

    		// Won't hurt to try again with simplified VIDEO (MP4 only)
    		// NOTE: Probably don't want to bother if either video_errored is set or createElement failed to create a usable VIDEO element

    		html += '<video src="/video/' + text2html( options.name ) + '.m4v" height="' + options.height + '" width="' + options.width + '" poster="/images/' + encodeURIComponent( options.name ) + '.png" onclick="if (\'undefined\' != this.play) { this.play(); }" onerror="degradeVideo( this );"><a href="/video/' + encodeURIComponent( options.name ) + '.m4v"><img src="/images/' + encodeURIComponent( options.poster_overlaid ) + '.png" alt="' + text2html( options.text ) + '" width="' + options.width + '" height="' + options.height + '"></a></video>';

    		html += '<!--[if !IE]>--></object><!--<![endif]--></object>';

    		elContainer.innerHTML = html;
   		}

    	// Discard unneeded host object references

    	el = elContainer = null;
	};
}

deepMixin

Relies on jessie.isOwnProperty

/*global isOwnProperty*/

var deepMixin;

/*
Description:
Relies on `jessie.isOwnProperty`
*/

/*
Degrades:
*/

/*
Author:
Ian Crowther
*/

if(isOwnProperty) {
	deepMixin = function(target, source) {
		for(var property in source) {
			if(!isOwnProperty(target, property)) {
				target[property] = source[property];
			} else {
				deepMixin(target[property], source[property]);
			}
		}
	};
}

every

Choose the most suitable rendition for your project.

Relies on Array.prototype.every

var every;

/*
Description:
Relies on `Array.prototype.every`
*/

if(Array.prototype.every) {
	every = function(arr, iterator, context) {
		return arr.every(iterator, context);
	};
}

Relies on Function.prototype.call and jessie.forEach

/*global canCall,forEach */

/*
Description:
Relies on `Function.prototype.call` and `jessie.forEach`
*/

var every;

if(canCall && forEach) {
	every = function(arr, iterator, context) {
		var result = true;
		// TODO: this is slightly inefficient, as it doesn't break out of the
		// loop when the first `falsy` value is encountered
		forEach(arr, function(value, index, list) {
			result = result && iterator.call(context, value, index, list);
		});

		return !!result;
	};
}

Relies on Array.prototype.every or Function.prototype.call and jessie.forEach which provides the widest support

/*global canCall,forEach */

/*
Description:
Relies on `Array.prototype.every` or `Function.prototype.call` and `jessie.forEach` which provides the widest support
*/

var every;

if(Array.prototype.every) {
	every = function(arr, iterator, context) {
		return arr.every(iterator, context);
	};
} else if(canCall && forEach) {
	every = function(arr, iterator, context) {
		var result = true;
		// TODO: this is slightly inefficient, as it doesn't break out of the
		// loop when the first `falsy` value is encountered
		forEach(arr, function(value, index, list) {
			result = result && iterator.call(context, value, index, list);
		});

		return !!result;
	};
}

forEach

Choose the most suitable rendition for your project.

Uses Array.prototype.forEach

/*
Description:
Uses `Array.prototype.forEach`
*/

var forEach;

if (Array.prototype.forEach) {
	forEach = function(elements, callback, thisObject) {
		elements.forEach(callback, thisObject);
	};
}

Relies on Function.prototype.call for browsers without native forEach

/*global canCall */

/*
Description:
Relies on `Function.prototype.call` for browsers without native forEach
*/

var forEach;

if (canCall) {
	forEach = function(elements, callback, thisObject) {
		for (var i = 0, l = elements.length; i < l; i++) {
			callback.call(thisObject, elements[i], i, elements);
		}
	};
}

Relies on Array.forEach or Function.prototype.call providing greatest browser support

/*global canCall */

/*
Description:
Relies on `Array.forEach` or `Function.prototype.call` providing greatest browser support
*/

var forEach;

if (Array.prototype.forEach) {
	forEach = function(elements, callback, thisObject) {
		elements.forEach(callback, thisObject);
	};
}else if (canCall) {
	forEach = function(elements, callback, thisObject) {
		for (var i = 0, l = elements.length; i < l; i++) {
			callback.call(thisObject, elements[i], i, elements);
		}
	};
}

getDocumentWindow

Choose the most suitable rendition for your project.

Cutting edge. Relies on document.defaultView

var getDocumentWindow;

/*
Description:
Cutting edge. Relies on `document.defaultView`
*/

/*
Degrades:
IE8
*/

getDocumentWindow = (function() {
    if (isHostObjectProperty(document, 'defaultView') && document.defaultView === this) {
        return function(doc) {
          return (doc || document).defaultView;
        };
    }
})();

Uses document.parentWindow where possible, otherwise document.defaultView


var getDocumentWindow;

/*
Description:
Uses `document.parentWindow` where possible, otherwise `document.defaultView`
*/

/*
Degrades:
IE3
*/

getDocumentWindow = (function() {
    if (isHostObjectProperty(document, 'parentWindow')) {
        return function(doc) {
            return (doc || document).parentWindow;
        };
    }

    if (isHostObjectProperty(document, 'defaultView') && document.defaultView === this) {
        return function(doc) {
            return (doc || document).defaultView;
        };
    }
})();

getGeoLocation

Relies on 'window.navigator.geolocation.getCurrentPosition'

/*global isHostMethod, isHostObjectProperty */

var getGeoLocation;

/*
Description:
Relies on 'window.navigator.geolocation.getCurrentPosition'
*/

/*
Degrades:
IE8
*/

// If required host object and methods are present...

if (isHostObjectProperty(window, 'navigator') && isHostObjectProperty(window.navigator, 'geolocation') && isHostMethod(window.navigator.geolocation, 'getCurrentPosition')) {

	// Wall off saved position and callback in module

	(function() {
		var savedPosition;

		function doCallback(position, callback, thisObject) {
			callback.call(thisObject || global, {
				latitude: position.coords.latitude,
				longitude: position.coords.longitude
			}, position);
		}

		// Refresh defaults to true, pass false to use cached result (if any)

		getGeoLocation = function(callback, thisObject, refresh) {

			// If previously cached and requested NOT to refresh...

			if (savedPosition && refresh !== false) {

				// Call back with cached result

				doCallback(savedPosition, callback, thisObject);
			} else {

				// Update position (asynchronous operation)

				window.navigator.geolocation.getCurrentPosition(function(position) {

					// Cache result

					savedPosition = position;

					// Call back with new position

					doCallback(position, callback, thisObject);
				});
			}
		};
	})();
}

getInputValue

getInputValue

/*global */

var getInputValue;

/*
Description:
getInputValue



*/

getInputValue = function(elInput, defaultValue) {
	return elInput[defaultValue ? 'defaultValue' : 'value'];
};

getNextElementSibling

Choose the most suitable rendition for your project.

Relies on el.nextElementSibling

/*global globalDocument */

/*
 Description:
 Relies on `el.nextElementSibling`
 */

/*
 Degrades:
IE 5.5, IE 6, IE 7, IE8, FF 3.0
 */

/*
 Author:
 Ben Chidgey
 */

var getNextElementSibling;

if (globalDocument && !!globalDocument.getElementsByTagName('head')[0].nextElementSibling) {

	getNextElementSibling = function (el) {
		return el.nextElementSibling;
	};
}

Relies on el.nextSibling

/*global globalDocument */

/*
 Description:
 Relies on `el.nextSibling`
 */

/*
 Author:
 Ben Chidgey
 */

var getNextElementSibling;

if (globalDocument && !!globalDocument.getElementsByTagName('head')[0].nextSibling) {

	getNextElementSibling = function (el) {

		do {
			el = el.nextSibling;
		} while (el && el.nodeType !== 1);

		return el;
	};
}

getOptionValue

Wide support

/*
Description:
Wide support
*/

var getOptionValue;

if (isHostMethod(html, hasAttribute)) {
    getOptionValue = function(o) {
        return (o.value || (hasAttribute( o, 'value' ) ? o.value : o.text));
    };
}

getPreviousElementSibling

Choose the most suitable rendition for your project.

Relies on el.previousElementSibling

/*global globalDocument */

/*
 Description:
 Relies on `el.previousElementSibling`
 */

/*
 Degrades:
IE 5.5, IE 6, IE 7, IE8, FF 3.0
 */

/*
 Author:
 Ben Chidgey
 */

var getPreviousElementSibling;

if (globalDocument && !!globalDocument.body.previousElementSibling) {

	getPreviousElementSibling = function (el) {
		return el.previousElementSibling;
	};
}

Relies on el.previousSibling

/*global globalDocument */

/*
Description:
Relies on `el.previousSibling`
*/

/*
 Author:
 Ben Chidgey
 */

var getPreviousElementSibling;

if (globalDocument && !!globalDocument.body.previousSibling) {

	getPreviousElementSibling = function (el) {

		do {
			el = el.previousSibling;
		} while (el && el.nodeType !== 1);

		return el;
	};
}

getViewportScrollPosition

Choose the most suitable rendition for your project.

Cutting edge

/*global global*/

/*
Description:
Cutting edge
*/

/*
Author:
David Mark
*/

var getViewportScrollPosition;

if('number' == typeof window.pageXOffset && 'number' == typeof window.pageYOffset ) {
	/*
	Many "standards-based" browsers feature this non-standard property. No ambiguity about what this window property means
	 */
	getViewportScrollPosition = function() {
		return [window.pageXOffset, window.pageYOffset];
	};
}

Widest support

/*global global, html, globalDocument */

/*
Description:
Widest support
*/

/*
Degrades:
IE5.5
*/

/*
Author:
David Mark
*/

var getViewportScrollPosition;

(function() {

	var getRoot;

	if('number' == typeof window.pageXOffset) {
		/*
		Many "standards-based" browsers feature this non-standard property. No ambiguity about what this window property means
		 */
		getViewportScrollPosition = function(win) {
			if (!win) {
				win = window;
			}
			return [win.pageXOffset, win.pageYOffset];
		};

	} else if(html && 'number' == typeof html.scrollTop) {

		if (typeof globalDocument.compatMode == 'string') {
			getRoot = function(win /* window */) {
				var doc = win.document,
					html = doc.documentElement,
					compatMode = doc.compatMode;

				return compatMode.toLowerCase().indexOf('css') == -1 ? doc.body : html;
			};
		}

		if (getRoot) {
			getViewportScrollPosition = function(win /* window */) {
				if (!win) {
					win = window;
				}
				var root = getRoot(win);
				return [root.scrollLeft, root.scrollTop];
			};
		}
	}
})();

getViewportSize

Choose the most suitable rendition for your project.

Cutting edge, will include space occupied by scroll bars. Fine for working out how to center a dialog for example.

/*global global */

/*
Description:
Cutting edge, will include space occupied by scroll bars. Fine for working out how to center a dialog for example.
*/

/*
Degrades:
IE8
*/

/*
Author:
David Mark
*/

var getViewportSize;

if (typeof global.innerWidth == 'number') {
	getViewportSize = function(win /* window */) {
		if (!win) {
			win = window;
		}
		return [win.innerWidth, win.innerHeight];
	};
}

Widest support. May include space occupid by scrol bar. So don't use to attempt to cover the viewport, which is ill-advised.

/*global global, globalDocument, html*/

/*
Description:
Widest support. May include space occupid by scrol bar. So don't use to attempt to cover the viewport, which is ill-advised.
*/

/*
Degrades:
IE5.5
*/

var getViewportSize;

(function() {

	var getRoot;

	if (typeof global.innerWidth == 'number') {
		getViewportSize = function(win /* window */) {
			if (!win) {
				win = window;
			}
			return [win.innerWidth, win.innerHeight];
		};
	} else  {
		if (typeof globalDocument.compatMode == 'string') {
			getRoot = function(win /* window */) {
				var doc = win.document,
					html = doc.documentElement,
					compatMode = doc.compatMode;

				return compatMode.toLowerCase().indexOf('css') == -1 ? doc.body : html;
			};

		// The following fork must be deferred which is not yet implemented in jessie. This fork is for a rendition that works in ie5 and under so isn't particularly necessary anyway
		} else if (typeof html.clientWidth == 'number') {
			getRoot = function(win /* window */) {
				var doc = win.document,
					html = doc.documentElement;

				return html.clientWidth === 0 ? doc.body : html;
			};
		}

		if (getRoot) {
			getViewportSize = function(win /* window */) {
				if (!win) {
					win = window;
				}
				var root = getRoot(win);
				return [root.clientWidth, root.clientHeight];
			};
		}
	}

})();

htmlToNodes

Wide support. 'jessie.setHtml' and 'jessie.createElement'

var htmlToNodes;

/*
Description:
Wide support. 'jessie.setHtml' and 'jessie.createElement'
*/

if (setTempHtml && createElement) {
    htmlToNodes = function(html, docNode) {
        var c;

        elTemp = createElement('div', docNode);

        if (elTemp) {
            setTempHtml(html);
            c = elTemp.childNodes;
            elTemp = null;
        }

        return c;
    };
}

inherit

Wide support

/*global cloneObject*/

/*
Description:
Wide support
*/

/*
Author:
David Mark
*/

var inherit;

if(cloneObject) {
	inherit = (function() {
		return function(fnSub, fnSuper) {
			// Set "sub" constructor prototype to a clone of the "super" constructor prototype
			fnSub.prototype = cloneObject(fnSuper.prototype);

			// Store this handy reference so methods can call on their super-predecessors
			fnSub.superConstructor = fnSuper;

			// Restore stepped on constructor property
			fnSub.prototype.constructor = fnSub;
		};
	})();
}

inheritAndFillin

Wide support

/*global inherit, fillin */

var inheritAndFillin;

/*
Description:
Wide support
*/

if (inherit && fillin) {
	inheritAndFillin = function(sub, super, fillin) {
		inherit(sub, super);
		fillin(sub.prototype, fillin);
	};
}

inheritAndMixin

Wide support

/*global inherit, mixin */

var inheritAndMixin;

/*
Description:
Wide support
*/

if (inherit && mixin) {
	inheritAndMixin = function(sub, super, mixin) {
		inherit(sub, super);
		mixin(sub.prototype, mixin);
	};
}

isEventSupported

Wide support

/*global createElement,isHostMethod */

/*
Description:
Wide support
*/

var isEventSupported;
var supportedEvents = {};

if (createElement) {
	isEventSupported = function(eventName, el) {
		eventName = 'on' + eventName;
		var eventKey = eventName + (el && el.tagName || '');

		if (typeof supportedEvents[eventKey] == 'undefined') {
			supportedEvents[eventKey] = true;
			el = el || createElement('div');
			if (el && isHostMethod(el, 'setAttribute')) {
				if (typeof el[eventName] == 'undefined') {
					el.setAttribute(eventName, 'window.alert(" ");');
					supportedEvents[eventKey] = isHostMethod(el, eventName);
				}
			}
		}
		return supportedEvents[eventKey];
	};
}

isOwnProperty

Choose the most suitable rendition for your project.

Cutting edge. Relises on Object.prototype.hasOwnProperty

var isOwnProperty;

/*
Description:
Cutting edge. Relises on `Object.prototype.hasOwnProperty`
*/

/*
Author:
David Mark
*/

if(Object.prototype.hasOwnProperty) {
	isOwnProperty = function(o, p) {
		return o.hasOwnProperty(p);
	};
}

Wide support.

var isOwnProperty;

/*
Description:
Wide support.
*/

/*
Author:
David Mark
*/

isOwnProperty = function(o, p) {
	var prop = o.constructor.prototype[p];
	return typeof prop == 'undefined' || prop !== o[p];
};

Wide support. Cutting edge where possible.

var isOwnProperty;

/*
Description:
Wide support. Cutting edge where possible.
*/

/*
Author:
David Mark
*/

if(Object.prototype.hasOwnProperty) {
	isOwnProperty = function(o, p) {
		return o.hasOwnProperty(p);
	};
}
else {
	isOwnProperty = function(o, p) {
		var prop = o.constructor.prototype[p];
		return typeof prop == 'undefined' || prop !== o[p];
	};
}

mixin

Relies on jessie.isOwnProperty

/*global isOwnProperty */

var mixin;

/*
Description:
Relies on `jessie.isOwnProperty`
*/

/*
Degrades:
*/

// TODO: Test the old iteration bug with shadowed built-in properties (e.g. toString)
//       Need another rendition that handles that bug

if(isOwnProperty) {
	mixin = function(target, source) {
		for(var property in source) {
			if(isOwnProperty(source, property)) {
				target[property] = source[property];
			}
		}
	};
}

parseJson

Choose the most suitable rendition for your project.

Relies on window.JSON.parse.

Note: could also use JSON2 lib to 'polyfill'

/*global global,isHostMethod,isHostObjectProperty */

/*
Description:
Relies on `window.JSON.parse`.

Note: could also use JSON2 lib to 'polyfill'
*/

/*
Author:
Adam Silver
*/

var parseJson;

if(isHostObjectProperty(global, "JSON") && isHostMethod(JSON, "parse")) {
	parseJson = function(str) {
		return JSON.parse(str);
	};
}

For browsers without window.JSON.parse

/*global global,isHostMethod */

/*
Description:
For browsers without `window.JSON.parse`
*/

/*
Author:
David Mark
*/

var parseJson;

parseJson = function(str) {
	return (new Function('return (' + str + ')'))();
};

Relies on window.JSON.parse or the Function constructor providing greatest browser support

/*global global,isHostMethod */

/*
Description:
Relies on `window.JSON.parse` or the `Function` constructor providing greatest 
browser support
*/

/*
Author:
Adam Silver
*/

var parseJson;

if(isHostObjectProperty(global, "JSON") && isHostMethod(JSON, "parse")) {
	parseJson = function(str) {
		return JSON.parse(str);
	};
} else {
	parseJson = function(str) {
		return (new Function('return (' + str + ')'))();
	};
}

replaceLocation

Wide support

/*
Description:
Wide support
*/

var replaceLocation;

if (isHostObjectProperty(window, 'location') && isHostMethod(window.location, 'replace')) {
    replaceLocation = function(uri) {
        window.location.replace(uri);
    };
}

setInputValue

Wide support

/*global */

var setInputValue;

/*
Description:
Wide support
*/

setInputValue = function(elInput, value) {
    elInput.value = value;
};

setViewportScrollPosition

Relies on window.scrollTo

/*global isHostMethod,global */

/*
Description:
Relies on `window.scrollTo`
*/

var setViewportScrollPosition;

if(isHostMethod(global, "scrollTo")) {
	setViewportScrollPosition = function(x, y) {
		window.scrollTo(x, y);
	};
}

some

Choose the most suitable rendition for your project.

Cutting edge. Relies on Array.prototype.some.

/*
Description:
Cutting edge. Relies on `Array.prototype.some`.
*/

/*
Degrades:
IE8
*/

/*
Author:
Graham Veal
*/

var some;

if(Array.prototype.some) {
	some = function(arr, iterator, context) {
		return arr.some(iterator, context);
	};
}

Wide support.

/*global */

/*
Description:
Wide support.
*/

/*
Author:
Graham Veal
*/

var some;

some = function(arr, iterator, context) {

	var i = 0,
		l = arr.length;

	context = context || arr;

	for( ; i < l; i++ ){

		if( iterator.call(context, arr[ i ], i, arr) ){
			return true;
		}
	}

	return false;
};

Wide support, cutting edge where possible

/*
Description:
Wide support, cutting edge where possible
*/

/*
Author:
Adam Silver
*/

var some;

if(Array.prototype.some) {
	some = function(arr, iterator, context) {
		return arr.some(iterator, context);
	};
} else {
	some = function(arr, iterator, context) {

		var i = 0,
			l = arr.length;

		context = context || arr;

		for( ; i < l; i++ ){

			if( iterator.call(context, arr[ i ], i, arr) ){
				return true;
			}
		}

		return false;
	};
}

toArray

Choose the most suitable rendition for your project.

Wide support, no cutting edge

/*
Description:
Wide support, no cutting edge
*/

/*
Author:
David Mark
*/

var toArray;

toArray = function(a) {
	var result = [];
	for (var i = 0, l = a.length; i < l; i++) {
		result[i] = a[i];
	}
	return result;
};

Cutting edge, relies on Array.prototype.slice

/*global canCall */

/*
Description:
Cutting edge, relies on `Array.prototype.slice`
*/

/*
Author:
David Mark
*/

var toArray;

if (canCall && Array.prototype.slice) {
	try {
		Array.prototype.slice.call(arguments, 0);
		toArray = function(a) {
			return Array.prototype.slice.call(a, 0);
		};
	} catch(e) {}
}

Cutting edge where possible, wide support

/*global canCall */

/*
Description:
Cutting edge where possible, wide support
*/

/*
Author:
Graham Veal
*/

var toArray;

if (canCall && Array.prototype.slice) {

	try {

		Array.prototype.slice.call(arguments, 0);

		toArray = function(a) {
			return Array.prototype.slice.call(a, 0);
		};

	} catch(e) {}

}

if (!toArray) {

	toArray = function(a) {

		var result = [],
			i = 0,
			l = a.length;

		for ( ; i < l; i++) {

			result[i] = a[i];
		}

		return result;
	};
}

trimString

Choose the most suitable rendition for your project.

Cutting edge. Relies on 'String.prototype.trim'

/*global  */

var trimString;

/*
Description:
Cutting edge. Relies on 'String.prototype.trim'
*/

/*
Degrades:
IE8
*/

if (String.prototype.trim) {
	trimString = function(s) {
		return s.trim();
	};
}

Wide support. Relies on String.prototype.replace

/*global */

var trimString;

/*
Description:
Wide support. Relies on `String.prototype.replace`
*/

/*
Degrades in:
Not sure yet
*/

trimString = function(s) {
	return s.replace(/^\s+|\s+$/g, '');
};

Wide support, cutting edge where possible

/*global */

var trimString;

/*
Description:
Wide support, cutting edge where possible
*/

if (String.prototype.trim) {
	trimString = function(s) {
		return s.trim();
	};
} else {
	trimString = function(s) {
		return s.replace(/^\s+|\s+$/g, '');
	};
}

Not sure what this is?

/*global */

var trimString;

/*
Description:
Not sure what this is?
*/

trimString = function(s) {
	return s.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
};

Not sure what this is?

/*global */

var trimString;

/*
Description:
Not sure what this is?
*/

trimString = function(s) {
	return s.replace(/^\s+/, '').replace(/\s+$/, '');
};

undelegateListener

Relies on jessie.detachListener

/*global detachListener */

/*
Description:
Relies on `jessie.detachListener`
*/

/*
Author:
Adam Silver
*/

var undelegateListener;

if(detachListener) {
	undelegateListener = function(el, eventType, delegateListener) {
		return detachListener(el, eventType, delegateListener);
	};
}

undelegateQueryListener

Relies on jessie.undelegateListener

/*global undelegateListener */

/*
Description:
Relies on `jessie.undelegateListener`
*/

/*
could have simply used detachListener
but this reinforces  that this function
expects a delegate listener which was returned
when it was attached
*/

/*
Author:
Adam Silver
*/

var undelegateQueryListener;

if(undelegateListener) {
	undelegateQueryListener = function(el, eventType, listener) {
		return undelegateListener(el, eventType, listener);
	};
}

urlDecode

Wide support

/*
Description:
Wide support
*/

var urlDecode;

if (typeof decodeURIComponent != 'undefined' && String.prototype.replace) {

    //

    urlDecode = (function() {

        // Create function to encode string

        var fn = function(s) {
            // TODO: Handle CR/LF issues (see urlEncode)

            return decodeURIComponent(s.replace(/\+/g, '%20'));
        };

        // If passes initial test...

        if (fn('%0D%0A+%0D%0A') == '\n \r') {

            // Return function reference

            return fn; // Function
        }
    })();
}

urlEncode

Wide support

/*
Description:
Wide support
*/

var urlEncode;

// If required language features present...

if (typeof encodeURIComponent != 'undefined' && String.prototype.replace) {

    //

    urlEncode = (function() {

        // Create function to encode string

        var fn = function(s) {
            return encodeURIComponent(s).replace( /%20/g, '+' ).replace( /(.{0,3})(%0A)/g, function(m, a, b) {
                return a + (a == '%0D' ? '' : '%0D') + b;
            }).replace( /(%0D)(.{0,3})/g, function( m, a, b ) {
                return a + (b == '%0A' ? '' : '%0A') + b;
            });
        };

        // If passes initial test...

        if (fn('\n \r') == '%0D%0A+%0D%0A') {

            // Return function reference

            return fn; // Function
        }
    })();
}

getYearWeekWeekday

Wide support


var getYearWeekWeekday;

/*
Description:
Wide support
*/

getYearWeekWeekday = function(y, m, d) { // ISO 8601 WkNo. m=1..12

    // Based on work by Dr JR Stockton (http://www.merlyn.demon.co.uk/)

    var ms1d = 864e5, ms7d = 7 * ms1d;
    var DC3 = Date.UTC( y, m - 1, d + 3 ) / ms1d;   // an Absolute Day Number
    var DoW = 1 + ( DC3 + 7777777 ) % 7;
    var AWN = Math.floor( DC3 / 7 );                // an Absolute Week Number
    var Wyr = new Date( AWN * ms7d ).getUTCFullYear();

    return [Wyr, AWN - Math.floor(Date.UTC(Wyr, 0, 7) / ms7d) + 1, DoW]; // Array
};