有没有一种方法可以;“热插拔”;浏览器中的JavaScript代码?

有没有一种方法可以;“热插拔”;浏览器中的JavaScript代码?,javascript,debugging,frameworks,Javascript,Debugging,Frameworks,是否有任何工具可以让您在执行网页时“热交换”JavaScript内容 我正在寻找类似HotSpot为Java所做的事情,一种不用重新加载整个页面就可以“热部署”新JS代码的方法 外面有类似的东西吗 在人们不理解“热插拔”时进行澄清,如锁所示: “热插拔”是指允许我更改页面本身及其.js文件中包含的部分代码 然后,这个框架将自动或通过我的终端的指示检测更改,并动态地重新加载代码,避免新的服务器端post(重新加载) 这种方法将简化调试和错误修复,因为您不需要重新加载页面并从头开始交互。如果您想对整

是否有任何工具可以让您在执行网页时“热交换”JavaScript内容

我正在寻找类似HotSpot为Java所做的事情,一种不用重新加载整个页面就可以“热部署”新JS代码的方法

外面有类似的东西吗

在人们不理解“热插拔”时进行澄清,如锁所示:

“热插拔”是指允许我更改页面本身及其.js文件中包含的部分代码

然后,这个框架将自动或通过我的终端的指示检测更改,并动态地重新加载代码,避免新的服务器端post(重新加载)


这种方法将简化调试和错误修复,因为您不需要重新加载页面并从头开始交互。

如果您想对整个JavaScript文件执行此操作,请参阅类似的内容,您应该能够了解基本的想法。

我不熟悉HotSport,但是如果你说的是动态加载JavaScript,是的,你可以这样做。允许您这样做,以及、、和,我相信大多数其他框架也可以这样做。您也可以使用。

我相信这里没有太多人知道您所说的热插拔是什么意思 但正如大师所言,mootools允许, 如果你不太信任mootools,那么jquery也有同样的插件 如果你不需要框架,你可以通过dom添加这些脚本

但是我确信你不允许改变你已经定义的头部脚本 因为任何通过DOM动态添加的脚本都只是主体级的(有趣的想法:)

我编写了以下bookmarklet:

function reload(){var scripts=document.getElementsByTagName("script");var head=document.getElementsByTagName("head")[0];var newScripts=[];var removeScripts=[];for(var i=0;i<scripts.length;i++){var parent=scripts[i].parentNode;if(parent==head&&scripts[i].src){var newScript={};newScript.src=scripts[i].src;newScript.innerHTML=scripts[i].innerHTML;newScripts.push(newScript);removeScripts.push(scripts[i]);}}for(var i=0;i<removeScripts.length;i++){head.removeChild(removeScripts[i]);}for(var i=0;i<newScripts.length;i++){var script=document.createElement("script");script.src=newScripts[i].src;script.type="text/javascript";script.innerHTML=newScripts[i].innerHTML;head.appendChild(script);}}

