<commit_before>Type.registerNamespace("Sys.Extended.UI");

Sys.Extended.UI.AsyncFileUpload = function(element) {
    Sys.Extended.UI.AsyncFileUpload.initializeBase(this, [element]);

    this._hiddenField = null;
    this._inputFile = null;
    this._innerTB = null;
    this._postBackUrl = "";
    this._formName = "";
    this._iframe = null;
    this._waitTimer = null;
    this._completeBackColor = "";
    this._uploadingBackColor = "";
    this._errorBackColor = "";
    this._throbber = null;

    this._onchange$delegate = null;
    this._onload$delegate = null;
    this._app_onload$delegate = Function.createDelegate(this, this._app_onload);
    this._onmouseup$delegate = null;
}

Sys.Extended.UI.AsyncFileUpload.prototype = {

    get_throbber: function() {
        return this._throbber;
    },
    set_throbber: function(value) {
        this._throbber = value;
    },

    get_completeBackColor: function() {
        return this._completeBackColor;
    },
    set_completeBackColor: function(value) {
        this._completeBackColor = value;
    },

    get_errorBackColor: function() {
        return this._errorBackColor;
    },
    set_errorBackColor: function(value) {
        this._errorBackColor = value;
    },

    get_uploadingBackColor: function() {
        return this._uploadingBackColor;
    },
    set_uploadingBackColor: function(value) {
        this._uploadingBackColor = value;
    },

    get_inputFile: function() {
        return this._inputFile;
    },
    set_inputFile: function(value) {
        this._inputFile = value;
    },

    get_hiddenField: function() {
        return this._hiddenField;
    },
    set_hiddenField: function(value) {
        this._hiddenField = value;
    },

    get_innerTB: function() {
        return this._innerTB;
    },
    set_innerTB: function(value) {
        this._innerTB = value;
    },

    get_postBackUrl: function() {
        return this._postBackUrl;
    },
    set_postBackUrl: function(value) {
        this._postBackUrl = value;
    },

    get_formName: function() {
        return this._formName;
    },
    set_formName: function(value) {
        this._formName = value;
    },

    add_uploadStarted: function(handler) {
        this.get_events().addHandler("uploadStarted", handler);
    },
    remove_uploadStarted: function(handler) {
        this.get_events().removeHandler("uploadStarted", handler);
    },
    raiseUploadStarted: function(e) {
        var eh = this.get_events().getHandler("uploadStarted");
        if (eh) {
            return eh(this, e);
        }
        return true;
    },

    add_uploadComplete: function(handler) {
        this.get_events().addHandler("uploadComplete", handler);
    },
    remove_uploadComplete: function(handler) {
        this.get_events().removeHandler("uploadComplete", handler);
    },
    raiseUploadComplete: function(e) {
        var eh = this.get_events().getHandler("uploadComplete");
        if (eh) {
            eh(this, e);
        }
    },

    add_uploadError: function(handler) {
        this.get_events().addHandler("uploadError", handler);
    },
    remove_uploadError: function(handler) {
        this.get_events().removeHandler("uploadError", handler);
    },
    raiseUploadError: function(e) {
        var eh = this.get_events().getHandler("uploadError");
        if (eh) {
            eh(this, e);
            return true;
        }
        return false;
    },

    setThrobber: function(value) {
        if (this.get_throbber() != null) {
            this.get_throbber().style.display = value ? "" : "none";
        }
    },

    _onStart: function(fileName) {
        var valid = this.raiseUploadStarted(new Sys.Extended.UI.AsyncFileUploadEventArgs(fileName, null, null, null));
        if (typeof valid == 'undefined') {
            valid = true;
        }

        return valid;
    },

    initialize: function() {
        Sys.Extended.UI.AsyncFileUpload.callBaseMethod(this, "initialize");
        Sys.Application.add_load(this._app_onload$delegate);
        this._iframeName = this.get_element() + "_iframe";
        this.setThrobber(false);
    },

    dispose: function() {
        Sys.Application.remove_load(this._app_onload$delegate);
        if (this._onchange$delegate != null) {
            $common.removeHandlers(this._inputFile, {
                change: this._onchange$delegate
            });
            this._onchange$delegate = null;
        }
        if (this._onmouseup$delegate != null) {
            $common.removeHandlers(this._inputFile, {
                mouseup: this._onmouseup$delegate
            });
            this._onmouseup$delegate = null;
        }
        this._removeIframe();
        Sys.Extended.UI.AsyncFileUpload.callBaseMethod(this, "dispose");
    },

    _onmouseup: function() {
        var inputFile = this._inputFile;
        setTimeout(function() { inputFile.blur(); }, 0);
        return true;
    },

    _app_onload: function(sender, e) {
        this.setThrobber(false);
        if (this._inputFile != null) {
            if (this._onchange$delegate == null) {
                this._onchange$delegate = Function.createDelegate(this, this._onchange);
                $addHandlers(this._inputFile, {
                    change: this._onchange$delegate
                });
            }
            if (Sys.Browser.agent == Sys.Browser.Firefox) {
                this._inputFile.size = 0;
                var width = this._inputFile.offsetWidth;
                this._inputFile.style.width = "";
                while (this._inputFile.offsetWidth < width) {
                    this._inputFile.size++;
                }
            }
            if (this._innerTB != null) {
                this._inputFile.blur();
                var inputFile = this._inputFile;
                setTimeout(function() { inputFile.blur(); }, 0);
                this._innerTB.style.width = (this._inputFile.offsetWidth - 107) + "px";
                this._inputFile.parentNode.style.width = this._inputFile.offsetWidth + "px";
                if (Sys.Browser.agent == Sys.Browser.InternetExplorer) {
                    this._onmouseup$delegate = Function.createDelegate(this, this._onmouseup);
                    $addHandlers(this._inputFile, {
                        mouseup: this._onmouseup$delegate
                    });
                }
            }
        }
    },

    _removeIframe: function() {
        this._removeTimer();
        if (this._iframe != null) {
            if (this._onload$delegate != null) {
                $common.removeHandlers(this._iframe, {
                    load: this._onload$delegate
                });
                this._onload$delegate = null;
            }
            document.body.removeChild(this._iframe);
            this._iframe = null;
        }
    },

    _removeTimer: function() {
        if (this._waitTimer != null) {
            window.clearTimeout(this._waitTimer);
            this._waitTimer = null;
        }
    },

    _onError: function(error) {
        var unhandledException = Sys.Extended.UI.Resources.AsyncFileUpload_UnhandledException;
        this.setThrobber(false);

        if (this.get_errorBackColor() != "") {
            if (this._innerTB != null) {
                this._innerTB.style.backgroundColor = this.get_errorBackColor();
            } else {
                this._inputFile.style.backgroundColor = this.get_errorBackColor();
            }
        }
        if (!this.raiseUploadError(new Sys.Extended.UI.AsyncFileUploadEventArgs(this._inputFile.value, null, null, error))) {
            alert(unhandledException + ": " + error);
        }
    },

    _onchange: function(e) {
        var value = this._inputFile.value;
        if (value == "") {
            return;
        }
        if (this._innerTB != null) {
            this._innerTB.value = value;
        }
        if (this._hiddenField != null) {
            this._hiddenField.value = value;
        }

        try {
            if (this._iframe == null) {
                this._onload$delegate = Function.createDelegate(this, this._onload);
                var iframe = document.createElement("IFRAME");
                iframe.width = "0";
                iframe.height = "0";
                iframe.style.display = "none";
                iframe.src = "about:blank";
                iframe.id = this._iframeName;
                iframe.name = this._iframeName;
                $addHandlers(iframe, {
                    load: this._onload$delegate
                });
                this._iframe = iframe;
                document.body.appendChild(this._iframe);
                iframe.contentWindow.name = this._iframeName;
            } else {
                this._removeIframe();
                var internalErrorMessage = Sys.Extended.UI.Resources.AsyncFileUpload_InternalErrorMessage;
                this._onError(internalErrorMessage);
            }
        } catch (ex) {
            this._onError(ex.message);
        }
    },

    _stopLoad: function(result) {
        var mainForm = document.getElementById(this._formName);
        this._removeTimer();
        this.setThrobber(false);
        mainForm.target = "_top";
        mainForm.action = this._postBackUrl;
        var length;
        var contentType = "";
        var temp = result.split("------");
        if (temp.length > 0) {
            if (temp[0] == "error") {
                this._onError(temp[1]);
                return;
            }
            length = parseInt(temp[0]);
        }
        if (temp.length > 1) {
            contentType = temp[1];
        }
        if (this.get_completeBackColor() != "") {
            if (this._innerTB != null) {
                this._innerTB.style.backgroundColor = this.get_completeBackColor();
            } else {
                this._inputFile.style.backgroundColor = this.get_completeBackColor();
            }
        }
        this.raiseUploadComplete(new Sys.Extended.UI.AsyncFileUploadEventArgs(this._inputFile.value, length, contentType, null));
    },

    _onload: function(e) {
        var cleanup = true;
        var uploader = this;
        var mainForm = document.getElementById(this._formName);
        try {
            var frameDocument = this._iframe.contentWindow.document;
            if (frameDocument == null || frameDocument.location == null) {
                var e = { "message": Sys.Extended.UI.Resources.AsyncFileUpload_UploadingProblem };
                throw (e);
            } else if (frameDocument.location.href == 'about:blank') {
                this._removeTimer();
                if (this.get_uploadingBackColor() != "") {
                    if (this._innerTB != null) {
                        this._innerTB.style.backgroundColor = this.get_uploadingBackColor();
                    } else {
                        this._inputFile.style.backgroundColor = this.get_uploadingBackColor();
                    }
                }

                var valid = this._onStart(this._inputFile.value);
                if (valid) {
                    var url = this._postBackUrl;
                    url += url.indexOf("?") === -1 ? "?" : "&";
                    mainForm.action = url + 'AsyncFileUploadID=' + this.get_element().id + '&rnd=' + Math.random().toString().replace(/\./g, "");
                    mainForm.target = this._iframeName;
                    cleanup = false;
                    this.setThrobber(true);
                    setTimeout(function() {
                        mainForm.submit();
                        uploader._waitTimer = setTimeout(function() { uploader._wait() }, 100);
                    }, 0);
                    return true;
                }
            } else {
                //----------------------------------------
                if (frameDocument.body.innerHTML == "") {
                    return true;
                }
//                if (this._waitTimer == null) {
//                    setTimeout(function() { uploader._removeIframe(); }, 100);
//                    return true;
//                }
                //----------------------------------------
                var result = frameDocument.getElementById(this.get_element().id);
                var length;
                var contentType = "";
                if (result != null) {
                    var temp = result.innerHTML.split("------");
                    if (temp.length > 0) {
                        if (temp[0] == "error") {
                            var e = { "message": temp[1] };
                            throw (e);
                        }
                        length = parseInt(temp[0]);
                    }
                    if (temp.length > 1) {
                        contentType = temp[1];
                    }
                } else {
                    var serverError = Sys.Extended.UI.Resources.AsyncFileUpload_UnknownServerError;
                    function replace_func(p0, p1) {
                        serverError = p1;
                        return "";
                    }
                    frameDocument.body.innerHTML.replace(/Exception\]:([^\n\r]+)[\n\r]/, replace_func);
                    var exMessage = Sys.Extended.UI.Resources.AsyncFileUpload_ServerResponseError + ": '" + serverError + "'";
                    var ret = confirm(exMessage + "\n\n" + Sys.Extended.UI.Resources.AsyncFileUpload_ConfirmToSeeErrorPage);
                    if (ret) {
                        var handle = window.open("", "NotFoundInAnswer", "toolbar=0,status=1,scrollbars=1,resizable=1,width=600,height=400");
                        function onOpen() {
                            try {
                                if (!handle.document)
                                    setTimeout(onOpen, 100);
                            }
                            catch (e) { return; }
                            var _doc = handle.document;
                            _doc.open();
                            _doc.write("<body>" + frameDocument.body.innerHTML + "</body>");
                            _doc.close();
                        }
                        setTimeout(onOpen, 0);
                    }
                    var e = { "message": exMessage };
                    throw (e);
                }

                this._removeTimer();
                mainForm.target = "_top";
                mainForm.action = this._postBackUrl;
                if (this.get_completeBackColor() != "") {
                    if (this._innerTB != null) {
                        this._innerTB.style.backgroundColor = this.get_completeBackColor();
                    } else {
                        this._inputFile.style.backgroundColor = this.get_completeBackColor();
                    }
                }
                this.setThrobber(false);
                this.raiseUploadComplete(new Sys.Extended.UI.AsyncFileUploadEventArgs(this._inputFile.value, length, contentType, null));
            }
        }
        catch (ex) {
            this._removeTimer();
            mainForm.target = "_top";
            mainForm.action = this._postBackUrl;
            this._onError(ex.message);
        }
        finally {
            if (cleanup) {
                setTimeout(function() { uploader._removeIframe(); }, 100);
            }
        }
    },

    _wait: function() {
        if (this._waitTimer == null) {
            return;
        }
        var uploader = this;
        try {
            var frameDocument = this._iframe.contentWindow.document;
            var location = frameDocument.location;
            var href = location.href;
            this._waitTimer = setTimeout(function() { uploader._wait() }, 100);
        } catch (ex) {
            setTimeout(function() { uploader._removeIframe(); }, 100);
            setTimeout(function() { uploader._onError(Sys.Extended.UI.Resources.AsyncFileUpload_UploadingProblem); }, 0);
            this._waitTimer = null;
        }
    }
}

