﻿/* getElementsByClassName
	function by Crisp
	http://crisp.tweakblogs.net/blog/getelementsbyclassname-re-re-re-visited.html
*/
var getElementsByClassName = function() 
{ 
    // native 
    if (document.getElementsByClassName) 
    { 
        return function(className, nodeName, parentElement) 
        { 
            var s = (parentElement || document).getElementsByClassName(className); 

            if (nodeName && nodeName != '*') 
            { 
                nodeName = nodeName.toUpperCase(); 
                return Array.filter(s, function(el) { return el.nodeName == nodeName; }); 
            } 
            else 
                return [].slice.call(s, 0); 
        } 
    } 

    // xpath 
    if (document.evaluate) 
    { 
        return  function(className, nodeName, parentElement) 
        { 
            if (!nodeName) nodeName = '*'; 
            if (!parentElement) parentElement = document; 

            var results = [], s, i = 0, element; 

            s = document.evaluate( 
                ".//" + nodeName + "[contains(concat(' ', @class, ' '), ' " + className + " ')]", 
                parentElement, 
                null, 
                XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, 
                null 
            ); 

            while ((element = s.snapshotItem(i++))) 
                results.push(element); 

            return results; 
        } 
    } 

    // generic 
    return function(className, nodeName, parentElement) 
    { 
        if (!nodeName) nodeName = '*'; 
        if (!parentElement) parentElement = document; 

        var results = [], s, i = 0, element; 
        var re = new RegExp('(^|\\s)' + className + '(\\s|$)'), elementClassName; 

        s = parentElement.getElementsByTagName(nodeName); 

        while ((element = s[i++])) 
        { 
            if (    (elementClassName = element.className) && 
                (elementClassName == className || re.test(elementClassName)) 
            ) 
                results.push(element); 
        } 

        return results; 
    } 
}();