function reload(){var scripts=document.getElementsByTagName(“script”);var head=document.getElementsByTagName(“head”)[0];var newScripts=[];var removeScripts=[];for(var i=0;i因为我有一个类似的问题要解决,所以我为热交换javascript、css和图像文件编写了一个小的js库。这当然是github上的开源软件:

希望能有帮助

更新:我已在此处附上完整的库源代码。要使用它,只需将内容复制到文件(例如:hotswap.js)中,然后将脚本标记插入您的网站,如下所示:

<script src="hotswap.js"></script>
完整来源(0.2.0版):

我不得不删除所有评论,使其低于30000字符的回答限制。 我知道内联html+css很难看,但我想把它保存在一个.js文件中

(function() {
    var root = this;
    var previousHotswap = root.hotswap;
    var hotswap = function()
    {
        if (!(this instanceof hotswap))
        {
            return new hotswap();
        }
        else
        {
            return this;
        }
    };
    root.hotswap = hotswap();
    hotswap.prototype.VERSION = '0.2.0';
    hotswap.prototype.RND_PARAM_NAME = 'hs982345jkasg89zqnsl';
    hotswap.prototype.FILE_REMOVAL_DELAY = 400;
    hotswap.prototype.CSS_HTML_PREFIX = 'hs982345jkasg89zqnsl';
    hotswap.prototype._prefix = false;
    hotswap.prototype._prefixCache = [];
    hotswap.prototype._guiCache = {};
    hotswap.prototype._guiGuiRefreshInterval = null;
    hotswap.prototype._guiHtml = '' +
        '<style type="text/css">'+
        '    #PREFIX'+
        '    {'+
        '        display: block;'+
        '        position: fixed;'+
        '        top: 20%;/*distance from top*/'+
        '        right: 0;'+
        '        z-index: 99999;'+
        '        width: 20em;'+
        '        height: auto;'+
        '        color: black;'+
        '        background-color: #666666;'+
        '        font-family: Verdana, sans-serif;'+
        '        font-size: 0.8em;'+
        '        -webkit-box-shadow: 0 0px 0.3em 0.1em #999999;'+
        '        -moz-box-shadow: 0 0px 0.3em 0.1em #999999;'+
        '        box-shadow: 0 0px 0.3em 0.1em #999999;'+
        '    }'+
        '    #PREFIX.mini'+
        '    {'+
        '        width: 2.9em;'+
        '        height: 2.9em;'+
        '        overflow:hidden;'+
        '    }'+
        '    #PREFIX.mini .PREFIX-header input, #PREFIX.mini .PREFIX-list, #PREFIX.mini .PREFIX-footer'+
        '    {'+
        '        display:none;'+
        '    }'+
        '        #PREFIX.mini .PREFIX-header div'+
        '    {'+
        '        display: block;'+
        '        width: 100%;'+
        '        height: 100%;'+
        '    }'+
        '    #PREFIX input'+
        '    {'+
        '        font-size: 1.0em;'+
        '        border: 0.1em solid #999999;'+
        '        border-radius: 0.2em;'+
        '        padding: 0.2em 0.1em;'+
        '        }'+
        '    #PREFIX .PREFIX-header'+
        '    {'+
        '        height: 2.4em;'+
        '        overflow:hidden;'+
        '        padding: 0.4em;'+
        '        color: white;'+
        '        background-color: black;'+
        '        }'+
        '    #PREFIX .PREFIX-header input'+
        '    {'+
        '        width: 83.5%;'+
        '        height: 1.6em;'+
        '    }'+
        '    #PREFIX .PREFIX-header div'+
        '    {'+
        '        position: absolute;'+
        '        top:0;'+
        '        right:0;'+
        '        width: 14.5%;'+
        '        height: 1.6em;'+
        '        line-height: 1.4em;'+
        '        text-align: center;'+
        '        font-size: 2em;'+
        '        font-weight: bold;'+
        '        cursor: pointer;'+
        '    }'+
        '    #PREFIX .PREFIX-header div:hover'+
        '    {'+
        '        background-color: #444444;'+
        '    }'+
        '    #PREFIX .PREFIX-list'+
        '    {'+
        '        width: 100%;'+
        '        height: 22em;'+
        '        overflow: auto;'+
        '    }'+
        '    #PREFIX ul'+
        '    {'+
        '        list-style-type: none;'+
        '        list-style-position: inside;'+
        '        padding: 0;'+
        '        margin: 0.5em 0.5em 1.2em 0.5em;'+
        '    }'+
        '    #PREFIX ul li'+
        '    {'+
        '        margin: 0.3em;'+
        '        padding: 0.5em 0.5em;'+
        '        color: white;'+
        '        background-color: #717171;'+
        '        font-size: 0.9em;'+
        '        line-height: 1.5em;'+
        '        cursor: pointer;'+
        '    }'+
        '    #PREFIX ul li:hover'+
        '    {'+
        '        background-color: #797979;'+
        '    }'+
        '    #PREFIX ul li.template'+
        '    {'+
        '        display: none;'+
        '    }'+
        '    #PREFIX ul li.active'+
        '    {'+
        '        background-color: black;'+
        '    }'+
        '    #PREFIX ul li.PREFIX-headline'+
        '    {'+
        '        color: white;'+
        '        background-color: transparent;'+
        '        text-align: center;'+
        '        font-weight: bold;'+
        '        cursor: default;'+
        '    }'+
        '    #PREFIX .PREFIX-footer'+
        '    {'+
        '        padding: 0;'+
        '        margin:0;'+
        '        background-color: #444444;'+
        '    }'+
        '    #PREFIX .PREFIX-footer ul'+
        '    {'+
        '        margin: 0;'+
        '        padding: 0.5em;'+
        '    }'+
        '    #PREFIX .PREFIX-footer ul li'+
        '    {'+
        '        color: white;'+
        '        background-color: black;'+
        '        font-size: 1.0em;'+
        '        border-radius: 0.5em;'+
        '        text-align: center;'+
        '        height: 2.2em;'+
        '        line-height: 2.2em;'+
        '    }'+
        '    #PREFIX .PREFIX-footer ul li input.PREFIX-seconds'+
        '    {'+
        '        text-align: center;'+
        '        width: 2em;'+
        '    }'+
        '    #PREFIX .PREFIX-footer ul li:hover'+
        '    {'+
        '        background-color: #222222;'+
        '        }'+
        '    #PREFIX .PREFIX-footer ul li.inactive'+
        '    {'+
        '        background-color: #666666;'+
        '        cursor: default;'+
        '    }'+
        '    </style>'+
        '    <div id="PREFIX" class="mini">'+
        '        <div class="PREFIX-header">'+
        '            <input id="PREFIX-prefix" placeholder="prefix" type="text" name="" />'+
        '            <div id="PREFIX-toggle">H</div>'+
        '        </div>'+
        '        <div class="PREFIX-list">'+
        '            <ul id="PREFIX-css">'+
        '                <li class="PREFIX-headline">CSS</li>'+
        '                <li class="template"></li>'+
        '            </ul>'+
        '            <ul id="PREFIX-js">'+
        '                <li class="PREFIX-headline">JS</li>'+
        '                <li class="template"></li>'+
        '            </ul>'+
        '            <ul id="PREFIX-img">'+
        '                <li class="PREFIX-headline">IMG</li>'+
        '                <li class="template"></li>'+
        '            </ul>'+
        '        </div>'+
        '        <div class="PREFIX-footer">'+
        '            <ul>'+
        '                <li id="PREFIX-submit-selected">refresh selected</li>'+
        '                <li id="PREFIX-submit-start">refresh every <input  class="PREFIX-seconds" type="text" value="1" /> sec.</li>'+
        '                <li id="PREFIX-submit-stop" class="inactive">stop refreshing</li>'+
        '                <li id="PREFIX-submit-refresh-list">refresh list</li>'+
        '            </ul>'+
        '        </div>'+
        '    </div>';
    var
        xGetElementById       = function(sId){ return document.getElementById(sId) },
        xGetElementsByTagName = function(sTags){ return document.getElementsByTagName(sTags) },
        xAppendChild          = function(parent, child){ return parent.appendChild(child) },
        xCloneNode            = function(node){ return document.cloneNode(node) },
        xCreateElement        = function(sTag){ return document.createElement(sTag) },
        xCloneNode            = function(ele, deep){ return ele.cloneNode(deep) },
        xRemove = function(ele)
        {
            if( typeof ele.parentNode != "undefined" && ele.parentNode )
            {
                ele.parentNode.removeChild( ele );
            }
        },
        xAddEventListener = function(ele, sEvent, fn, bCaptureOrBubble)
        {
            if( xIsEmpty(bCaptureOrBubble) )
            {
                bCaptureOrBubble = false;
            }
            if (ele.addEventListener)
            {
                ele.addEventListener(sEvent, fn, bCaptureOrBubble);
                return true;
            }
            else if (ele.attachEvent)
            {
                return ele.attachEvent('on' + sEvent, fn);
            }
            else
            {
                ele['on' + sEvent] = fn;
            }
        },
        xStopPropagation = function(evt)
        {
            if (evt && evt.stopPropogation)
            {
                evt.stopPropogation();
            }
            else if (window.event && window.event.cancelBubble)
            {
                window.event.cancelBubble = true;
            }
        },
        xPreventDefault = function(evt)
        {
            if (evt && evt.preventDefault)
            {
                evt.preventDefault();
            }
            else if (window.event && window.event.returnValue)
            {
                window.eventReturnValue = false;
            }
        },
        xContains = function(sHaystack, sNeedle)
        {
            return sHaystack.indexOf(sNeedle) >= 0
        },
        xStartsWith = function(sHaystack, sNeedle)
        {
            return sHaystack.indexOf(sNeedle) === 0
        },
        xReplace = function(sHaystack, sNeedle, sReplacement)
        {
            if( xIsEmpty(sReplacement) )
            {
                sReplacement = "";
            }
            return sHaystack.split(sNeedle).join(sReplacement);
        },
        xGetAttribute = function(ele, sAttr)
        {
            var result = (ele.getAttribute && ele.getAttribute(sAttr)) || null;
            if( !result ) {
                result = ele[sAttr];
            }
            if( !result ) {
                var attrs = ele.attributes;
                var length = attrs.length;
                for(var i = 0; i < length; i++)
                    if(attrs[i].nodeName === sAttr)
                        result = attrs[i].nodeValue;
            }
            return result;
        },
        xSetAttribute = function(ele, sAttr, value)
        {
            if(ele.setAttribute)
            {
                ele.setAttribute(sAttr, value)
            }
            else
            {
                ele[sAttr] = value;
            }
        },
        xGetParent = function(ele)
        {
            return ele.parentNode || ele.parentElement;
        },
        xInsertAfter = function( refEle, newEle )
        {
            return xGetParent(refEle).insertBefore(newEle, refEle.nextSibling);
        },
        xBind = function(func, context)
        {
            if (Function.prototype.bind && func.bind === Function.prototype.bind)
            {
                return func.bind(context);
            }
            else
            {
                return function() {
                    if( arguments.length > 2 )
                    {
                        return func.apply(context, arguments.slice(2));
                    }
                    else
                    {
                        return func.apply(context);
                    }
                };
            }
        },
        xIsEmpty = function(value)
        {
            var ret = true;
            if( value instanceof Object )
            {
                for(var i in value){ if(value.hasOwnProperty(i)){return false}}
                return true;
            }
            ret = typeof value === "undefined" || value === undefined || value === null || value === "";
            return ret;
        },
        xAddClass = function(ele, sClass)
        {
            var clazz = xGetAttribute( ele, "class" );
            if( !xHasClass(ele, sClass) )
            {
                xSetAttribute( ele, "class", clazz + " " + sClass );
            }
        },
        xRemoveClass = function(ele, sClass)
        {
            var clazz = xGetAttribute( ele, "class" );
            if( xHasClass(ele, sClass) )
            {
                xSetAttribute( ele, "class", xReplace( clazz, sClass, "" ) );
            }
        },
        xHasClass = function(ele, sClass)
        {
            var clazz = xGetAttribute( ele, "class" );
            return !xIsEmpty(clazz) && xContains( clazz, sClass );
        };
    hotswap.prototype._recreate = function( type, xcludedFiles, xcludeComparator, nDeleteDelay, bForceRecreation )
    {
        if( typeof nDeleteDelay == "undefined")
        {
            nDeleteDelay = 0;
        }

        if( typeof bForceRecreation == "undefined")
        {
            bForceRecreation = false;
        }

        var tags = this._getFilesByType(type, xcludedFiles, xcludeComparator);
        var newTags = [];
        var removeTags = [];
        var i, src, detected, node, srcAttributeName;
        for(i=0; i<tags.length; i++)
        {
            node = tags[i].node;
            srcAttributeName = tags[i].srcAttributeName;
            var newNode = {
                node: null,
                oldNode: node,
                parent: xGetParent(node)
            };
            if( bForceRecreation )
            {
                newNode.node = xCreateElement("script");
            }
            else
            {
                newNode.node = xCloneNode(node, false);
            }
            for (var p in node) {
                if (node.hasOwnProperty(p)) {
                    newNode.node.p = node.p;
                }
            }
            src = xGetAttribute( node, srcAttributeName );
            xSetAttribute( newNode.node, srcAttributeName, this._updatedUrl(src) );
            newTags.push(newNode);
            removeTags.push(node);
        }
        for(var i=0; i < newTags.length; i++) {
            xInsertAfter(newTags[i].oldNode, newTags[i].node);
        }
        if( nDeleteDelay > 0 )
        {
            for(var i=0; i < removeTags.length; i++) {
                xSetAttribute(removeTags[i], "data-hotswap-deleted", "1");
            }

            setTimeout( function() {
                for(var i=0; i < removeTags.length; i++) {
                    xRemove(removeTags[i]);
                }
            }, nDeleteDelay);
        }
        else
        {
            for(var i=0; i < removeTags.length; i++) {
                xRemove(removeTags[i]);
            }
        }
    };
    hotswap.prototype._reload = function( type, xcludedFiles, xcludeComparator )
    {
        var tags = this._getFilesByType(type, xcludedFiles, xcludeComparator);
        var i, src, node, srcAttributeName;
        for(i=0; i<tags.length; i++)
        {
            node = tags[i].node;
            srcAttributeName = tags[i].srcAttributeName;
            // update the src property
            src = xGetAttribute( node, srcAttributeName );
            xSetAttribute( node, srcAttributeName, this._updatedUrl(src) );
        }
    };
    hotswap.prototype._getFilesByType = function( type, xcludedFiles, xcludeComparator )
    {
        var files;
        switch(type)
        {
            case "css":
                files = this._getFiles(
                    "css",
                    "link",
                    function(ele)
                    {
                        return (xGetAttribute(ele, "rel") == "stylesheet" || xGetAttribute(ele, "type") == "text/css");
                    },
                    "href",
                    xcludedFiles,
                    xcludeComparator
                )
                break;

            case "js":
                files = this._getFiles(
                    "js",
                    "script",
                    function(ele)
                    {
                        return (xGetAttribute(ele, "type") == "" || xGetAttribute(ele, "type") == "text/javascript");
                    },
                    "src",
                    xcludedFiles,
                    xcludeComparator
                )
                break;

            case "img":
                files = this._getFiles(
                    "img",
                    "img",
                    function(ele)
                    {
                        return (xGetAttribute(ele, "src") != "");
                    },
                    "src",
                    xcludedFiles,
                    xcludeComparator
                )
                break;
        }

        return files;
    }
    hotswap.prototype._getFiles = function( type, tagName, tagFilterFunc, srcAttributeName, xcludedFiles, xcludeComparator )
    {
        if( typeof xcludedFiles == "undefined" || !xcludedFiles)
        {
            xcludedFiles = [];
        }

        if( typeof xcludeComparator == "undefined" || !xcludeComparator)
        {
            xcludeComparator = false;
        }

        var fileNodes = [];
        var tags = xGetElementsByTagName(tagName);
        var src, detected, node;
        for(var i=0; i<tags.length; i++) {
            node = tags[i];
            src = xGetAttribute(node,[srcAttributeName]);
            if( xIsEmpty( xGetAttribute(node, "data-hotswap-deleted") ) )
            {
                if(src && tagFilterFunc(node))
                {
                    detected = false;
                    for(var j=0; j<xcludedFiles.length; j++) {
                        if( xContains(src,xcludedFiles[j]) )
                        {
                            detected = true;
                            break;
                        }
                    }
                    if( detected == xcludeComparator )
                    {
                        fileNodes.push({
                            type: type,
                            node : node,
                            tagName : tagName,
                            srcAttributeName : srcAttributeName
                        });
                    }
                }
            }
        }

        return fileNodes;
    };
    hotswap.prototype._updatedUrl = function( url, getCleanUrl )
    {
        var cleanUrl;
        if( typeof getCleanUrl == "undefined")
        {
            getCleanUrl = false;
        }
        url = cleanUrl = url.replace(new RegExp("(\\?|&)"+this.RND_PARAM_NAME+"=[0-9.]*","g"), "");
        var queryString = "", randomizedQueryString = "";
        if( xContains(url, "?") )
        {
            if(xContains(url, "&" + this.RND_PARAM_NAME))
            {
                queryString = url.split("&" + this.RND_PARAM_NAME).slice(1,-1).join("");
            }
            randomizedQueryString = queryString + "&" + this.RND_PARAM_NAME + "=" + Math.random() * 99999999;
        }
        else
        {
            if(xContains(url, "?" + this.RND_PARAM_NAME))
            {
                queryString = url.split("?" + this.RND_PARAM_NAME).slice(1,-1).join("");
            }
            randomizedQueryString = queryString + "?" + this.RND_PARAM_NAME + "=" + Math.random() * 99999999;
        }
        var foundAt = -1;
        if( !xIsEmpty( this._prefixCache ) )
        {
            for(var i=0; i<this._prefixCache.length; ++i)
            {
                if( !xIsEmpty(this._prefixCache[i]) && foundAt < 0 )
                {
                    for(var h=0; h<this._prefixCache[i].length; ++h)
                    {
                        if( this._prefixCache[i][h] == cleanUrl + queryString )
                        {
                            cleanUrl = this._prefixCache[i][0];
                            foundAt = i;
                            break;
                        }
                    }
                }
            }
        }

        var prefixHistory = [cleanUrl + queryString];
        var applyPrefix = true;
        if( prefixHistory[0].match( new RegExp('^[A-Za-z0-9-_]+://') ) )
        {
            applyPrefix = false;
        }
        var prefix = this._prefix;
        if( !xIsEmpty(this._prefix) && this._prefix )
        {
            prefixHistory.push( this._prefix + cleanUrl + queryString );
            if(foundAt >= 0)
            {
                this._prefixCache[foundAt] = prefixHistory;
            }
            else
            {
                this._prefixCache.push( prefixHistory );
            }
        }
        else
        {
            prefix = "";
        }
        if( !applyPrefix )
        {
            prefix = "";
        }
        url = prefix + cleanUrl + randomizedQueryString;

        return (getCleanUrl) ? (cleanUrl + queryString) : url;
    }
    hotswap.prototype.refreshAllJs = function( excludedFiles )
    {
        if( typeof excludedFiles == "undefined" || !excludedFiles)
        {
            excludedFiles = []
        }
        excludedFiles.push("hotswap.js");

        this._recreate( "js", excludedFiles, false, 0, true );
    };
    hotswap.prototype.refreshJs = function( includedFiles )
    {
        this._recreate( "js", includedFiles, true, 0, true );
    };
    hotswap.prototype.refreshAllCss = function( excludedFiles )
    {
        this._recreate( "css", excludedFiles, false, this.FILE_REMOVAL_DELAY );
    };
    hotswap.prototype.refreshCss = function( includedFiles )
    {
        this._recreate( "css", includedFiles, true, this.FILE_REMOVAL_DELAY );
    };
    hotswap.prototype.refreshAllImg = function( excludedFiles )
    {
        this._reload( "img", excludedFiles, false );
    };
    hotswap.prototype.refreshImg = function( includedFiles )
    {
        this._reload( "img", includedFiles, true );
    };
    hotswap.prototype.setPrefix = function( prefix )
    {
        this._prefix = prefix;
        var gui = xGetElementById(this.CSS_HTML_PREFIX + "_wrapper");
        if( gui )
        {
            if( !xIsEmpty(this._prefix) && this._prefix )
            {
                xGetElementById(this.CSS_HTML_PREFIX+"-prefix").value = this._prefix;
            }
            else
            {
                xGetElementById(this.CSS_HTML_PREFIX+"-prefix").value = "";
            }
        }
    }
    hotswap.prototype.getPrefix = function()
    {
        return this._prefix;
    }
    hotswap.prototype.createGui = function( nDistanceFromTopInPercent )
    {
        if( xIsEmpty(nDistanceFromTopInPercent) )
        {
            nDistanceFromTopInPercent = 20;
        }
        var gui = xGetElementById(this.CSS_HTML_PREFIX + "_wrapper");
        if( gui )
        {
            xRemove(xGetElementById(this.CSS_HTML_PREFIX + "_wrapper"));
        }
        gui = xCreateElement("div");
        xSetAttribute( gui, "id", this.CSS_HTML_PREFIX + "_wrapper" );
        var guiHtml = xReplace( this._guiHtml, "PREFIX", this.CSS_HTML_PREFIX );
        guiHtml = xReplace( guiHtml, '20%;/*distance from top*/', nDistanceFromTopInPercent+'%;/*distance from top*/' );
        gui.innerHTML = guiHtml;
        xAppendChild( xGetElementsByTagName("body")[0], gui );
        if( !xIsEmpty(this._guiCache) )
        {
            this._guiCache = {};
        }
        this._guiCreateFilesList();
        if( !xIsEmpty(this._prefix) && this._prefix )
        {
            xGetElementById(this.CSS_HTML_PREFIX+"-prefix").value = this._prefix;
        }
        var self = this;
        xAddEventListener( xGetElementById(this.CSS_HTML_PREFIX+"-toggle"), "click", function(evt)
        {
            var gui = xGetElementById(self.CSS_HTML_PREFIX);
            if( xHasClass(gui, "mini") )
            {
                xRemoveClass( gui, "mini" );
            }
            else
            {
                xAddClass( gui, "mini" );
            }
        });
        xAddEventListener( xGetElementById(this.CSS_HTML_PREFIX+"-prefix"), "blur", function(evt)
        {
            self._guiPrefixChanged(evt.target);
        });
        xAddEventListener( xGetElementById(this.CSS_HTML_PREFIX+"-submit-selected"), "click", function(evt)
        {
            self._guiRefreshSelected()
        });
        xAddEventListener( xGetElementById(this.CSS_HTML_PREFIX+"-submit-start"), "click", function(evt)
        {
            if( xGetAttribute(evt.target, "class") != this.CSS_HTML_PREFIX+"-seconds" )
            {
                var input, nSeconds = 1;
                var children = evt.target.children;
                for(var i=0; i<children.length; ++i)
                {
                    if( xGetAttribute(children[i], "class") == this.CSS_HTML_PREFIX+"-seconds" )
                    {
                        nSeconds = children[i].value;
                    }
                }

                self._guiRefreshSelected();
                self._guiRefreshStart( nSeconds );
            }
        });
        xAddEventListener( xGetElementById(this.CSS_HTML_PREFIX+"-submit-stop"), "click", function(evt)
        {
            self._guiRefreshStop();
        });
        xAddEventListener( xGetElementById(this.CSS_HTML_PREFIX+"-submit-refresh-list"), "click", xBind(self.guiRefreshFilesList,self) );
    }

    hotswap.prototype._guiCreateFilesList = function()
    {
        this._guiCache.files = [];
        this._guiCache.activeFiles = {
            "css" : [],
            "js" : [],
            "img" : []
        };

        var self = this;
        var createFilesList = function(list, files)
        {
            var i, j, r, clone, template, file, fileName, nodesToRemove = [];
            for(j=0; j<list.children.length; ++j)
            {
                if( xHasClass( list.children[j], "template" ) )
                {
                    template = list.children[j];
                }
                else
                {
                    if( !xHasClass( list.children[j], self.CSS_HTML_PREFIX + "-headline" ) )
                    {
                        nodesToRemove.push(list.children[j]);
                    }
                }
            }
            for(r=0; r<nodesToRemove.length; ++r)
            {
                xRemove( nodesToRemove[r] );
            }
            for(i=0; i<files.length; ++i)
            {
                file = files[i];
                clone = xCloneNode( template );
                xRemoveClass( clone, "template" );
                fileName = self._updatedUrl( xGetAttribute( file.node, file.srcAttributeName ), true );
                if( !xContains(self._guiCache.files,fileName) )
                {
                    self._guiCache.files.push(fileName);
                    clone.innerHTML = fileName;
                    xAppendChild( list, clone );
                    xAddEventListener( clone, "click", (function(type, fileName){
                        return function(evt){
                            xStopPropagation(evt);
                            xPreventDefault(evt);
                            self._guiClickedFile(evt.target, type, fileName);
                        };
                    })(file.type, fileName)
                    );
                }
            }
        }

        createFilesList( xGetElementById(this.CSS_HTML_PREFIX+"-css"), this._getFilesByType("css") );
        createFilesList( xGetElementById(this.CSS_HTML_PREFIX+"-js"), this._getFilesByType("js", ["hotswap.js"]) );
        createFilesList( xGetElementById(this.CSS_HTML_PREFIX+"-img"), this._getFilesByType("img") );
    }
    hotswap.prototype.deleteGui = function()
    {
        var gui = xGetElementById(this.CSS_HTML_PREFIX + "_wrapper");
        if( gui )
        {
            xRemove(xGetElementById(this.CSS_HTML_PREFIX + "_wrapper"));
        }
    }
    hotswap.prototype._guiPrefixChanged = function(ele)
    {
        if( ele )
        {
            this.setPrefix(ele.value);
        }
    },

    hotswap.prototype._guiClickedFile = function( ele, sType, sFileName )
    {
        var activeFiles = this._guiCache.activeFiles[sType];
        if( xContains( activeFiles, sFileName ) )
        {
            xRemoveClass(ele, "active");
            activeFiles.splice( activeFiles.indexOf(sFileName), 1 )
        }
        else
        {
            xAddClass(ele, "active");
            activeFiles.push( sFileName );
        }
    },

    hotswap.prototype._guiRefreshSelected = function()
    {
        var activeFiles = this._guiCache.activeFiles;
        if( activeFiles['css'].length > 0 )
        {
            this.refreshCss( activeFiles['css'] );
        }
        if( activeFiles['js'].length > 0 )
        {
            this.refreshJs( activeFiles['js'] );
        }
        if( activeFiles['img'].length > 0 )
        {
            this.refreshImg( activeFiles['img'] );
        }
    },

    hotswap.prototype._guiRefreshStart = function( nSeconds )
    {
        if( this._guiGuiRefreshInterval !== null )
        {
            this._guiRefreshStop();
        }
        var self = this;
        this._guiGuiRefreshInterval = setInterval( xBind(this._guiRefreshSelected, this), nSeconds * 1000 );
        xAddClass( xGetElementById(this.CSS_HTML_PREFIX+"-submit-start"), "inactive" );
        xRemoveClass( xGetElementById(this.CSS_HTML_PREFIX+"-submit-stop"), "inactive" );
    },

    hotswap.prototype._guiRefreshStop = function()
    {
        if( this._guiGuiRefreshInterval !== null )
        {
            clearInterval(this._guiGuiRefreshInterval);
        }
        this._guiGuiRefreshInterval = null;
        xRemoveClass( xGetElementById(this.CSS_HTML_PREFIX+"-submit-start"), "inactive" );
        xAddClass( xGetElementById(this.CSS_HTML_PREFIX+"-submit-stop"), "inactive" );
    }

    hotswap.prototype.guiRefreshFilesList = function()
    {
        this._guiCreateFilesList();
    }

}).call(this);
(函数(){
var root=这个;
var previousHotswap=root.hotswap;
var hotswap=函数()
{
如果(!(此热插拔实例))
{
返回新的热插拔();
}
其他的
{
归还这个;
}
};
root.hotswap=hotswap();
hotswap.prototype.VERSION='0.2.0';
hotswap.prototype.RND_参数_NAME='hs982345jkasg89zqnsl';
hotswap.prototype.FILE_removation_DELAY=400;
hotswap.prototype.CSS_HTML_前缀='hs982345jkasg89zqnsl';
hotswap.prototype.\u prefix=false;
hotswap.prototype._prefixCache=[];
prototype.\u guiCache={};
hotswap.prototype.\u guirefreshInterval=null;
hotswap.prototype.\u guiHtml=''+
''+
“#前缀”+
'    {'+
'显示:块;'+
'位置:固定;'+
'顶部:20%;/*与顶部的距离*/'+
'右:0;'+
'z-索引:99999;'+
'宽度:20em;'+
'高度:自动;'+
'颜色:黑色;'+
'背景色:#666666;'+
'字体系列:Verdana,无衬线;'+
'字体大小:0.8em;'+
“-webkit盒阴影:0 0px 0.3em 0.1em#999999;”+
'-moz盒阴影:0 0px 0.3em 0.1em#999999;'+
'盒影:0 0px 0.3em 0.1em#999999;'+
'    }'+
“#前缀.迷你”+
'    {'+
'宽度:2.9em;'+
'高度:2.9em;'+
'溢出:隐藏;'+
'    }'+
“#PREFIX.mini.前缀页眉输入,#PREFIX.mini.前缀列表,#PREFIX.mini.前缀页脚”+
'    {'+
'显示:无;'+
'    }'+
“#PREFIX.mini.PREFIX header div”+
'    {'+
'显示:块;'+
“宽度:100%;”+
“身高:100%;”+
'    }'+
“#前缀输入”+
'    {'+
'字体大小:1.0em;'+
'边框:0.1米实心#999999;'+
'边界半径:0.2米;'+
'填充:0.2em 0.1em;'+
'        }'+
“#前缀。前缀标题”+
'    {'+
'高度:2.4em;'+
'溢出:隐藏;'+
'填充:0.4em;'+
'颜色:白色;'+
'背景色:黑色;'+
'        }'+
“#前缀。前缀头输入”+
'    {'+
“宽度:83.5%;”+
'高度:1.6em;'+
'    }'+
“#前缀。前缀头div”+
'    {'+
'位置:绝对;'+
'顶部:0;'+
'右:0;'+
“宽度:14.5%;”+
'高度:1.6em;'+
'线高:1.4em;'+
'文本对齐:居中;'+
'字体大小:2em;'+
'字体大小:粗体;'+
'光标:指针;'+
'    }'+
“#前缀。前缀头div:hover”+
'    {'+
'背景色:#4444;'+
'    }'+
“#前缀。前缀列表”+
'    {'+
“宽度:100%;”+
'高度:22em;'+
'溢出:自动;'+
'    }'+
“#前缀ul”+
'    {'+
'列表样式类型:无;'+
'列表样式位置:在
// refresh .js files
hotswap.refreshAllJs(arrExcludedFiles);
hotswap.refreshJs(arrIncludedFiles);

// refresh .css files
hotswap.refreshAllCss(arrExcludedFiles);
hotswap.refreshCss(arrIncludedFiles);

// refresh images
hotswap.refreshAllImg(arrExcludedFiles);
hotswap.refreshImg(arrIncludedFiles);

// show a gui (this is optional and not required for hotswap to work) (Click on the "H").
hotswap.createGui();

// Examples:
// refresh all .js files
hotswap.refreshAllJs();

// refresh main.css only
hotswap.refreshCss( ["main.js"] );

// refresh all images (img tags) except "dont-refreh-me.png".
hotswap.refreshAllImg( ["dont-refreh-me.png"] );
(function() {
    var root = this;
    var previousHotswap = root.hotswap;
    var hotswap = function()
    {
        if (!(this instanceof hotswap))
        {
            return new hotswap();
        }
        else
        {
            return this;
        }
    };
    root.hotswap = hotswap();
    hotswap.prototype.VERSION = '0.2.0';
    hotswap.prototype.RND_PARAM_NAME = 'hs982345jkasg89zqnsl';
    hotswap.prototype.FILE_REMOVAL_DELAY = 400;
    hotswap.prototype.CSS_HTML_PREFIX = 'hs982345jkasg89zqnsl';
    hotswap.prototype._prefix = false;
    hotswap.prototype._prefixCache = [];
    hotswap.prototype._guiCache = {};
    hotswap.prototype._guiGuiRefreshInterval = null;
    hotswap.prototype._guiHtml = '' +
        '<style type="text/css">'+
        '    #PREFIX'+
        '    {'+
        '        display: block;'+
        '        position: fixed;'+
        '        top: 20%;/*distance from top*/'+
        '        right: 0;'+
        '        z-index: 99999;'+
        '        width: 20em;'+
        '        height: auto;'+
        '        color: black;'+
        '        background-color: #666666;'+
        '        font-family: Verdana, sans-serif;'+
        '        font-size: 0.8em;'+
        '        -webkit-box-shadow: 0 0px 0.3em 0.1em #999999;'+
        '        -moz-box-shadow: 0 0px 0.3em 0.1em #999999;'+
        '        box-shadow: 0 0px 0.3em 0.1em #999999;'+
        '    }'+
        '    #PREFIX.mini'+
        '    {'+
        '        width: 2.9em;'+
        '        height: 2.9em;'+
        '        overflow:hidden;'+
        '    }'+
        '    #PREFIX.mini .PREFIX-header input, #PREFIX.mini .PREFIX-list, #PREFIX.mini .PREFIX-footer'+
        '    {'+
        '        display:none;'+
        '    }'+
        '        #PREFIX.mini .PREFIX-header div'+
        '    {'+
        '        display: block;'+
        '        width: 100%;'+
        '        height: 100%;'+
        '    }'+
        '    #PREFIX input'+
        '    {'+
        '        font-size: 1.0em;'+
        '        border: 0.1em solid #999999;'+
        '        border-radius: 0.2em;'+
        '        padding: 0.2em 0.1em;'+
        '        }'+
        '    #PREFIX .PREFIX-header'+
        '    {'+
        '        height: 2.4em;'+
        '        overflow:hidden;'+
        '        padding: 0.4em;'+
        '        color: white;'+
        '        background-color: black;'+
        '        }'+
        '    #PREFIX .PREFIX-header input'+
        '    {'+
        '        width: 83.5%;'+
        '        height: 1.6em;'+
        '    }'+
        '    #PREFIX .PREFIX-header div'+
        '    {'+
        '        position: absolute;'+
        '        top:0;'+
        '        right:0;'+
        '        width: 14.5%;'+
        '        height: 1.6em;'+
        '        line-height: 1.4em;'+
        '        text-align: center;'+
        '        font-size: 2em;'+
        '        font-weight: bold;'+
        '        cursor: pointer;'+
        '    }'+
        '    #PREFIX .PREFIX-header div:hover'+
        '    {'+
        '        background-color: #444444;'+
        '    }'+
        '    #PREFIX .PREFIX-list'+
        '    {'+
        '        width: 100%;'+
        '        height: 22em;'+
        '        overflow: auto;'+
        '    }'+
        '    #PREFIX ul'+
        '    {'+
        '        list-style-type: none;'+
        '        list-style-position: inside;'+
        '        padding: 0;'+
        '        margin: 0.5em 0.5em 1.2em 0.5em;'+
        '    }'+
        '    #PREFIX ul li'+
        '    {'+
        '        margin: 0.3em;'+
        '        padding: 0.5em 0.5em;'+
        '        color: white;'+
        '        background-color: #717171;'+
        '        font-size: 0.9em;'+
        '        line-height: 1.5em;'+
        '        cursor: pointer;'+
        '    }'+
        '    #PREFIX ul li:hover'+
        '    {'+
        '        background-color: #797979;'+
        '    }'+
        '    #PREFIX ul li.template'+
        '    {'+
        '        display: none;'+
        '    }'+
        '    #PREFIX ul li.active'+
        '    {'+
        '        background-color: black;'+
        '    }'+
        '    #PREFIX ul li.PREFIX-headline'+
        '    {'+
        '        color: white;'+
        '        background-color: transparent;'+
        '        text-align: center;'+
        '        font-weight: bold;'+
        '        cursor: default;'+
        '    }'+
        '    #PREFIX .PREFIX-footer'+
        '    {'+
        '        padding: 0;'+
        '        margin:0;'+
        '        background-color: #444444;'+
        '    }'+
        '    #PREFIX .PREFIX-footer ul'+
        '    {'+
        '        margin: 0;'+
        '        padding: 0.5em;'+
        '    }'+
        '    #PREFIX .PREFIX-footer ul li'+
        '    {'+
        '        color: white;'+
        '        background-color: black;'+
        '        font-size: 1.0em;'+
        '        border-radius: 0.5em;'+
        '        text-align: center;'+
        '        height: 2.2em;'+
        '        line-height: 2.2em;'+
        '    }'+
        '    #PREFIX .PREFIX-footer ul li input.PREFIX-seconds'+
        '    {'+
        '        text-align: center;'+
        '        width: 2em;'+
        '    }'+
        '    #PREFIX .PREFIX-footer ul li:hover'+
        '    {'+
        '        background-color: #222222;'+
        '        }'+
        '    #PREFIX .PREFIX-footer ul li.inactive'+
        '    {'+
        '        background-color: #666666;'+
        '        cursor: default;'+
        '    }'+
        '    </style>'+
        '    <div id="PREFIX" class="mini">'+
        '        <div class="PREFIX-header">'+
        '            <input id="PREFIX-prefix" placeholder="prefix" type="text" name="" />'+
        '            <div id="PREFIX-toggle">H</div>'+
        '        </div>'+
        '        <div class="PREFIX-list">'+
        '            <ul id="PREFIX-css">'+
        '                <li class="PREFIX-headline">CSS</li>'+
        '                <li class="template"></li>'+
        '            </ul>'+
        '            <ul id="PREFIX-js">'+
        '                <li class="PREFIX-headline">JS</li>'+
        '                <li class="template"></li>'+
        '            </ul>'+
        '            <ul id="PREFIX-img">'+
        '                <li class="PREFIX-headline">IMG</li>'+
        '                <li class="template"></li>'+
        '            </ul>'+
        '        </div>'+
        '        <div class="PREFIX-footer">'+
        '            <ul>'+
        '                <li id="PREFIX-submit-selected">refresh selected</li>'+
        '                <li id="PREFIX-submit-start">refresh every <input  class="PREFIX-seconds" type="text" value="1" /> sec.</li>'+
        '                <li id="PREFIX-submit-stop" class="inactive">stop refreshing</li>'+
        '                <li id="PREFIX-submit-refresh-list">refresh list</li>'+
        '            </ul>'+
        '        </div>'+
        '    </div>';
    var
        xGetElementById       = function(sId){ return document.getElementById(sId) },
        xGetElementsByTagName = function(sTags){ return document.getElementsByTagName(sTags) },
        xAppendChild          = function(parent, child){ return parent.appendChild(child) },
        xCloneNode            = function(node){ return document.cloneNode(node) },
        xCreateElement        = function(sTag){ return document.createElement(sTag) },
        xCloneNode            = function(ele, deep){ return ele.cloneNode(deep) },
        xRemove = function(ele)
        {
            if( typeof ele.parentNode != "undefined" && ele.parentNode )
            {
                ele.parentNode.removeChild( ele );
            }
        },
        xAddEventListener = function(ele, sEvent, fn, bCaptureOrBubble)
        {
            if( xIsEmpty(bCaptureOrBubble) )
            {
                bCaptureOrBubble = false;
            }
            if (ele.addEventListener)
            {
                ele.addEventListener(sEvent, fn, bCaptureOrBubble);
                return true;
            }
            else if (ele.attachEvent)
            {
                return ele.attachEvent('on' + sEvent, fn);
            }
            else
            {
                ele['on' + sEvent] = fn;
            }
        },
        xStopPropagation = function(evt)
        {
            if (evt && evt.stopPropogation)
            {
                evt.stopPropogation();
            }
            else if (window.event && window.event.cancelBubble)
            {
                window.event.cancelBubble = true;
            }
        },
        xPreventDefault = function(evt)
        {
            if (evt && evt.preventDefault)
            {
                evt.preventDefault();
            }
            else if (window.event && window.event.returnValue)
            {
                window.eventReturnValue = false;
            }
        },
        xContains = function(sHaystack, sNeedle)
        {
            return sHaystack.indexOf(sNeedle) >= 0
        },
        xStartsWith = function(sHaystack, sNeedle)
        {
            return sHaystack.indexOf(sNeedle) === 0
        },
        xReplace = function(sHaystack, sNeedle, sReplacement)
        {
            if( xIsEmpty(sReplacement) )
            {
                sReplacement = "";
            }
            return sHaystack.split(sNeedle).join(sReplacement);
        },
        xGetAttribute = function(ele, sAttr)
        {
            var result = (ele.getAttribute && ele.getAttribute(sAttr)) || null;
            if( !result ) {
                result = ele[sAttr];
            }
            if( !result ) {
                var attrs = ele.attributes;
                var length = attrs.length;
                for(var i = 0; i < length; i++)
                    if(attrs[i].nodeName === sAttr)
                        result = attrs[i].nodeValue;
            }
            return result;
        },
        xSetAttribute = function(ele, sAttr, value)
        {
            if(ele.setAttribute)
            {
                ele.setAttribute(sAttr, value)
            }
            else
            {
                ele[sAttr] = value;
            }
        },
        xGetParent = function(ele)
        {
            return ele.parentNode || ele.parentElement;
        },
        xInsertAfter = function( refEle, newEle )
        {
            return xGetParent(refEle).insertBefore(newEle, refEle.nextSibling);
        },
        xBind = function(func, context)
        {
            if (Function.prototype.bind && func.bind === Function.prototype.bind)
            {
                return func.bind(context);
            }
            else
            {
                return function() {
                    if( arguments.length > 2 )
                    {
                        return func.apply(context, arguments.slice(2));
                    }
                    else
                    {
                        return func.apply(context);
                    }
                };
            }
        },
        xIsEmpty = function(value)
        {
            var ret = true;
            if( value instanceof Object )
            {
                for(var i in value){ if(value.hasOwnProperty(i)){return false}}
                return true;
            }
            ret = typeof value === "undefined" || value === undefined || value === null || value === "";
            return ret;
        },
        xAddClass = function(ele, sClass)
        {
            var clazz = xGetAttribute( ele, "class" );
            if( !xHasClass(ele, sClass) )
            {
                xSetAttribute( ele, "class", clazz + " " + sClass );
            }
        },
        xRemoveClass = function(ele, sClass)
        {
            var clazz = xGetAttribute( ele, "class" );
            if( xHasClass(ele, sClass) )
            {
                xSetAttribute( ele, "class", xReplace( clazz, sClass, "" ) );
            }
        },
        xHasClass = function(ele, sClass)
        {
            var clazz = xGetAttribute( ele, "class" );
            return !xIsEmpty(clazz) && xContains( clazz, sClass );
        };
    hotswap.prototype._recreate = function( type, xcludedFiles, xcludeComparator, nDeleteDelay, bForceRecreation )
    {
        if( typeof nDeleteDelay == "undefined")
        {
            nDeleteDelay = 0;
        }

        if( typeof bForceRecreation == "undefined")
        {
            bForceRecreation = false;
        }

        var tags = this._getFilesByType(type, xcludedFiles, xcludeComparator);
        var newTags = [];
        var removeTags = [];
        var i, src, detected, node, srcAttributeName;
        for(i=0; i<tags.length; i++)
        {
            node = tags[i].node;
            srcAttributeName = tags[i].srcAttributeName;
            var newNode = {
                node: null,
                oldNode: node,
                parent: xGetParent(node)
            };
            if( bForceRecreation )
            {
                newNode.node = xCreateElement("script");
            }
            else
            {
                newNode.node = xCloneNode(node, false);
            }
            for (var p in node) {
                if (node.hasOwnProperty(p)) {
                    newNode.node.p = node.p;
                }
            }
            src = xGetAttribute( node, srcAttributeName );
            xSetAttribute( newNode.node, srcAttributeName, this._updatedUrl(src) );
            newTags.push(newNode);
            removeTags.push(node);
        }
        for(var i=0; i < newTags.length; i++) {
            xInsertAfter(newTags[i].oldNode, newTags[i].node);
        }
        if( nDeleteDelay > 0 )
        {
            for(var i=0; i < removeTags.length; i++) {
                xSetAttribute(removeTags[i], "data-hotswap-deleted", "1");
            }

            setTimeout( function() {
                for(var i=0; i < removeTags.length; i++) {
                    xRemove(removeTags[i]);
                }
            }, nDeleteDelay);
        }
        else
        {
            for(var i=0; i < removeTags.length; i++) {
                xRemove(removeTags[i]);
            }
        }
    };
    hotswap.prototype._reload = function( type, xcludedFiles, xcludeComparator )
    {
        var tags = this._getFilesByType(type, xcludedFiles, xcludeComparator);
        var i, src, node, srcAttributeName;
        for(i=0; i<tags.length; i++)
        {
            node = tags[i].node;
            srcAttributeName = tags[i].srcAttributeName;
            // update the src property
            src = xGetAttribute( node, srcAttributeName );
            xSetAttribute( node, srcAttributeName, this._updatedUrl(src) );
        }
    };
    hotswap.prototype._getFilesByType = function( type, xcludedFiles, xcludeComparator )
    {
        var files;
        switch(type)
        {
            case "css":
                files = this._getFiles(
                    "css",
                    "link",
                    function(ele)
                    {
                        return (xGetAttribute(ele, "rel") == "stylesheet" || xGetAttribute(ele, "type") == "text/css");
                    },
                    "href",
                    xcludedFiles,
                    xcludeComparator
                )
                break;

            case "js":
                files = this._getFiles(
                    "js",
                    "script",
                    function(ele)
                    {
                        return (xGetAttribute(ele, "type") == "" || xGetAttribute(ele, "type") == "text/javascript");
                    },
                    "src",
                    xcludedFiles,
                    xcludeComparator
                )
                break;

            case "img":
                files = this._getFiles(
                    "img",
                    "img",
                    function(ele)
                    {
                        return (xGetAttribute(ele, "src") != "");
                    },
                    "src",
                    xcludedFiles,
                    xcludeComparator
                )
                break;
        }

        return files;
    }
    hotswap.prototype._getFiles = function( type, tagName, tagFilterFunc, srcAttributeName, xcludedFiles, xcludeComparator )
    {
        if( typeof xcludedFiles == "undefined" || !xcludedFiles)
        {
            xcludedFiles = [];
        }

        if( typeof xcludeComparator == "undefined" || !xcludeComparator)
        {
            xcludeComparator = false;
        }

        var fileNodes = [];
        var tags = xGetElementsByTagName(tagName);
        var src, detected, node;
        for(var i=0; i<tags.length; i++) {
            node = tags[i];
            src = xGetAttribute(node,[srcAttributeName]);
            if( xIsEmpty( xGetAttribute(node, "data-hotswap-deleted") ) )
            {
                if(src && tagFilterFunc(node))
                {
                    detected = false;
                    for(var j=0; j<xcludedFiles.length; j++) {
                        if( xContains(src,xcludedFiles[j]) )
                        {
                            detected = true;
                            break;
                        }
                    }
                    if( detected == xcludeComparator )
                    {
                        fileNodes.push({
                            type: type,
                            node : node,
                            tagName : tagName,
                            srcAttributeName : srcAttributeName
                        });
                    }
                }
            }
        }

        return fileNodes;
    };
    hotswap.prototype._updatedUrl = function( url, getCleanUrl )
    {
        var cleanUrl;
        if( typeof getCleanUrl == "undefined")
        {
            getCleanUrl = false;
        }
        url = cleanUrl = url.replace(new RegExp("(\\?|&)"+this.RND_PARAM_NAME+"=[0-9.]*","g"), "");
        var queryString = "", randomizedQueryString = "";
        if( xContains(url, "?") )
        {
            if(xContains(url, "&" + this.RND_PARAM_NAME))
            {
                queryString = url.split("&" + this.RND_PARAM_NAME).slice(1,-1).join("");
            }
            randomizedQueryString = queryString + "&" + this.RND_PARAM_NAME + "=" + Math.random() * 99999999;
        }
        else
        {
            if(xContains(url, "?" + this.RND_PARAM_NAME))
            {
                queryString = url.split("?" + this.RND_PARAM_NAME).slice(1,-1).join("");
            }
            randomizedQueryString = queryString + "?" + this.RND_PARAM_NAME + "=" + Math.random() * 99999999;
        }
        var foundAt = -1;
        if( !xIsEmpty( this._prefixCache ) )
        {
            for(var i=0; i<this._prefixCache.length; ++i)
            {
                if( !xIsEmpty(this._prefixCache[i]) && foundAt < 0 )
                {
                    for(var h=0; h<this._prefixCache[i].length; ++h)
                    {
                        if( this._prefixCache[i][h] == cleanUrl + queryString )
                        {
                            cleanUrl = this._prefixCache[i][0];
                            foundAt = i;
                            break;
                        }
                    }
                }
            }
        }

        var prefixHistory = [cleanUrl + queryString];
        var applyPrefix = true;
        if( prefixHistory[0].match( new RegExp('^[A-Za-z0-9-_]+://') ) )
        {
            applyPrefix = false;
        }
        var prefix = this._prefix;
        if( !xIsEmpty(this._prefix) && this._prefix )
        {
            prefixHistory.push( this._prefix + cleanUrl + queryString );
            if(foundAt >= 0)
            {
                this._prefixCache[foundAt] = prefixHistory;
            }
            else
            {
                this._prefixCache.push( prefixHistory );
            }
        }
        else
        {
            prefix = "";
        }
        if( !applyPrefix )
        {
            prefix = "";
        }
        url = prefix + cleanUrl + randomizedQueryString;

        return (getCleanUrl) ? (cleanUrl + queryString) : url;
    }
    hotswap.prototype.refreshAllJs = function( excludedFiles )
    {
        if( typeof excludedFiles == "undefined" || !excludedFiles)
        {
            excludedFiles = []
        }
        excludedFiles.push("hotswap.js");

        this._recreate( "js", excludedFiles, false, 0, true );
    };
    hotswap.prototype.refreshJs = function( includedFiles )
    {
        this._recreate( "js", includedFiles, true, 0, true );
    };
    hotswap.prototype.refreshAllCss = function( excludedFiles )
    {
        this._recreate( "css", excludedFiles, false, this.FILE_REMOVAL_DELAY );
    };
    hotswap.prototype.refreshCss = function( includedFiles )
    {
        this._recreate( "css", includedFiles, true, this.FILE_REMOVAL_DELAY );
    };
    hotswap.prototype.refreshAllImg = function( excludedFiles )
    {
        this._reload( "img", excludedFiles, false );
    };
    hotswap.prototype.refreshImg = function( includedFiles )
    {
        this._reload( "img", includedFiles, true );
    };
    hotswap.prototype.setPrefix = function( prefix )
    {
        this._prefix = prefix;
        var gui = xGetElementById(this.CSS_HTML_PREFIX + "_wrapper");
        if( gui )
        {
            if( !xIsEmpty(this._prefix) && this._prefix )
            {
                xGetElementById(this.CSS_HTML_PREFIX+"-prefix").value = this._prefix;
            }
            else
            {
                xGetElementById(this.CSS_HTML_PREFIX+"-prefix").value = "";
            }
        }
    }
    hotswap.prototype.getPrefix = function()
    {
        return this._prefix;
    }
    hotswap.prototype.createGui = function( nDistanceFromTopInPercent )
    {
        if( xIsEmpty(nDistanceFromTopInPercent) )
        {
            nDistanceFromTopInPercent = 20;
        }
        var gui = xGetElementById(this.CSS_HTML_PREFIX + "_wrapper");
        if( gui )
        {
            xRemove(xGetElementById(this.CSS_HTML_PREFIX + "_wrapper"));
        }
        gui = xCreateElement("div");
        xSetAttribute( gui, "id", this.CSS_HTML_PREFIX + "_wrapper" );
        var guiHtml = xReplace( this._guiHtml, "PREFIX", this.CSS_HTML_PREFIX );
        guiHtml = xReplace( guiHtml, '20%;/*distance from top*/', nDistanceFromTopInPercent+'%;/*distance from top*/' );
        gui.innerHTML = guiHtml;
        xAppendChild( xGetElementsByTagName("body")[0], gui );
        if( !xIsEmpty(this._guiCache) )
        {
            this._guiCache = {};
        }
        this._guiCreateFilesList();
        if( !xIsEmpty(this._prefix) && this._prefix )
        {
            xGetElementById(this.CSS_HTML_PREFIX+"-prefix").value = this._prefix;
        }
        var self = this;
        xAddEventListener( xGetElementById(this.CSS_HTML_PREFIX+"-toggle"), "click", function(evt)
        {
            var gui = xGetElementById(self.CSS_HTML_PREFIX);
            if( xHasClass(gui, "mini") )
            {
                xRemoveClass( gui, "mini" );
            }
            else
            {
                xAddClass( gui, "mini" );
            }
        });
        xAddEventListener( xGetElementById(this.CSS_HTML_PREFIX+"-prefix"), "blur", function(evt)
        {
            self._guiPrefixChanged(evt.target);
        });
        xAddEventListener( xGetElementById(this.CSS_HTML_PREFIX+"-submit-selected"), "click", function(evt)
        {
            self._guiRefreshSelected()
        });
        xAddEventListener( xGetElementById(this.CSS_HTML_PREFIX+"-submit-start"), "click", function(evt)
        {
            if( xGetAttribute(evt.target, "class") != this.CSS_HTML_PREFIX+"-seconds" )
            {
                var input, nSeconds = 1;
                var children = evt.target.children;
                for(var i=0; i<children.length; ++i)
                {
                    if( xGetAttribute(children[i], "class") == this.CSS_HTML_PREFIX+"-seconds" )
                    {
                        nSeconds = children[i].value;
                    }
                }

                self._guiRefreshSelected();
                self._guiRefreshStart( nSeconds );
            }
        });
        xAddEventListener( xGetElementById(this.CSS_HTML_PREFIX+"-submit-stop"), "click", function(evt)
        {
            self._guiRefreshStop();
        });
        xAddEventListener( xGetElementById(this.CSS_HTML_PREFIX+"-submit-refresh-list"), "click", xBind(self.guiRefreshFilesList,self) );
    }

    hotswap.prototype._guiCreateFilesList = function()
    {
        this._guiCache.files = [];
        this._guiCache.activeFiles = {
            "css" : [],
            "js" : [],
            "img" : []
        };

        var self = this;
        var createFilesList = function(list, files)
        {
            var i, j, r, clone, template, file, fileName, nodesToRemove = [];
            for(j=0; j<list.children.length; ++j)
            {
                if( xHasClass( list.children[j], "template" ) )
                {
                    template = list.children[j];
                }
                else
                {
                    if( !xHasClass( list.children[j], self.CSS_HTML_PREFIX + "-headline" ) )
                    {
                        nodesToRemove.push(list.children[j]);
                    }
                }
            }
            for(r=0; r<nodesToRemove.length; ++r)
            {
                xRemove( nodesToRemove[r] );
            }
            for(i=0; i<files.length; ++i)
            {
                file = files[i];
                clone = xCloneNode( template );
                xRemoveClass( clone, "template" );
                fileName = self._updatedUrl( xGetAttribute( file.node, file.srcAttributeName ), true );
                if( !xContains(self._guiCache.files,fileName) )
                {
                    self._guiCache.files.push(fileName);
                    clone.innerHTML = fileName;
                    xAppendChild( list, clone );
                    xAddEventListener( clone, "click", (function(type, fileName){
                        return function(evt){
                            xStopPropagation(evt);
                            xPreventDefault(evt);
                            self._guiClickedFile(evt.target, type, fileName);
                        };
                    })(file.type, fileName)
                    );
                }
            }
        }

        createFilesList( xGetElementById(this.CSS_HTML_PREFIX+"-css"), this._getFilesByType("css") );
        createFilesList( xGetElementById(this.CSS_HTML_PREFIX+"-js"), this._getFilesByType("js", ["hotswap.js"]) );
        createFilesList( xGetElementById(this.CSS_HTML_PREFIX+"-img"), this._getFilesByType("img") );
    }
    hotswap.prototype.deleteGui = function()
    {
        var gui = xGetElementById(this.CSS_HTML_PREFIX + "_wrapper");
        if( gui )
        {
            xRemove(xGetElementById(this.CSS_HTML_PREFIX + "_wrapper"));
        }
    }
    hotswap.prototype._guiPrefixChanged = function(ele)
    {
        if( ele )
        {
            this.setPrefix(ele.value);
        }
    },

    hotswap.prototype._guiClickedFile = function( ele, sType, sFileName )
    {
        var activeFiles = this._guiCache.activeFiles[sType];
        if( xContains( activeFiles, sFileName ) )
        {
            xRemoveClass(ele, "active");
            activeFiles.splice( activeFiles.indexOf(sFileName), 1 )
        }
        else
        {
            xAddClass(ele, "active");
            activeFiles.push( sFileName );
        }
    },

    hotswap.prototype._guiRefreshSelected = function()
    {
        var activeFiles = this._guiCache.activeFiles;
        if( activeFiles['css'].length > 0 )
        {
            this.refreshCss( activeFiles['css'] );
        }
        if( activeFiles['js'].length > 0 )
        {
            this.refreshJs( activeFiles['js'] );
        }
        if( activeFiles['img'].length > 0 )
        {
            this.refreshImg( activeFiles['img'] );
        }
    },

    hotswap.prototype._guiRefreshStart = function( nSeconds )
    {
        if( this._guiGuiRefreshInterval !== null )
        {
            this._guiRefreshStop();
        }
        var self = this;
        this._guiGuiRefreshInterval = setInterval( xBind(this._guiRefreshSelected, this), nSeconds * 1000 );
        xAddClass( xGetElementById(this.CSS_HTML_PREFIX+"-submit-start"), "inactive" );
        xRemoveClass( xGetElementById(this.CSS_HTML_PREFIX+"-submit-stop"), "inactive" );
    },

    hotswap.prototype._guiRefreshStop = function()
    {
        if( this._guiGuiRefreshInterval !== null )
        {
            clearInterval(this._guiGuiRefreshInterval);
        }
        this._guiGuiRefreshInterval = null;
        xRemoveClass( xGetElementById(this.CSS_HTML_PREFIX+"-submit-start"), "inactive" );
        xAddClass( xGetElementById(this.CSS_HTML_PREFIX+"-submit-stop"), "inactive" );
    }

    hotswap.prototype.guiRefreshFilesList = function()
    {
        this._guiCreateFilesList();
    }

}).call(this);