Sys.Extended.UI.AsyncFileUpload.registerClass("Sys.Extended.UI.AsyncFileUpload", Sys.Extended.UI.ControlBase);

Sys.Extended.UI.AsyncFileUploadEventArgs = function(fileName, length, contentType, errorMessage) {
    if (arguments.length != 4) throw Error.parameterCount();

    //Calling the base class constructor
    Sys.Extended.UI.AsyncFileUploadEventArgs.initializeBase(this);
    this._fileName = fileName;
    this._length = length;
    this._contentType = contentType;
    this._errorMessage = errorMessage;
}

Sys.Extended.UI.AsyncFileUploadEventArgs.prototype =
{
    get_fileName: function() {
        var slashPos = this._fileName.lastIndexOf("/");
        var backSlashPos = this._fileName.lastIndexOf("\\");

        var fileName = this._fileName.substr(((slashPos > backSlashPos) ? slashPos : backSlashPos) + 1);
        return fileName;
    },
    get_path: function() {
        return this._fileName;
    },
    get_length: function() {
        return this._length;
    },
    get_contentType: function() {
    return this._contentType;
    },
    get_errorMessage: function() {
        return this._errorMessage;
    }
}

Sys.Extended.UI.AsyncFileUploadEventArgs.registerClass('Sys.Extended.UI.AsyncFileUploadEventArgs', Sys.EventArgs);<commit_msg>Superexpert: Fixed issue 26898 AsyncFileUploader doesn't work in Firefox 4<commit_after>Type.registerNamespace("Sys.Extended.UI");

Sys.Extended.UI.AsyncFileUpload = function (element) {
    Sys.Extended.UI.AsyncFileUpload.initializeBase(this, [element]);

    this._hiddenField = null;
    this._inputFile = null;
    this._innerTB = null;
    this._postBackUrl = "";
    this._formName = "";
    this._iframe = null;
    this._waitTimer = null;
    this._completeBackColor = "";
    this._uploadingBackColor = "";
    this._errorBackColor = "";
    this._throbber = null;

    this._onchange$delegate = null;
    this._onload$delegate = null;
    this._app_onload$delegate = Function.createDelegate(this, this._app_onload);
    this._onmouseup$delegate = null;
}

Sys.Extended.UI.AsyncFileUpload.prototype = {

    get_throbber: function () {
        return this._throbber;
    },
    set_throbber: function (value) {
        this._throbber = value;
    },

    get_completeBackColor: function () {
        return this._completeBackColor;
    },
    set_completeBackColor: function (value) {
        this._completeBackColor = value;
    },

    get_errorBackColor: function () {
        return this._errorBackColor;
    },
    set_errorBackColor: function (value) {
        this._errorBackColor = value;
    },

    get_uploadingBackColor: function () {
        return this._uploadingBackColor;
    },
    set_uploadingBackColor: function (value) {
        this._uploadingBackColor = value;
    },

    get_inputFile: function () {
        return this._inputFile;
    },
    set_inputFile: function (value) {
        this._inputFile = value;
    },

    get_hiddenField: function () {
        return this._hiddenField;
    },
    set_hiddenField: function (value) {
        this._hiddenField = value;
    },

    get_innerTB: function () {
        return this._innerTB;
    },
    set_innerTB: function (value) {
        this._innerTB = value;
    },

    get_postBackUrl: function () {
        return this._postBackUrl;
    },
    set_postBackUrl: function (value) {
        this._postBackUrl = value;
    },

    get_formName: function () {
        return this._formName;
    },
    set_formName: function (value) {
        this._formName = value;
    },

    add_uploadStarted: function (handler) {
        this.get_events().addHandler("uploadStarted", handler);
    },
    remove_uploadStarted: function (handler) {
        this.get_events().removeHandler("uploadStarted", handler);
    },
    raiseUploadStarted: function (e) {
        var eh = this.get_events().getHandler("uploadStarted");
        if (eh) {
            return eh(this, e);
        }
        return true;
    },

    add_uploadComplete: function (handler) {
        this.get_events().addHandler("uploadComplete", handler);
    },
    remove_uploadComplete: function (handler) {
        this.get_events().removeHandler("uploadComplete", handler);
    },
    raiseUploadComplete: function (e) {
        var eh = this.get_events().getHandler("uploadComplete");
        if (eh) {
            eh(this, e);
        }
    },

    add_uploadError: function (handler) {
        this.get_events().addHandler("uploadError", handler);
    },
    remove_uploadError: function (handler) {
        this.get_events().removeHandler("uploadError", handler);
    },
    raiseUploadError: function (e) {
        var eh = this.get_events().getHandler("uploadError");
        if (eh) {
            eh(this, e);
            return true;
        }
        return false;
    },

    setThrobber: function (value) {
        if (this.get_throbber() != null) {
            this.get_throbber().style.display = value ? "" : "none";
        }
    },

    _onStart: function (fileName) {
        var valid = this.raiseUploadStarted(new Sys.Extended.UI.AsyncFileUploadEventArgs(fileName, null, null, null));
        if (typeof valid == 'undefined') {
            valid = true;
        }

        return valid;
    },

    initialize: function () {
        Sys.Extended.UI.AsyncFileUpload.callBaseMethod(this, "initialize");
        Sys.Application.add_load(this._app_onload$delegate);
        this._iframeName = this.get_element() + "_iframe";
        this.setThrobber(false);
    },

    dispose: function () {
        Sys.Application.remove_load(this._app_onload$delegate);
        if (this._onchange$delegate != null) {
            $common.removeHandlers(this._inputFile, {
                change: this._onchange$delegate
            });
            this._onchange$delegate = null;
        }
        if (this._onmouseup$delegate != null) {
            $common.removeHandlers(this._inputFile, {
                mouseup: this._onmouseup$delegate
            });
            this._onmouseup$delegate = null;
        }
        this._removeIframe();
        Sys.Extended.UI.AsyncFileUpload.callBaseMethod(this, "dispose");
    },

    _onmouseup: function () {
        var inputFile = this._inputFile;
        setTimeout(function () { inputFile.blur(); }, 0);
        return true;
    },

    _app_onload: function (sender, e) {
        this.setThrobber(false);
        if (this._inputFile != null) {
            if (this._onchange$delegate == null) {
                this._onchange$delegate = Function.createDelegate(this, this._onchange);
                $addHandlers(this._inputFile, {
                    change: this._onchange$delegate
                });
            }
            if (Sys.Browser.agent == Sys.Browser.Firefox) {
                this._inputFile.size = 1;
                var width = this._inputFile.offsetWidth;
                this._inputFile.style.width = "";
                while (this._inputFile.offsetWidth < width) {
                    this._inputFile.size++;
                }
            }
            if (this._innerTB != null) {
                this._inputFile.blur();
                var inputFile = this._inputFile;
                setTimeout(function () { inputFile.blur(); }, 0);
                this._innerTB.style.width = (this._inputFile.offsetWidth - 107) + "px";
                this._inputFile.parentNode.style.width = this._inputFile.offsetWidth + "px";
                if (Sys.Browser.agent == Sys.Browser.InternetExplorer) {
                    this._onmouseup$delegate = Function.createDelegate(this, this._onmouseup);
                    $addHandlers(this._inputFile, {
                        mouseup: this._onmouseup$delegate
                    });
                }
            }
        }
    },

    _removeIframe: function () {
        this._removeTimer();
        if (this._iframe != null) {
            if (this._onload$delegate != null) {
                $common.removeHandlers(this._iframe, {
                    load: this._onload$delegate
                });
                this._onload$delegate = null;
            }
            document.body.removeChild(this._iframe);
            this._iframe = null;
        }
    },

    _removeTimer: function () {
        if (this._waitTimer != null) {
            window.clearTimeout(this._waitTimer);
            this._waitTimer = null;
        }
    },

    _onError: function (error) {
        var unhandledException = Sys.Extended.UI.Resources.AsyncFileUpload_UnhandledException;
        this.setThrobber(false);

        if (this.get_errorBackColor() != "") {
            if (this._innerTB != null) {
                this._innerTB.style.backgroundColor = this.get_errorBackColor();
            } else {
                this._inputFile.style.backgroundColor = this.get_errorBackColor();
            }
        }
        if (!this.raiseUploadError(new Sys.Extended.UI.AsyncFileUploadEventArgs(this._inputFile.value, null, null, error))) {
            alert(unhandledException + ": " + error);
        }
    },

    _onchange: function (e) {
        var value = this._inputFile.value;
        if (value == "") {
            return;
        }
        if (this._innerTB != null) {
            this._innerTB.value = value;
        }
        if (this._hiddenField != null) {
            this._hiddenField.value = value;
        }

        try {
            if (this._iframe == null) {
                this._onload$delegate = Function.createDelegate(this, this._onload);
                var iframe = document.createElement("IFRAME");
                iframe.width = "0";
                iframe.height = "0";
                iframe.style.display = "none";
                iframe.src = "about:blank";
                iframe.id = this._iframeName;
                iframe.name = this._iframeName;
                $addHandlers(iframe, {
                    load: this._onload$delegate
                });
                this._iframe = iframe;
                document.body.appendChild(this._iframe);
                iframe.contentWindow.name = this._iframeName;
            } else {
                this._removeIframe();
                var internalErrorMessage = Sys.Extended.UI.Resources.AsyncFileUpload_InternalErrorMessage;
                this._onError(internalErrorMessage);
            }
        } catch (ex) {
            this._onError(ex.message);
        }
    },

    _stopLoad: function (result) {
        var mainForm = document.getElementById(this._formName);
        this._removeTimer();
        this.setThrobber(false);
        mainForm.target = "_top";
        mainForm.action = this._postBackUrl;
        var length;
        var contentType = "";
        var temp = result.split("------");
        if (temp.length > 0) {
            if (temp[0] == "error") {
                this._onError(temp[1]);
                return;
            }
            length = parseInt(temp[0]);
        }
        if (temp.length > 1) {
            contentType = temp[1];
        }
        if (this.get_completeBackColor() != "") {
            if (this._innerTB != null) {
                this._innerTB.style.backgroundColor = this.get_completeBackColor();
            } else {
                this._inputFile.style.backgroundColor = this.get_completeBackColor();
            }
        }
        this.raiseUploadComplete(new Sys.Extended.UI.AsyncFileUploadEventArgs(this._inputFile.value, length, contentType, null));
    },

    _onload: function (e) {
        var cleanup = true;
        var uploader = this;
        var mainForm = document.getElementById(this._formName);
        try {
            var frameDocument = this._iframe.contentWindow.document;
            if (frameDocument == null || frameDocument.location == null) {
                var e = { "message": Sys.Extended.UI.Resources.AsyncFileUpload_UploadingProblem };
                throw (e);
            } else if (frameDocument.location.href == 'about:blank') {
                this._removeTimer();
                if (this.get_uploadingBackColor() != "") {
                    if (this._innerTB != null) {
                        this._innerTB.style.backgroundColor = this.get_uploadingBackColor();
                    } else {
                        this._inputFile.style.backgroundColor = this.get_uploadingBackColor();
                    }
                }

                var valid = this._onStart(this._inputFile.value);
                if (valid) {
                    var url = this._postBackUrl;
                    url += url.indexOf("?") === -1 ? "?" : "&";
                    mainForm.action = url + 'AsyncFileUploadID=' + this.get_element().id + '&rnd=' + Math.random().toString().replace(/\./g, "");
                    mainForm.target = this._iframeName;
                    cleanup = false;
                    this.setThrobber(true);
                    setTimeout(function () {
                        mainForm.submit();
                        uploader._waitTimer = setTimeout(function () { uploader._wait() }, 100);
                    }, 0);
                    return true;
                }
            } else {
                //----------------------------------------
                if (frameDocument.body.innerHTML == "") {
                    return true;
                }
                //                if (this._waitTimer == null) {
                //                    setTimeout(function() { uploader._removeIframe(); }, 100);
                //                    return true;
                //                }
                //----------------------------------------
                var result = frameDocument.getElementById(this.get_element().id);
                var length;
                var contentType = "";
                if (result != null) {
                    var temp = result.innerHTML.split("------");
                    if (temp.length > 0) {
                        if (temp[0] == "error") {
                            var e = { "message": temp[1] };
                            throw (e);
                        }
                        length = parseInt(temp[0]);
                    }
                    if (temp.length > 1) {
                        contentType = temp[1];
                    }
                } else {
                    var serverError = Sys.Extended.UI.Resources.AsyncFileUpload_UnknownServerError;
                    function replace_func(p0, p1) {
                        serverError = p1;
                        return "";
                    }
                    frameDocument.body.innerHTML.replace(/Exception\]:([^\n\r]+)[\n\r]/, replace_func);
                    var exMessage = Sys.Extended.UI.Resources.AsyncFileUpload_ServerResponseError + ": '" + serverError + "'";
                    var ret = confirm(exMessage + "\n\n" + Sys.Extended.UI.Resources.AsyncFileUpload_ConfirmToSeeErrorPage);
                    if (ret) {
                        var handle = window.open("", "NotFoundInAnswer", "toolbar=0,status=1,scrollbars=1,resizable=1,width=600,height=400");
                        function onOpen() {
                            try {
                                if (!handle.document)
                                    setTimeout(onOpen, 100);
                            }
                            catch (e) { return; }
                            var _doc = handle.document;
                            _doc.open();
                            _doc.write("<body>" + frameDocument.body.innerHTML + "</body>");
                            _doc.close();
                        }
                        setTimeout(onOpen, 0);
                    }
                    var e = { "message": exMessage };
                    throw (e);
                }

                this._removeTimer();
                mainForm.target = "_top";
                mainForm.action = this._postBackUrl;
                if (this.get_completeBackColor() != "") {
                    if (this._innerTB != null) {
                        this._innerTB.style.backgroundColor = this.get_completeBackColor();
                    } else {
                        this._inputFile.style.backgroundColor = this.get_completeBackColor();
                    }
                }
                this.setThrobber(false);
                this.raiseUploadComplete(new Sys.Extended.UI.AsyncFileUploadEventArgs(this._inputFile.value, length, contentType, null));
            }
        }
        catch (ex) {
            this._removeTimer();
            mainForm.target = "_top";
            mainForm.action = this._postBackUrl;
            this._onError(ex.message);
        }
        finally {
            if (cleanup) {
                setTimeout(function () { uploader._removeIframe(); }, 100);
            }
        }
    },

    _wait: function () {
        if (this._waitTimer == null) {
            return;
        }
        var uploader = this;
        try {
            var frameDocument = this._iframe.contentWindow.document;
            var location = frameDocument.location;
            var href = location.href;
            this._waitTimer = setTimeout(function () { uploader._wait() }, 100);
        } catch (ex) {
            setTimeout(function () { uploader._removeIframe(); }, 100);
            setTimeout(function () { uploader._onError(Sys.Extended.UI.Resources.AsyncFileUpload_UploadingProblem); }, 0);
            this._waitTimer = null;
        }
    }
}

Sys.Extended.UI.AsyncFileUpload.registerClass("Sys.Extended.UI.AsyncFileUpload", Sys.Extended.UI.ControlBase);

Sys.Extended.UI.AsyncFileUploadEventArgs = function (fileName, length, contentType, errorMessage) {
    if (arguments.length != 4) throw Error.parameterCount();

    //Calling the base class constructor
    Sys.Extended.UI.AsyncFileUploadEventArgs.initializeBase(this);
    this._fileName = fileName;
    this._length = length;
    this._contentType = contentType;
    this._errorMessage = errorMessage;
}

Sys.Extended.UI.AsyncFileUploadEventArgs.prototype =
{
    get_fileName: function () {
        var slashPos = this._fileName.lastIndexOf("/");
        var backSlashPos = this._fileName.lastIndexOf("\\");

        var fileName = this._fileName.substr(((slashPos > backSlashPos) ? slashPos : backSlashPos) + 1);
        return fileName;
    },
    get_path: function () {
        return this._fileName;
    },
    get_length: function () {
        return this._length;
    },
    get_contentType: function () {
        return this._contentType;
    },
    get_errorMessage: function () {
        return this._errorMessage;
    }
}

Sys.Extended.UI.AsyncFileUploadEventArgs.registerClass('Sys.Extended.UI.AsyncFileUploadEventArgs', Sys.EventArgs);<|endoftext|>


<commit_before>/**
* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
*/
;(function(window, document) {
/*jshint evil:true */
  /** version */
  var version = '3.7.3';

  /** Preset options */
  var options = window.html5 || {};

  /** Used to skip problem elements */
  var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i;

  /** Not all elements can be cloned in IE **/
  var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i;

  /** Detect whether the browser supports default html5 styles */
  var supportsHtml5Styles;

  /** Name of the expando, to work with multiple documents or to re-shiv one document */
  var expando = '_html5shiv';

  /** The id for the the documents expando */
  var expanID = 0;

  /** Cached data for each document */
  var expandoData = {};

  /** Detect whether the browser supports unknown elements */
  var supportsUnknownElements;

  (function() {
    try {
        var a = document.createElement('a');
        a.innerHTML = '<xyz></xyz>';
        //if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles
        supportsHtml5Styles = ('hidden' in a);

        supportsUnknownElements = a.childNodes.length == 1 || (function() {
          // assign a false positive if unable to shiv
          (document.createElement)('a');
          var frag = document.createDocumentFragment();
          return (
            typeof frag.cloneNode == 'undefined' ||
            typeof frag.createDocumentFragment == 'undefined' ||
            typeof frag.createElement == 'undefined'
          );
        }());
    } catch(e) {
      // assign a false positive if detection fails => unable to shiv
      supportsHtml5Styles = true;
      supportsUnknownElements = true;
    }

  }());

  /*--------------------------------------------------------------------------*/

  /**
   * Creates a style sheet with the given CSS text and adds it to the document.
   * @private
   * @param {Document} ownerDocument The document.
   * @param {String} cssText The CSS text.
   * @returns {StyleSheet} The style element.
   */
  function addStyleSheet(ownerDocument, cssText) {
    var p = ownerDocument.createElement('p'),
        parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement;

    p.innerHTML = 'x<style>' + cssText + '</style>';
    return parent.insertBefore(p.lastChild, parent.firstChild);
  }

  /**
   * Returns the value of `html5.elements` as an array.
   * @private
   * @returns {Array} An array of shived element node names.
   */
  function getElements() {
    var elements = html5.elements;
    return typeof elements == 'string' ? elements.split(' ') : elements;
  }

  /**
   * Extends the built-in list of html5 elements
   * @memberOf html5
   * @param {String|Array} newElements whitespace separated list or array of new element names to shiv
   * @param {Document} ownerDocument The context document.
   */
  function addElements(newElements, ownerDocument) {
    var elements = html5.elements;
    if(typeof elements != 'string'){
      elements = elements.join(' ');
    }
    if(typeof newElements != 'string'){
      newElements = newElements.join(' ');
    }
    html5.elements = elements +' '+ newElements;
    shivDocument(ownerDocument);
  }

   /**
   * Returns the data associated to the given document
   * @private
   * @param {Document} ownerDocument The document.
   * @returns {Object} An object of data.
   */
  function getExpandoData(ownerDocument) {
    var data = expandoData[ownerDocument[expando]];
    if (!data) {
        data = {};
        expanID++;
        ownerDocument[expando] = expanID;
        expandoData[expanID] = data;
    }
    return data;
  }

  /**
   * returns a shived element for the given nodeName and document
   * @memberOf html5
   * @param {String} nodeName name of the element
   * @param {Document|DocumentFragment} ownerDocument The context document.
   * @returns {Object} The shived element.
   */
  function createElement(nodeName, ownerDocument, data){
    if (!ownerDocument) {
        ownerDocument = document;
    }
    if(supportsUnknownElements){
        return ownerDocument.createElement(nodeName);
    }
    if (!data) {
        data = getExpandoData(ownerDocument);
    }
    var node;

    if (data.cache[nodeName]) {
        node = data.cache[nodeName].cloneNode();
    } else if (saveClones.test(nodeName)) {
        node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode();
    } else {
        node = data.createElem(nodeName);
    }

    // Avoid adding some elements to fragments in IE < 9 because
    // * Attributes like `name` or `type` cannot be set/changed once an element
    //   is inserted into a document/fragment
    // * Link elements with `src` attributes that are inaccessible, as with
    //   a 403 response, will cause the tab/window to crash
    // * Script elements appended to fragments will execute when their `src`
    //   or `text` property is set
    return node.canHaveChildren && !reSkip.test(nodeName) && !node.tagUrn ? data.frag.appendChild(node) : node;
  }

  /**
   * returns a shived DocumentFragment for the given document
   * @memberOf html5
   * @param {Document} ownerDocument The context document.
   * @returns {Object} The shived DocumentFragment.
   */
  function createDocumentFragment(ownerDocument, data){
    if (!ownerDocument) {
        ownerDocument = document;
    }
    if(supportsUnknownElements){
        return ownerDocument.createDocumentFragment();
    }
    data = data || getExpandoData(ownerDocument);
    var clone = data.frag.cloneNode(),
        i = 0,
        elems = getElements(),
        l = elems.length;
    for(;i<l;i++){
        clone.createElement(elems[i]);
    }
    return clone;
  }

  /**
   * Shivs the `createElement` and `createDocumentFragment` methods of the document.
   * @private
   * @param {Document|DocumentFragment} ownerDocument The document.
   * @param {Object} data of the document.
   */
  function shivMethods(ownerDocument, data) {
    if (!data.cache) {
        data.cache = {};
        data.createElem = ownerDocument.createElement;
        data.createFrag = ownerDocument.createDocumentFragment;
        data.frag = data.createFrag();
    }

    ownerDocument.createElement = function(nodeName) {
      //abort shiv
      if (!html5.shivMethods) {
          return data.createElem(nodeName);
      }
      return createElement(nodeName, ownerDocument, data);
    };

    ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' +
      'var n=f.cloneNode(),c=n.createElement;' +
      'h.shivMethods&&(' +
        // unroll the `createElement` calls
        getElements().join().replace(/[\w\-:]+/g, function(nodeName) {
          data.createElem(nodeName);
          data.frag.createElement(nodeName);
          return 'c("' + nodeName + '")';
        }) +
      ');return n}'
    )(html5, data.frag);
  }

  /*--------------------------------------------------------------------------*/

  /**
   * Shivs the given document.
   * @memberOf html5
   * @param {Document} ownerDocument The document to shiv.
   * @returns {Document} The shived document.
   */
  function shivDocument(ownerDocument) {
    if (!ownerDocument) {
        ownerDocument = document;
    }
    var data = getExpandoData(ownerDocument);

    if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) {
      data.hasCSS = !!addStyleSheet(ownerDocument,
        // corrects block display not defined in IE6/7/8/9
        'article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}' +
        // adds styling not present in IE6/7/8/9
        'mark{background:#FF0;color:#000}' +
        // hides non-rendered elements
        'template{display:none}'
      );
    }
    if (!supportsUnknownElements) {
      shivMethods(ownerDocument, data);
    }
    return ownerDocument;
  }

  /*--------------------------------------------------------------------------*/

  /**
   * The `html5` object is exposed so that more elements can be shived and
   * existing shiving can be detected on iframes.
   * @type Object
   * @example
   *
   * // options can be changed before the script is included
   * html5 = { 'elements': 'mark section', 'shivCSS': false, 'shivMethods': false };
   */
  var html5 = {

    /**
     * An array or space separated string of node names of the elements to shiv.
     * @memberOf html5
     * @type Array|String
     */
    'elements': options.elements || 'abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video',

    /**
     * current version of html5shiv
     */
    'version': version,

    /**
     * A flag to indicate that the HTML5 style sheet should be inserted.
     * @memberOf html5
     * @type Boolean
     */
    'shivCSS': (options.shivCSS !== false),

    /**
     * Is equal to true if a browser supports creating unknown/HTML5 elements
     * @memberOf html5
     * @type boolean
     */
    'supportsUnknownElements': supportsUnknownElements,

    /**
     * A flag to indicate that the document's `createElement` and `createDocumentFragment`
     * methods should be overwritten.
     * @memberOf html5
     * @type Boolean
     */
    'shivMethods': (options.shivMethods !== false),

    /**
     * A string to describe the type of `html5` object ("default" or "default print").
     * @memberOf html5
     * @type String
     */
    'type': 'default',

    // shivs the document according to the specified `html5` object options
    'shivDocument': shivDocument,

    //creates a shived element
    createElement: createElement,

    //creates a shived documentFragment
    createDocumentFragment: createDocumentFragment,

    //extends list of elements
    addElements: addElements
  };

  /*--------------------------------------------------------------------------*/

  // expose html5
  window.html5 = html5;

  // shiv the document
  shivDocument(document);

  if(typeof module == 'object' && module.exports){
    module.exports = html5;
  }

}(typeof window !== "undefined" ? window : this, document));
<commit_msg>Why was this still here?<commit_after><|endoftext|>


<commit_before>//- JavaScript source code

//- qspec.js ~~
//
//  Jasmine (http://pivotal.github.com/jasmine/) BDD Specs for Quanah, written
//  in an effort to:
//    * Provide a degree of documentation
//    * Learn the damn thing
//    * Provide a way to catch changes made in Quanah's API
//
//  The actually interesting, i.e. expressive of Quanah's use, code takes place in
//  the describe(...) blocks; everything prior is just helpers.
//
//                                                      ~~ (c) DER, 6 Apr 2012

(function(){
  "use strict";
  var getAvars, toType, onerror;

  // Pragmas for JSHint
  /*globals describe:false it:false beforeEach:false expect:false Q:false*/
  /*globals jasmine:false console:false*/

  // Utility Additions and functions
  getAvars = function getAvars(){
    // Returns an avar whose val is an array of avars, with one for each
    // of the arguments (or each element of the first argument if it is
    // an array.
    var avars = [], arg, args, i, temp;
    if ( toType(arguments[0]) === "array" ) args = arguments[0];
    else args = arguments;
    for ( i in args) {
      if ( args.hasOwnProperty(i) === false ) continue;
      arg = args[i];
      temp = Q.avar({ val:arg });
      temp.onerror = onerror;
      avars.push(temp);
    }
    temp = Q.avar({ val:avars });
    temp.onerror = onerror;
    return temp;
  };

  toType = function toType(obj) {
        return ({}).toString.call(obj).match(/\s([a-z|A-Z]+)/)[1].toLowerCase();
  };

  onerror = function (msg) {
    console.error(msg);
  };

  beforeEach(function(){

    var customMatchers, setMatcherMessage;

    setMatcherMessage = function(message, matcher_context){
          matcher_context.message = function(){return message;};
    };

    customMatchers = {};

    customMatchers.toBeA = function toBeA(expected_type){
      return toType(this.actual) === expected_type;
    };

    customMatchers.toBeAFunction = function toBeAFunction(){
      return toType(this.actual) === 'function';
    };

    customMatchers.toBeAObject = function toBeAObject(){
      return toType(this.actual) === 'object';
    };

    customMatchers.toBeAUuid = function toBeAUuid(){
      return (this.actual.match(/[0-9abcdef]{32}/)) !== null;
    };

    customMatchers.toContainPrefixes = function toContainPrefixes(expected){
      var key;
      for (key in expected){
        if (expected.hasOwnProperty(key) && this.actual[key] !== expected[key]){
          setMatcherMessage(
              "Expected "+this.actual[key]+" to be "+expected[key]+", with prefix "+key+".",
              this
          );
          return false;
        }
      }
      return true;
    };

    this.addMatchers(customMatchers);

  });

  // The Overall Spec
  describe("Quanah", function(){

    it("should be awesome", function(){
      expect(true).toBeTruthy();
    });

    it("should place function Q on the Object prototype", function(){
      expect(Object.prototype.hasOwnProperty('Q')).toBeTruthy();
    });

    it("shoud provide the quanah API", function(){
      //Needs a better "should" string...
      var api, thing;
      api = {
        avar : 'function',
        ply : 'function',
        map : 'function',
        reduce : 'function',
        when : 'function'
      };
      for ( thing in api ){
        if (api.hasOwnProperty(thing)){
          expect(typeof Q[thing]).toBe(api[thing]);
        }
      }
    });

  });

  describe("Quanah Avars", function(){

    describe("Avar Creation", function(){

      it("should allow creation of Avars with no spec", function(){
        var x = Q.avar();
        expect(x).toBeAObject();
        expect(x.key).toBeAUuid();
        expect(x.val).toBeNull();
      });

      it("should allow creation of Avars with only a key", function(){
        var x = Q.avar({ key : "a" });
        expect(x).toBeAObject();
        expect(x.key).toEqual("a");
        expect(x.val).toBeNull();
      });

      it("should allow creation of Avars with only a val", function(){
        var x = Q.avar({ val : "a" });
        expect(x).toBeAObject();
        expect(x.key).toBeAUuid();
        expect(x.val).toEqual("a");
      });

      it("should allow creation of Avars with a key and val", function(){
        var x = Q.avar({ key : "a", val : 12345 });
        expect(x).toBeAObject();
        expect(x.key).toEqual("a");
        expect(x.val).toEqual(12345);
      });

      it("should allow creation of Avars with a stringified avar", function(){
        var x, y, z;
        x = Q.avar({ key : "a", val : 12345 });
        y = JSON.stringify(x);
        z = Q.avar(y);
        expect(x).toEqual(z);
      });

    });

    describe("Avar Access", function(){

      var avars, vals, i, spy;

      beforeEach(function(){
        vals = [1234, "1234", [1,2,3,4], {a:1, b:2}, function(){}];
        avars = getAvars(vals);
        spy = jasmine.createSpy();
      });

      xit("should be retrievable as JSON with toJSON()", function(){
        // Disabled until toJSON is better specified,
        // e.g. for functions as vals
        var x, spec;
        spec = { key : "a", val : "12345"};
        x = Q.avar(spec);
        expect(x.toJSON()).toEqual(spec);
        avars.onready = Q.ply(function(k,v){
          expect(v.toJSON().val).toEqual(vals[k]);
          spy();
        });
        expect(spy.callCount).toEqual(5);
      });

      it("should allow the value to be retrieved as a string with toString()", function(){
        avars.onready = Q.ply(function(k,v){
          expect(v.toString()).toEqual(vals[k].toString());
          spy();
        });
        expect(spy.callCount).toEqual(5);
      });

      it("should allow the value to be retrieved with valueOf()", function(){
        avars.onready = Q.ply(function(k,v){
          expect(v.valueOf()).toEqual(vals[k]);
          spy();
        });
        expect(spy.callCount).toEqual(5);
      });

    });

    describe("Avar execution", function(){

      var x, spy;

      beforeEach(function(){
        x = Q.avar();
        spy = jasmine.createSpy();
      });

      it("should allow computations to be run with Avar.onready", function(){
        x = Q.avar({ val:0 });
        x.onready = function (evt) {
          this.val += 1;
          evt.exit();
        };
        expect(x.val).toEqual(1);
      });

      it("should apply Avar.onready's sequentially", function(){
        x.onready = function (evt) {
          this.val = "dogs";
          evt.exit();
        };
        x.onready = function (evt) {
          expect(this.val).toEqual("dogs");
          this.val = "cats";
          evt.exit();
        };
        x.onready = function (evt) {
          expect(this.val).toEqual("cats");
          evt.exit();
        };
      });

      it("should allow an onready to pause execution using evt.stay()", function(){
        x.onready = function (evt) {
          this.val = "before";
          evt.exit();
        };
        x.onready = function (evt) {
          evt.stay();
        };
        x.onready = function (evt) {
          spy();
          evt.exit();
        };
        expect(spy).not.toHaveBeenCalled();
      });

      it("should not execute the next onready block if evt.exit() is not called", function(){
        x.onready = function (evt) {
          this.val = "value";
        };
        x.onready = function (evt) {
          spy();
          evt.exit();
        };
        expect(spy).not.toHaveBeenCalled();
      });

      it("should execute the onerror block if evt.fail() is called", function(){
        x.onerror = function (msg) {
          expect(msg).toEqual("Oh Noes!!");
          spy();
        };
        x.onready = function (evt) {
          evt.fail("Oh Noes!!");
        };
        expect(spy).toHaveBeenCalled();
      });

      it("should allow iteration over iterable avars with Q.ply", function(){
        var vals, avars, afterVals, i, doubleIt;
        vals = [[1,2,3,4], {a:1,b:2,c:3,d:4}];
        afterVals = [[2,4,6,8], {a:2,b:4,c:6,d:8}];
        avars = getAvars(vals);
        doubleIt = function (k,v) { this.val *= 2; };
        for ( i in vals ){
          if ( vals.hasOwnProperty(i) === false ) continue;
          avars[i].onready = Q.ply(doubleIt);
          avars[i].onready = function (evt) {
            expect(this.val).toEqual(afterVals[i]);
            evt.exit();
          }
        }
      });

    });

  });

}());
<commit_msg>Improve test of Q.ply()<commit_after>//- JavaScript source code

//- qspec.js ~~
//
//  Jasmine (http://pivotal.github.com/jasmine/) BDD Specs for Quanah, written
//  in an effort to:
//    * Provide a degree of documentation
//    * Learn the damn thing
//    * Provide a way to catch changes made in Quanah's API
//
//  The actually interesting, i.e. expressive of Quanah's use, code takes place in
//  the describe(...) blocks; everything prior is just helpers.
//
//                                                      ~~ (c) DER, 6 Apr 2012

(function(){
  "use strict";
  var getAvars, toType, onerror;

  // Pragmas for JSHint
  /*globals describe:false it:false beforeEach:false expect:false Q:false*/
  /*globals jasmine:false console:false*/

  // Utility Additions and functions
  getAvars = function getAvars(){
    // Returns an avar whose val is an array of avars, with one for each
    // of the arguments (or each element of the first argument if it is
    // an array.
    var avars = [], arg, args, i, temp;
    if ( toType(arguments[0]) === "array" ) args = arguments[0];
    else args = arguments;
    for ( i in args) {
      if ( args.hasOwnProperty(i) === false ) continue;
      arg = args[i];
      temp = Q.avar({ val:arg });
      temp.onerror = onerror;
      avars.push(temp);
    }
    temp = Q.avar({ val:avars });
    temp.onerror = onerror;
    return temp;
  };

  toType = function toType(obj) {
        return ({}).toString.call(obj).match(/\s([a-z|A-Z]+)/)[1].toLowerCase();
  };

  onerror = function (msg) {
    console.error(msg);
  };

  beforeEach(function(){

    var customMatchers, setMatcherMessage;

    setMatcherMessage = function(message, matcher_context){
          matcher_context.message = function(){return message;};
    };

    customMatchers = {};

    customMatchers.toBeA = function toBeA(expected_type){
      return toType(this.actual) === expected_type;
    };

    customMatchers.toBeAFunction = function toBeAFunction(){
      return toType(this.actual) === 'function';
    };

    customMatchers.toBeAObject = function toBeAObject(){
      return toType(this.actual) === 'object';
    };

    customMatchers.toBeAUuid = function toBeAUuid(){
      return (this.actual.match(/[0-9abcdef]{32}/)) !== null;
    };

    customMatchers.toContainPrefixes = function toContainPrefixes(expected){
      var key;
      for (key in expected){
        if (expected.hasOwnProperty(key) && this.actual[key] !== expected[key]){
          setMatcherMessage(
              "Expected "+this.actual[key]+" to be "+expected[key]+", with prefix "+key+".",
              this
          );
          return false;
        }
      }
      return true;
    };

    this.addMatchers(customMatchers);

  });

  // The Overall Spec
  describe("Quanah", function(){

    it("should be awesome", function(){
      expect(true).toBeTruthy();
    });

    it("should place function Q on the Object prototype", function(){
      expect(Object.prototype.hasOwnProperty('Q')).toBeTruthy();
    });

    it("shoud provide the quanah API", function(){
      //Needs a better "should" string...
      var api, thing;
      api = {
        avar : 'function',
        ply : 'function',
        map : 'function',
        reduce : 'function',
        when : 'function'
      };
      for ( thing in api ){
        if (api.hasOwnProperty(thing)){
          expect(typeof Q[thing]).toBe(api[thing]);
        }
      }
    });

  });

  describe("Quanah Avars", function(){

    describe("Avar Creation", function(){

      it("should allow creation of Avars with no spec", function(){
        var x = Q.avar();
        expect(x).toBeAObject();
        expect(x.key).toBeAUuid();
        expect(x.val).toBeNull();
      });

      it("should allow creation of Avars with only a key", function(){
        var x = Q.avar({ key : "a" });
        expect(x).toBeAObject();
        expect(x.key).toEqual("a");
        expect(x.val).toBeNull();
      });

      it("should allow creation of Avars with only a val", function(){
        var x = Q.avar({ val : "a" });
        expect(x).toBeAObject();
        expect(x.key).toBeAUuid();
        expect(x.val).toEqual("a");
      });

      it("should allow creation of Avars with a key and val", function(){
        var x = Q.avar({ key : "a", val : 12345 });
        expect(x).toBeAObject();
        expect(x.key).toEqual("a");
        expect(x.val).toEqual(12345);
      });

      it("should allow creation of Avars with a stringified avar", function(){
        var x, y, z;
        x = Q.avar({ key : "a", val : 12345 });
        y = JSON.stringify(x);
        z = Q.avar(y);
        expect(x).toEqual(z);
      });

    });

    describe("Avar Access", function(){

      var avars, vals, i, spy;

      beforeEach(function(){
        vals = [1234, "1234", [1,2,3,4], {a:1, b:2}, function(){}];
        avars = getAvars(vals);
        spy = jasmine.createSpy();
      });

      xit("should be retrievable as JSON with toJSON()", function(){
        // Disabled until toJSON is better specified,
        // e.g. for functions as vals
        var x, spec;
        spec = { key : "a", val : "12345"};
        x = Q.avar(spec);
        expect(x.toJSON()).toEqual(spec);
        avars.onready = Q.ply(function(k,v){
          expect(v.toJSON().val).toEqual(vals[k]);
          spy();
        });
        expect(spy.callCount).toEqual(5);
      });

      it("should allow the value to be retrieved as a string with toString()", function(){
        avars.onready = Q.ply(function(k,v){
          expect(v.toString()).toEqual(vals[k].toString());
          spy();
        });
        expect(spy.callCount).toEqual(5);
      });

      it("should allow the value to be retrieved with valueOf()", function(){
        avars.onready = Q.ply(function(k,v){
          expect(v.valueOf()).toEqual(vals[k]);
          spy();
        });
        expect(spy.callCount).toEqual(5);
      });

    });

    describe("Avar execution", function(){

      var x, spy;

      beforeEach(function(){
        x = Q.avar();
        spy = jasmine.createSpy();
      });

      it("should allow computations to be run with Avar.onready", function(){
        x = Q.avar({ val:0 });
        x.onready = function (evt) {
          this.val += 1;
          evt.exit();
        };
        expect(x.val).toEqual(1);
      });

      it("should apply Avar.onready's sequentially", function(){
        x.onready = function (evt) {
          this.val = "dogs";
          evt.exit();
        };
        x.onready = function (evt) {
          expect(this.val).toEqual("dogs");
          this.val = "cats";
          evt.exit();
        };
        x.onready = function (evt) {
          expect(this.val).toEqual("cats");
          evt.exit();
        };
      });

      it("should allow an onready to pause execution using evt.stay()", function(){
        x.onready = function (evt) {
          this.val = "before";
          evt.exit();
        };
        x.onready = function (evt) {
          evt.stay();
        };
        x.onready = function (evt) {
          spy();
          evt.exit();
        };
        expect(spy).not.toHaveBeenCalled();
      });

      it("should not execute the next onready block if evt.exit() is not called", function(){
        x.onready = function (evt) {
          this.val = "value";
        };
        x.onready = function (evt) {
          spy();
          evt.exit();
        };
        expect(spy).not.toHaveBeenCalled();
      });

      it("should execute the onerror block if evt.fail() is called", function(){
        x.onerror = function (msg) {
          expect(msg).toEqual("Oh Noes!!");
          spy();
        };
        x.onready = function (evt) {
          evt.fail("Oh Noes!!");
        };
        expect(spy).toHaveBeenCalled();
      });

      it("should allow iteration over iterable avars with Q.ply", function(){
        var vals, avars, afterVals, i, doubleIt, checkIt;
        vals = [[1,2,3,4], {a:1,b:2,c:3,d:4}];
        afterVals = [[2,4,6,8], {a:2,b:4,c:6,d:8}];
        avars = getAvars(vals).val;
        doubleIt = function (k,v) { this.val *= 2; };
        checkIt = function (i) {
          return function (evt) {
            expect(this.val).toEqual(afterVals[i]);
            spy();
            evt.exit();
          };
        };
        for ( i in vals ){ // Could be replaced with ply...but that would be cheating?
          if ( vals.hasOwnProperty(i) === false ) continue;
          avars[i].onready = Q.ply(doubleIt);
          avars[i].onready = checkIt(i);
        }
        expect(spy.callCount).toBe(2);
      });
      });

    });

  });

}());
<|endoftext|>


<commit_before>describe('core', function() {
  Backbone.history || (Backbone.history = new Backbone.History());
  Backbone.history.start();

  Handlebars.templates.parent = Handlebars.compile('
{{view child}}
');
  Handlebars.templates.child = Handlebars.compile('
{{value}}
');
  Handlebars.templates['extension-test.handlebars'] = Handlebars.compile('123');

  it("registry", function() {
    var ViewClass = Thorax.View.extend({name: 'a-name'}, {});
    expect(ViewClass.prototype.name).to.equal('a-name', 'sets a name attribute on view class');
    expect((new ViewClass()).name).to.equal('a-name', 'sets a name attribute on view instance');
    var viewClassB = ViewClass.extend({
      name: 'b-name',
      key: 'value'
    });
    expect(viewClassB.prototype.key).to.equal('value', 'can accept a class as a value');
    ViewClass.extend({
      name: 'b-name',
      key: 'value2'
    });
    expect(Thorax.Views['b-name'].prototype.key).to.equal('value2', 'will overwrite a previous class when passed a new one');
    Thorax.View.extend({
      name: 'a-name',
      key: 'value'
    });
    expect(Thorax.Views['a-name'].prototype.key).to.equal('value', 'registry will extend an existing class prototype');
  });

  it("can set view el", function() {
    $('body').append('

');
    var view = new Thorax.View({
      template: function() { return 'testing123'; },
      el: $('#test-target')[0]
    });
    view.render();
    expect($('#test-target-container > #test-target')[0].innerHTML).to.equal('testing123');
    expect(view.el.parentNode).to.equal($('#test-target-container')[0]);
    $('#test-target-container').remove();
  });

  it("should allow local helpers to be declared", function() {
    // register a global helper to ensure that it isn't overwritten
    Handlebars.registerHelper('globalHelper', function() {
      return '-';
    });

    var view = new Thorax.View({
      helpers: {
        test: function() {
          return this.key;
        },
        testWithArg: function(arg) {
          return this.key + arg;
        },
        testWithBlock: function(options) {
          return options.fn(options.context);
        }
      },
      key: 'value',
      template: Handlebars.compile('{{globalHelper}} {{test}} {{testWithArg "!"}} {{#testWithBlock}}{{key}}{{/testWithBlock}}')
    });
    view.render();
    expect(view.html()).to.equal('- value value! value');

    view = new Thorax.View({
      collection: new Thorax.Collection([{letter: 'a'}]),
      template: Handlebars.compile('{{#collection tag="ul"}}
{{globalHelper}} {{test letter}}
{{/collection}}'),
      helpers: {
        test: function(letter) {
          return letter + "!";
        }
      }
    });
    view.render();
    expect(view.$('li').html()).to.equal('- a!');
  });

  it("assign template by name", function() {
    var view = new Thorax.View({
      name: 'a',
      template: 'child',
      value: 'test'
    });
    view.render();
    expect(view.$('div').html()).to.equal('test');
  });

  it("template not found handling", function() {
    var view = new Thorax.View();
    expect(function() {
      view.render();
    }).to['throw']();
  });

  it("render() subclassing", function() {
    var a = new Thorax.View({
      render: function() {
        Thorax.View.prototype.render.call(this, '
a
');
      }
    });
    a.render();

    var b = new Thorax.View({
      render: function() {
        Thorax.View.prototype.render.call(this, $('
b
'));
      }
    });
    b.render();

    var c = new Thorax.View({
      render: function() {
        var el = document.createElement('p');
        el.innerHTML = 'c';
        Thorax.View.prototype.render.call(this, el);
      }
    });
    c.render();

    var d = new Thorax.View({
      render: function() {
        var view = new Thorax.View({
          render: function() {
            Thorax.View.prototype.render.call(this, '
d
');
          }
        });
        view.render();
        Thorax.View.prototype.render.call(this, view);
      }
    });
    d.render();

    expect(a._renderCount).to.equal(1, '_renderCount incrimented');
    expect(b._renderCount).to.equal(1, '_renderCount incrimented');
    expect(c._renderCount).to.equal(1, '_renderCount incrimented');
    expect(d._renderCount).to.equal(1, '_renderCount incrimented');
    expect(a.$('p').html()).to.equal('a', 'parent render accepts string');
    expect(b.$('p').html()).to.equal('b', 'parent render accepts dom array');
    expect(c.$('p').html()).to.equal('c', 'parent render accepts dom element');
    expect(d.$('p').html()).to.equal('d', 'parent render accepts view');
  });

  it("onException", function() {
    var oldOnException = Thorax.onException;
    var view = new Thorax.View({
      events: {
        test: function () {
          throw new Error('view error');
        },
        'click div': function() {
          throw new Error('dom error');
        }
      },
      template: Handlebars.compile('

')
    });
    view.render();
    document.body.appendChild(view.el);
    Thorax.onException = function(errorName) {
      expect(errorName.match(/click/)).to.exist;
    };
    view.$('div').trigger('click');
    Thorax.onException = function(errorName) {
      expect(errorName.match(/test/)).to.exist;
    };
    view.trigger('test');
    Thorax.onException = oldOnException;
    view.$el.remove();
  });

  describe('context', function() {
    it("may be an object", function() {
      var view = new (Thorax.View.extend({
        context: {
          a: 'a',
          b: 'b',
          c: function() {
            return 'c';
          }
        },
        template: Handlebars.compile('{{a}}{{b}}{{c}}')
      }))();
      view.render();
      expect(view.html()).to.equal('abc');
    });

    it("can return undefined", function() {
      var view = new Thorax.View({
        key: 'value',
        context: function() {
          return;
        },
        template: Handlebars.compile('{{key}}')
      });
      view.render();
      expect(view.html()).to.equal('value');
    });

    it("function is additive", function() {
      var view = new Thorax.View({
        a: 'a',
        context: function() {
          return {
            b: 'b'
          };
        },
        template: Handlebars.compile('{{a}}{{b}}')
      });
      view.render();
      expect(view.html()).to.equal('ab');
    });

    it("template helpers will not mutate view or model attributes", function() {
      Handlebars.registerHelper('modifyObject', function(obj) {
        obj.mutated = true;
        return obj;
      });
      var view = new Thorax.View({
        a: 'a',
        model: new Thorax.Model({
          b: 'b'
        }),
        template: Handlebars.compile('{{modifyObject a}}{{modifyObject b}}')
      });
      view.render();
      expect(view.a.mutated).to.be['undefined'];
      expect(view.model.attributes.b.mutated).to.be['undefined'];
      expect(view.html()).to.equal('ab');
    });
  });
});
<commit_msg>Add test to ensure that template cid differs from view cid<commit_after>describe('core', function() {
  Backbone.history || (Backbone.history = new Backbone.History());
  Backbone.history.start();

  Handlebars.templates.parent = Handlebars.compile('
{{view child}}
');
  Handlebars.templates.child = Handlebars.compile('
{{value}}
');
  Handlebars.templates['extension-test.handlebars'] = Handlebars.compile('123');

  it("registry", function() {
    var ViewClass = Thorax.View.extend({name: 'a-name'}, {});
    expect(ViewClass.prototype.name).to.equal('a-name', 'sets a name attribute on view class');
    expect((new ViewClass()).name).to.equal('a-name', 'sets a name attribute on view instance');
    var viewClassB = ViewClass.extend({
      name: 'b-name',
      key: 'value'
    });
    expect(viewClassB.prototype.key).to.equal('value', 'can accept a class as a value');
    ViewClass.extend({
      name: 'b-name',
      key: 'value2'
    });
    expect(Thorax.Views['b-name'].prototype.key).to.equal('value2', 'will overwrite a previous class when passed a new one');
    Thorax.View.extend({
      name: 'a-name',
      key: 'value'
    });
    expect(Thorax.Views['a-name'].prototype.key).to.equal('value', 'registry will extend an existing class prototype');
  });

  it("can set view el", function() {
    $('body').append('

');
    var view = new Thorax.View({
      template: function() { return 'testing123'; },
      el: $('#test-target')[0]
    });
    view.render();
    expect($('#test-target-container > #test-target')[0].innerHTML).to.equal('testing123');
    expect(view.el.parentNode).to.equal($('#test-target-container')[0]);
    $('#test-target-container').remove();
  });

  it("should allow local helpers to be declared", function() {
    // register a global helper to ensure that it isn't overwritten
    Handlebars.registerHelper('globalHelper', function() {
      return '-';
    });

    var view = new Thorax.View({
      helpers: {
        test: function() {
          return this.key;
        },
        testWithArg: function(arg) {
          return this.key + arg;
        },
        testWithBlock: function(options) {
          return options.fn(options.context);
        }
      },
      key: 'value',
      template: Handlebars.compile('{{globalHelper}} {{test}} {{testWithArg "!"}} {{#testWithBlock}}{{key}}{{/testWithBlock}}')
    });
    view.render();
    expect(view.html()).to.equal('- value value! value');

    view = new Thorax.View({
      collection: new Thorax.Collection([{letter: 'a'}]),
      template: Handlebars.compile('{{#collection tag="ul"}}
{{globalHelper}} {{test letter}}
{{/collection}}'),
      helpers: {
        test: function(letter) {
          return letter + "!";
        }
      }
    });
    view.render();
    expect(view.$('li').html()).to.equal('- a!');
  });

  it("assign template by name", function() {
    var view = new Thorax.View({
      name: 'a',
      template: 'child',
      value: 'test'
    });
    view.render();
    expect(view.$('div').html()).to.equal('test');
  });

  it("template not found handling", function() {
    var view = new Thorax.View();
    expect(function() {
      view.render();
    }).to['throw']();
  });

  it("render() subclassing", function() {
    var a = new Thorax.View({
      render: function() {
        Thorax.View.prototype.render.call(this, '
a
');
      }
    });
    a.render();

    var b = new Thorax.View({
      render: function() {
        Thorax.View.prototype.render.call(this, $('
b
'));
      }
    });
    b.render();

    var c = new Thorax.View({
      render: function() {
        var el = document.createElement('p');
        el.innerHTML = 'c';
        Thorax.View.prototype.render.call(this, el);
      }
    });
    c.render();

    var d = new Thorax.View({
      render: function() {
        var view = new Thorax.View({
          render: function() {
            Thorax.View.prototype.render.call(this, '
d
');
          }
        });
        view.render();
        Thorax.View.prototype.render.call(this, view);
      }
    });
    d.render();

    expect(a._renderCount).to.equal(1, '_renderCount incrimented');
    expect(b._renderCount).to.equal(1, '_renderCount incrimented');
    expect(c._renderCount).to.equal(1, '_renderCount incrimented');
    expect(d._renderCount).to.equal(1, '_renderCount incrimented');
    expect(a.$('p').html()).to.equal('a', 'parent render accepts string');
    expect(b.$('p').html()).to.equal('b', 'parent render accepts dom array');
    expect(c.$('p').html()).to.equal('c', 'parent render accepts dom element');
    expect(d.$('p').html()).to.equal('d', 'parent render accepts view');
  });

  it("onException", function() {
    var oldOnException = Thorax.onException;
    var view = new Thorax.View({
      events: {
        test: function () {
          throw new Error('view error');
        },
        'click div': function() {
          throw new Error('dom error');
        }
      },
      template: Handlebars.compile('

')
    });
    view.render();
    document.body.appendChild(view.el);
    Thorax.onException = function(errorName) {
      expect(errorName.match(/click/)).to.exist;
    };
    view.$('div').trigger('click');
    Thorax.onException = function(errorName) {
      expect(errorName.match(/test/)).to.exist;
    };
    view.trigger('test');
    Thorax.onException = oldOnException;
    view.$el.remove();
  });

  describe('context', function() {
    it("may be an object", function() {
      var view = new (Thorax.View.extend({
        context: {
          a: 'a',
          b: 'b',
          c: function() {
            return 'c';
          }
        },
        template: Handlebars.compile('{{a}}{{b}}{{c}}')
      }))();
      view.render();
      expect(view.html()).to.equal('abc');
    });

    it("can return undefined", function() {
      var view = new Thorax.View({
        key: 'value',
        context: function() {
          return;
        },
        template: Handlebars.compile('{{key}}')
      });
      view.render();
      expect(view.html()).to.equal('value');
    });

    it("function is additive", function() {
      var view = new Thorax.View({
        a: 'a',
        context: function() {
          return {
            b: 'b'
          };
        },
        template: Handlebars.compile('{{a}}{{b}}')
      });
      view.render();
      expect(view.html()).to.equal('ab');
    });

    it("template helpers will not mutate view or model attributes", function() {
      Handlebars.registerHelper('modifyObject', function(obj) {
        obj.mutated = true;
        return obj;
      });
      var view = new Thorax.View({
        a: 'a',
        model: new Thorax.Model({
          b: 'b'
        }),
        template: Handlebars.compile('{{modifyObject a}}{{modifyObject b}}')
      });
      view.render();
      expect(view.a.mutated).to.be['undefined'];
      expect(view.model.attributes.b.mutated).to.be['undefined'];
      expect(view.html()).to.equal('ab');
    });

    it("template does not expose template cid", function() {
      var view = new Thorax.View({
        template: Handlebars.compile("{{cid}}")
      });
      view.render();
      expect(view.html()).to.contain('view');
      view = new Thorax.View({
        template: Handlebars.compile("{{@cid}}")
      });
      view.render();
      expect(view.html()).to.contain('t');
    });
  });
});
<|endoftext|>


<commit_before>#!/usr/bin/env node

'use strict';

var child_process = require('child_process'),
    fs = require('fs'),
    os = require('os'),
    path = require('path');

var urls = require('./benchmarks');
var fileNames = Object.keys(urls).sort();

function run(tasks, callback) {
  var remaining = tasks.length;

  function done() {
    if (!--remaining) {
      callback();
    }
  }

  tasks.forEach(function(task) {
    task(done);
  });
}

function git() {
  var args = [].concat.apply([], [].slice.call(arguments, 0, -1));
  var callback = arguments[arguments.length - 1];
  var task = child_process.spawn('git', args, { stdio: [ 'ignore', 'pipe', 'ignore' ] });
  var output = '';
  task.stdout.setEncoding('utf8');
  task.stdout.on('data', function(data) {
    output += data;
  });
  task.on('exit', function(code) {
    callback(code, output);
  });
}

function readText(filePath, callback) {
  fs.readFile(filePath, { encoding: 'utf8' }, callback);
}

function minify(hash, options) {
  var minify = require('./src/htmlminifier').minify;
  process.send('ready');
  var results = {};
  run(fileNames.map(function(fileName) {
    return function(done) {
      readText(path.join('benchmarks/', fileName + '.html'), function(err, data) {
        if (err) {
          throw err;
        }
        else {
          results[fileName] = minify(data, options).length;
          done();
        }
      });
    };
  }), function() {
    process.send(results);
  });
}

function print(table) {
  var output = [];
  var row = fileNames.slice(0);
  row.unshift('hash', 'date');
  output.push(row.join(','));
  for (var hash in table) {
    var data = table[hash];
    row = [ hash, '"' + data.date + '"' ];
    for (var i = 0; i < fileNames.length; i++) {
      row.push(data[fileNames[i]]);
    }
    output.push(row.join(','));
  }
  fs.writeFile('backtest.csv', output.join('\n'), { encoding: 'utf8' }, function(err) {
    if (err) {
      throw err;
    }
  });
}

if (process.argv.length > 2) {
  var count = +process.argv[2];
  if (count) {
    git('log', '--date=iso', '--pretty=format:%h %cd', '-' + count, function(code, data) {
      var table = {};
      var commits = data.split(/\s*?\n/).map(function(line) {
        var index = line.indexOf(' ');
        var hash = line.substr(0, index);
        table[hash] = {
          date: line.substr(index + 1).replace('+', '').replace(/ 0000$/, '')
        };
        return hash;
      });
      var nThreads = os.cpus().length;
      var running = 0, ready = true;

      function fork() {
        if (commits.length && running < nThreads) {
          var hash = commits.shift();
          var task = child_process.fork('./backtest', { silent: true });

          function done() {
            if (!--running && !commits.length) {
              print(table);
            }
          }

          task.on('message', function(data) {
            if (data === 'ready') {
              ready = true;
            }
            else {
              var date = table[hash].date;
              table[hash] = data;
              table[hash].date = date;
              task.disconnect();
              done();
            }
            fork();
          }).on('exit', function(code) {
            if (code !== 0) {
              console.error(hash, ': minify task failed');
              done();
              fork();
            }
          });
          task.stderr.resume();
          task.stdout.resume();
          task.send(hash);
          running++;
        }
      }

      fork();
    });
  }
  else {
    console.error('Invalid input:', process.argv[2]);
  }
}
else {
  process.on('message', function(hash) {
    var paths = ['src', 'benchmark.conf', 'sample-cli-config-file.conf'];
    git('reset', 'HEAD', '--', paths, function() {
      var conf = 'sample-cli-config-file.conf';

      function checkout() {
        var path = paths.shift();
        git('checkout', hash, '--', path, function(code) {
          if (code === 0 && path === 'benchmark.conf') {
            conf = path;
          }
          if (paths.length) {
            checkout();
          }
          else {
            readText(conf, function(err, data) {
              if (err) {
                throw err;
              }
              else {
                minify(hash, JSON.parse(data));
              }
            });
          }
        });
      }

      checkout();
    });
  });
}
<commit_msg>improve error reporting fix lints<commit_after>#!/usr/bin/env node

'use strict';

var child_process = require('child_process'),
    fs = require('fs'),
    os = require('os'),
    path = require('path');

var urls = require('./benchmarks');
var fileNames = Object.keys(urls).sort();

function run(tasks, callback) {
  var remaining = tasks.length;

  function done() {
    if (!--remaining) {
      callback();
    }
  }

  tasks.forEach(function(task) {
    task(done);
  });
}

function git() {
  var args = [].concat.apply([], [].slice.call(arguments, 0, -1));
  var callback = arguments[arguments.length - 1];
  var task = child_process.spawn('git', args, { stdio: [ 'ignore', 'pipe', 'ignore' ] });
  var output = '';
  task.stdout.setEncoding('utf8');
  task.stdout.on('data', function(data) {
    output += data;
  });
  task.on('exit', function(code) {
    callback(code, output);
  });
}

function readText(filePath, callback) {
  fs.readFile(filePath, { encoding: 'utf8' }, callback);
}

function minify(hash, options) {
  var minify = require('./src/htmlminifier').minify;
  process.send('ready');
  var results = {};
  run(fileNames.map(function(fileName) {
    return function(done) {
      readText(path.join('benchmarks/', fileName + '.html'), function(err, data) {
        if (err) {
          throw err;
        }
        else {
          results[fileName] = minify(data, options).length;
          done();
        }
      });
    };
  }), function() {
    process.send(results);
  });
}

function print(table) {
  var output = [];
  var row = fileNames.slice(0);
  row.unshift('hash', 'date');
  output.push(row.join(','));
  for (var hash in table) {
    var data = table[hash];
    row = [ hash, '"' + data.date + '"' ];
    for (var i = 0; i < fileNames.length; i++) {
      row.push(data[fileNames[i]]);
    }
    output.push(row.join(','));
  }
  fs.writeFile('backtest.csv', output.join('\n'), { encoding: 'utf8' }, function(err) {
    if (err) {
      throw err;
    }
  });
}

if (process.argv.length > 2) {
  var count = +process.argv[2];
  if (count) {
    git('log', '--date=iso', '--pretty=format:%h %cd', '-' + count, function(code, data) {
      var table = {};
      var commits = data.split(/\s*?\n/).map(function(line) {
        var index = line.indexOf(' ');
        var hash = line.substr(0, index);
        table[hash] = {
          date: line.substr(index + 1).replace('+', '').replace(/ 0000$/, '')
        };
        return hash;
      });
      var nThreads = os.cpus().length;
      var running = 0, ready = true;

      function done() {
        if (!--running && !commits.length) {
          print(table);
        }
      }

      function fork() {
        if (commits.length && running < nThreads) {
          var hash = commits.shift();
          var task = child_process.fork('./backtest', { silent: true });
          var output = '';
          task.on('message', function(data) {
            if (data === 'ready') {
              ready = true;
            }
            else {
              var date = table[hash].date;
              table[hash] = data;
              table[hash].date = date;
              task.disconnect();
              done();
            }
            fork();
          }).on('exit', function(code) {
            if (code !== 0) {
              console.error(hash, '-', output.substr(0, output.indexOf('\n')));
              done();
              fork();
            }
          });
          task.stderr.setEncoding('utf8');
          task.stderr.on('data', function(data) {
            output += data;
          });
          task.stdout.resume();
          task.send(hash);
          running++;
        }
      }

      fork();
    });
  }
  else {
    console.error('Invalid input:', process.argv[2]);
  }
}
else {
  process.on('message', function(hash) {
    var paths = ['src', 'benchmark.conf', 'sample-cli-config-file.conf'];
    git('reset', 'HEAD', '--', paths, function() {
      var conf = 'sample-cli-config-file.conf';

      function checkout() {
        var path = paths.shift();
        git('checkout', hash, '--', path, function(code) {
          if (code === 0 && path === 'benchmark.conf') {
            conf = path;
          }
          if (paths.length) {
            checkout();
          }
          else {
            readText(conf, function(err, data) {
              if (err) {
                throw err;
              }
              else {
                /* global JSON: true */
                minify(hash, JSON.parse(data));
              }
            });
          }
        });
      }

      checkout();
    });
  });
}
<|endoftext|>


<commit_before>/*
 * Optics test / subcommand.js
 * copyright (c) 2016 Susisu
 */

"use strict";

describe("subcommand", () => {
    describe("Subcommand", () => {
        describe("constructor(name, cmd)", () => {
            it("should create a new Subcommand instance");
            it("should throw a TypeError if 'name' is not a string");
            it("should throw a TypeError if 'cmd' is not an instance of CommandBase");
        });
    });

    describe("CommandGroup", () => {
        describe("constructor(desc, subcmds, defaultCmd)", () => {
            it("should create a new CommandGroup instance");
            it("should throw a TypeError if 'desc' is not a string");
            it("should throw a TypeError if 'subcmds' is not an array of Subcommand");
            it("should throw a TypeError if 'defaultCmd' is not an instance of CommandBase nor null");
        });
    });
});
<commit_msg>Add tests for the Subcommand constructor<commit_after>/*
 * Optics test / subcommand.js
 * copyright (c) 2016 Susisu
 */

"use strict";

const chai   = require("chai");
const expect = chai.expect;

const command    = require("../lib/command.js");
const subcommand = require("../lib/subcommand.js");

describe("subcommand", () => {
    describe("Subcommand", () => {
        describe("constructor(name, cmd)", () => {
            it("should create a new Subcommand instance", () => {
                let cmd = new command.Command(
                    "test command",
                    [],
                    [],
                    (args, opts) => {}
                );
                let subcmd = new subcommand.Subcommand("test", cmd);
                expect(subcmd).to.be.an.instanceOf(subcommand.Subcommand);
            });

            it("should throw a TypeError if 'name' is not a string", () => {
                let cmd = new command.Command(
                    "test command",
                    [],
                    [],
                    (args, opts) => {}
                );
                function construct(name) {
                    return () => {
                        new subcommand.Subcommand(name, cmd);
                    };
                }
                expect(construct("test")).not.to.throw(TypeError);

                expect(construct(null)).to.throw(TypeError);
                expect(construct(undefined)).to.throw(TypeError);
                expect(construct(3.14)).to.throw(TypeError);
                expect(construct(true)).to.throw(TypeError);
                expect(construct({})).to.throw(TypeError);
                expect(construct(() => {})).to.throw(TypeError);
            });

            it("should throw a TypeError if 'cmd' is not an instance of CommandBase", () => {
                let cmd = new command.Command(
                    "test command",
                    [],
                    [],
                    (args, opts) => {}
                );
                function construct(cmd) {
                    return () => {
                        new subcommand.Subcommand("test", cmd);
                    };
                }
                expect(construct(cmd)).not.to.throw(TypeError);

                expect(construct(null)).to.throw(TypeError);
                expect(construct(undefined)).to.throw(TypeError);
                expect(construct("foobar")).to.throw(TypeError);
                expect(construct(3.14)).to.throw(TypeError);
                expect(construct(true)).to.throw(TypeError);
                expect(construct({})).to.throw(TypeError);
                expect(construct(() => {})).to.throw(TypeError);
            });
        });
    });

    describe("CommandGroup", () => {
        describe("constructor(desc, subcmds, defaultCmd)", () => {
            it("should create a new CommandGroup instance");
            it("should throw a TypeError if 'desc' is not a string");
            it("should throw a TypeError if 'subcmds' is not an array of Subcommand");
            it("should throw a TypeError if 'defaultCmd' is not an instance of CommandBase nor null");
        });
    });
});
<|endoftext|>