<commit_before>/*global describe it before after bar */

"use client";

require(["lib/architect/architect", "lib/chai/chai", "/vfs-root", "async"],
  function (architect, chai, baseProc) {
    var expect = chai.expect;
    var async = require("async");

    document.body.appendChild(document.createElement("div"))
        .setAttribute("id", "saveStatus");

    expect.setupArchitectTest([
        {
            packagePath: "plugins/c9.core/c9",
            startdate: new Date(),
            debug: true,
            hosted: true,
            local: false,
            davPrefix: "/"
        },

        "plugins/c9.core/ext",
        "plugins/c9.core/http-xhr",
        "plugins/c9.core/util",
        "plugins/c9.ide.ui/lib_apf",
        "plugins/c9.ide.ui/menus",
        {
            packagePath: "plugins/c9.core/settings",
            testing: true
        },
        "plugins/c9.core/api.js",
        {
            packagePath: "plugins/c9.ide.ui/ui",
            staticPrefix: "plugins/c9.ide.ui"
        },
        "plugins/c9.ide.editors/document",
        "plugins/c9.ide.editors/undomanager",
        {
            packagePath: "plugins/c9.ide.editors/editors",
            defaultEditor: "texteditor"
        },
        "plugins/c9.ide.editors/editor",
        "plugins/c9.ide.editors/tabmanager",
        "plugins/c9.ide.ui/focus",
        "plugins/c9.ide.editors/pane",
        "plugins/c9.ide.editors/tab",
        "plugins/c9.ide.ace/ace",
        "plugins/c9.ide.save/save",
        "plugins/c9.vfs.client/vfs_client",
        "plugins/c9.vfs.client/endpoint",
        "plugins/c9.ide.auth/auth",
        {
            packagePath: "plugins/c9.fs/fs",
            baseProc: baseProc
        },
        "plugins/c9.fs/fs.cache.xml",

        "plugins/c9.ide.dialog/dialog",
        "plugins/c9.ide.dialog.common/alert",
        "plugins/c9.ide.dialog.common/alert_internal",
        "plugins/c9.ide.dialog.common/confirm",
        "plugins/c9.ide.dialog.common/filechange",
        "plugins/c9.ide.dialog.common/fileoverwrite",
        "plugins/c9.ide.dialog.common/fileremove",
        "plugins/c9.ide.dialog.common/question",
        "plugins/c9.ide.dialog.file/file",

        // Mock plugins
        {
            consumes: ["apf", "ui", "Plugin"],
            provides: [
                "commands", "menus", "commands", "layout", "watcher",
                "save", "anims", "tree", "preferences", "clipboard",
                "auth.bootstrap", "info", "dialog.error"
            ],
            setup: expect.html.mocked
        },
        {
            consumes: [],
            provides: ["proc"],
            setup: expect.html.mocked
        },
        {
            consumes: ["tabManager", "save", "fs", "dialog.file", "dialog.question"],
            provides: [],
            setup: main
        }
    ], architect);

    function main(options, imports, register) {
        var tabs = imports.tabManager;
        var fs = imports.fs;
        var save = imports.save;
        var filesave = imports["dialog.file"];
        var question = imports["dialog.question"];

        function countEvents(count, expected, done) {
            if (count == expected)
                done();
            else
                throw new Error("Wrong Event Count: "
                    + count + " of " + expected);
        }

        expect.html.setConstructor(function(tab) {
            if (typeof tab == "object")
                return tab.pane.aml.getPage("editor::" + tab.editorType).$ext;
        });

        function changeTab(path, done) {
            var tab = tabs.findTab(path);
            if (!tab)
                return setTimeout(changeTab.bind(null, path, done), 10);

            tab.document.undoManager.once("change", function(){
                expect(tab.document.changed).to.ok;
                setTimeout(done, 0);
            });
            setTimeout(function() {
                tabs.focusTab(tab);
                tab.document.editor.ace.insert("test");
            });

            return tab;
        }

        var TIMEOUT = 10;
        var files = [];
        describe('save', function() {
            this.timeout(10000);

            before(function(done) {
                apf.config.setProperty("allow-select", false);
                apf.config.setProperty("allow-blur", false);

                files = ["/save1.txt", "/save2.txt", "/save3.txt"];

                bar.$ext.style.background = "rgba(220, 220, 220, 0.93)";
                bar.$ext.style.position = "fixed";
                bar.$ext.style.left = "20px";
                bar.$ext.style.right = "20px";
                bar.$ext.style.bottom = "20px";
                bar.$ext.style.height = "150px";

                document.body.style.marginBottom = "180px";

                tabs.once("ready", function(){
                    tabs.getPanes()[0].focus();
                    done();
                });
            });
            after(function(done) {
                async.each(files, function(path, next) {
                    fs.unlink(path, function(){
                        next();
                    });
                }, done);
            });

            describe("save", function(){
                before(function(done) {
                    var count = 0;
                    files.every(function(path, i) {
                        count++;
                        fs.writeFile(path, path, function(){
                            tabs.openFile(path, function(){
                                if (--count === 0)
                                    done();
                            });
                        });
                        return i == 2 ? false : true;
                    });
                });

                it('should save a tab that is changed', function(done) {
                    var path = "/save1.txt";
                    var count = 0;

                    var c1 = function(){ count++; };

                    save.on("beforeSave", c1);
                    save.on("afterSave", c1);

                    var tab = changeTab(path, function(){
                        save.save(tab, null, function(err) {
                            if (err) throw err;
                            expect(tab.document.changed).to.not.ok;

                            fs.readFile(path, function(err, data) {
                                if (err) throw err;
                                expect(data).to.equal("test" + path);
                                expect(count).to.equal(2);
                                save.off("beforeSave", c1);
                                save.off("afterSave", c1);
                                done();
                            });
                        });
                    });
                });
                it('should queue saves when called sequentially', function(done) {
                    var tab = tabs.focussedTab;
                    var count = 0;
                    save.save(tab, null, function(err) {
                        if (err) throw err;
                        expect(count).to.equal(0);
                        count++;
                    });
                    tab.editor.ace.insert("test");
                    setTimeout(function() {
                        save.save(tab, null, function(err) {
                            if (err) throw err;
                            expect(count).to.equal(1);
                            done();
                        });
                    });
                });
                it('should save a tab at a new path/filename', function(done) {
                    var tab = changeTab("/save2.txt", function(){
                        var path = "/save2b.txt";
                        files.push(path); // cleanup

                        save.save(tab, { path: path }, function(err) {
                            if (err) throw err;

                            expect(tab.path).to.equal(path);
                            expect(tab.document.changed).to.not.ok;

                            fs.readFile(path, function(err, data) {
                                if (err) throw err;
                                expect(data).to.equal("test/save2.txt");

                                fs.unlink(path, function(){
                                    setTimeout(function(){
                                        // give some time for tab to finish animation
                                        expect(tabs.getTabs().indexOf(tab)).to.equal(-1);
                                        done();
                                    }, 10);
                                });
                            });
                        });
                    });
                });
                it('should show the saveAs dialog when saving a newfile without path in the options', function(done) {
                    var path = "/shouldnotsave.txt";
                    files.push(path); //cleanup

                    tabs.open({
                        active: true,
                        path: path,
                        document: {
                            value: "test",
                            meta: {
                                newfile: true
                            }
                        }
                    }, function(err, tab) {
                        save.save(tab, null, function(err) {
                            expect(seen).to.ok;
                            tab.close();
                            done();
                        });
                    });

                    var seen = false;
                    setTimeout(function(){
                        var win = filesave.getElement("window");
                        var input = filesave.getElement("txtFilename");
                        expect(win.visible).to.ok;
                        expect(input.value).to.equal(path.substr(1));
                        seen = true;
                        win.hide();
                    }, TIMEOUT);
                });
                it('should not show the saveAs dialog when saving a newfile with path in the options', function(done) {
                    var path = "/shouldnotsave.txt";

                    tabs.open({
                        active: true,
                        document: {
                            value: "test",
                            meta: {
                                newfile: true
                            }
                        }
                    }, function(err, tab) {
                        save.save(tab, { path: path}, function(err) {
                            expect(tab.document.changed).not.ok;
                            expect(tab.document.meta.newfile).not.ok;
                            tab.close();
                            done();
                        });
                    });
                });
                it('should be triggered when closing a changed tab', function(done) {
                    var path = "/save3.txt";
                    var tab = changeTab(path, function(){
                        save.once("beforeWarn", function(){
                            question.once("show", function(){
                                save.once("afterSave", function(){
                                    fs.readFile(path, function(err, data) {
                                        if (err) throw err;
                                        expect(data).to.equal("test" + path);
                                        done();
                                    });
                                });

                                question.getElement("yes").dispatchEvent("click");
                            });
                        });

                        tab.close();
                    });
                });
                it('should not be triggered when closing an unchanged tab', function(done) {
                    var path = "/save1.txt";
                    var tab = tabs.findTab(path);
                    save.once("beforeWarn", function(){
                        if (tab)
                            throw new Error();
                    });
                    tab.close();
                    setTimeout(function(){
                        tab = tabs.findTab(path);
                        expect(tab).to.not.ok;
                        done();
                    });
                });
                it('should not be triggered when closing a new empty file', function(done) {
                    tabs.open({
                        active: true,
                        document: {
                            value: "",
                            meta: {
                                newfile: true
                            }
                        }
                    }, function(err, tab) {
                        save.once("beforeWarn", function(){
                            throw new Error();
                        });

                        tab.close();
                        setTimeout(function(){
                            tab = tabs.findTab(tab.path);
                            expect(tab).to.not.ok;
                            done();
                        });
                    });
                });
            });
            describe("saveAs", function(){
                before(function(done) {
                    files.every(function(path, i) {
                        fs.writeFile(path, path, function(){
                            tabs.openFile(path, function(){
                                if (path == files[2])
                                    done();
                            });
                        });
                        return i == 2 ? false : true;
                    });
                });
                after(function(done) {
                    tabs.getTabs().forEach(function(tab) {
                        tab.unload();
                    });
                    done();
                });

                it('should save a file under a new filename', function(done) {
                    var tab = tabs.focussedTab;
                    files.push("/save1b.txt");
                    fs.unlink("/save1b.txt", function(){
                        save.saveAs(tab, function(err) {
                            expect(err).to.not.ok
                            expect(seen).to.ok
                            done();
                        });

                        var seen = false;
                        setTimeout(function(){
                            var win = filesave.getElement("window");
                            expect(win.visible).to.ok;
                            seen = true;
                            filesave.getElement("txtFilename").setValue("save1b.txt");
                            filesave.getElement("btnChoose").dispatchEvent("click");
                        }, TIMEOUT);
                    });
                });
                it('should trigger saveAs and then cancel it', function(done) {
                    var tab = tabs.focussedTab;
                    save.saveAs(tab, function(err) {
                        expect(err).to.ok
                        expect(seen).to.ok
                        done();
                    });

                    var seen = false;
                    setTimeout(function(){
                        var win = filesave.getElement("window");
                        expect(win.visible).to.ok;
                        seen = true;
                        win.hide();
                    }, TIMEOUT);
                });
            });
            describe("revertToSaved", function(){
                before(function(done) {
                    files.every(function(path, i) {
                        fs.writeFile(path, path, function(){
                            tabs.openFile(path, function(){
                                if (path == files[2]) {
                                    done();
                                }
                            });
                        });
                        return i == 2 ? false : true;
                    });
                });
                after(function(done) {
                    tabs.getTabs().forEach(function(tab) {
                        tab.unload();
                    });
                    done();
                });

                it('should revert a change tab', function(done) {
                    var tab = changeTab("/save1.txt", function(){
                        save.revertToSaved(tab, function(err) {
                            expect(err).to.not.ok;
                            setTimeout(function(){
                                expect(tab.document.changed).to.not.ok
                                expect(tab.document.value).to.equal("/save1.txt");
                                expect(tab.document.undoManager.length).to.equal(2);
                                expect(tab.document.undoManager.position).to.equal(1);
                                expect(tab.document.undoManager.isAtBookmark()).to.ok;
                                expect(tab.classList.names.indexOf("loading")).to.equal(-1);
                                done();
                            }, TIMEOUT);
                        });
                    });
                });
            });
            describe("saveAll", function(){
                before(function(done) {
                    var count = 0;

                    files.every(function(path, i) {
                        count++;

                        fs.writeFile(path, path, function(){
                            tabs.openFile(path, function(){
                                if (--count === 0)
                                    done();
                            });
                        });
                        return i == 2 ? false : true;
                    });
                });
                after(function(done) {
                    tabs.getTabs().forEach(function(tab) {
                        tab.unload();
                    });
                    done();
                });

                it('should save all changed files', function(done) {
                    var page3 = tabs.findTab("/save3.txt");
                    var page1 = changeTab("/save1.txt", function(){
                        var page2 = changeTab("/save2.txt", function(){
                            expect(page1.document.changed).to.ok;
                            expect(page2.document.changed).to.ok;
                            expect(page3.document.changed).to.not.ok;

                            save.saveAll(function(err) {
                                if (err) throw err;

                                expect(page1.document.changed).to.not.ok;
                                expect(page2.document.changed).to.not.ok;
                                expect(page3.document.changed).to.not.ok;
                                done();
                            });
                        });
                    });
                });
            });
            describe("saveAllInteractive", function(){
                before(function(done) {
                    files.every(function(path, i) {
                        fs.writeFile(path, path, function(){
                            tabs.openFile(path, function(){
                                if (path == files[2])
                                    done();
                            });
                        });
                        return i == 2 ? false : true;
                    });
                });
                after(function(done) {
                    tabs.getTabs().forEach(function(tab) {
                        tab.unload();
                    });
                    done();
                });

                it('should be triggered when closing multiple pages that are changed', function(done) {
                    var page1 = changeTab("/save1.txt", function(){
                        var page2 = changeTab("/save2.txt", function(){
                            var page3 = changeTab("/save3.txt", function(){
                                var pages = [page1, page2, page3];

                                save.saveAllInteractive(pages, function(result) {
                                    expect(result).to.equal(save.YESTOALL);
                                    done();
                                });

                                question.once("show", function(){
                                    question.getElement("yestoall").dispatchEvent("click");
                                });
                            });
                        });
                    });
                });
            });
            if (!onload.remain) {
                describe("unload()", function(){
                    it('should destroy all ui elements when it is unloaded', function(done) {
                        save.unload();
                        done();
                    });
                });

                //@todo Idea: show in the tabs whether the editor is running atm
                // @todo test fs integration

                after(function(done) {
                    document.body.style.marginBottom = "";
                    tabs.unload();
                    done();
                });
            }
        });

        onload && onload();
    }
});<commit_msg>Revert "Revert php completion fix"<commit_after>/*global describe it before after bar */

"use client";

require(["lib/architect/architect", "lib/chai/chai", "/vfs-root", "async"],
  function (architect, chai, baseProc) {
    var expect = chai.expect;
    var async = require("async");

    document.body.appendChild(document.createElement("div"))
        .setAttribute("id", "saveStatus");

    expect.setupArchitectTest([
        {
            packagePath: "plugins/c9.core/c9",
            startdate: new Date(),
            debug: true,
            hosted: true,
            local: false,
            davPrefix: "/"
        },

        "plugins/c9.core/ext",
        "plugins/c9.core/http-xhr",
        "plugins/c9.core/util",
        "plugins/c9.ide.ui/lib_apf",
        "plugins/c9.ide.ui/menus",
        {
            packagePath: "plugins/c9.core/settings",
            testing: true
        },
        "plugins/c9.core/api.js",
        {
            packagePath: "plugins/c9.ide.ui/ui",
            staticPrefix: "plugins/c9.ide.ui"
        },
        "plugins/c9.ide.editors/document",
        "plugins/c9.ide.editors/undomanager",
        {
            packagePath: "plugins/c9.ide.editors/editors",
            defaultEditor: "texteditor"
        },
        "plugins/c9.ide.editors/editor",
        "plugins/c9.ide.editors/tabmanager",
        "plugins/c9.ide.ui/focus",
        "plugins/c9.ide.editors/pane",
        "plugins/c9.ide.editors/tab",
        "plugins/c9.ide.ace/ace",
        "plugins/c9.ide.save/save",
        "plugins/c9.vfs.client/vfs_client",
        "plugins/c9.vfs.client/endpoint",
        "plugins/c9.ide.auth/auth",
        {
            packagePath: "plugins/c9.fs/fs",
            baseProc: baseProc
        },
        "plugins/c9.fs/fs.cache.xml",

        "plugins/c9.ide.dialog/dialog",
        "plugins/c9.ide.dialog.common/alert",
        "plugins/c9.ide.dialog.common/alert_internal",
        "plugins/c9.ide.dialog.common/confirm",
        "plugins/c9.ide.dialog.common/filechange",
        "plugins/c9.ide.dialog.common/fileoverwrite",
        "plugins/c9.ide.dialog.common/fileremove",
        "plugins/c9.ide.dialog.common/question",
        "plugins/c9.ide.dialog.file/file",

        // Mock plugins
        {
            consumes: ["apf", "ui", "Plugin"],
            provides: [
                "commands", "menus", "commands", "layout", "watcher",
                "save", "anims", "tree", "preferences", "clipboard",
                "auth.bootstrap", "info", "dialog.error"
            ],
            setup: expect.html.mocked
        },
        {
            consumes: [],
            provides: ["proc"],
            setup: expect.html.mocked
        },
        {
            consumes: ["tabManager", "save", "fs", "dialog.file", "dialog.question"],
            provides: [],
            setup: main
        }
    ], architect);

    function main(options, imports, register) {
        var tabs = imports.tabManager;
        var fs = imports.fs;
        var save = imports.save;
        var filesave = imports["dialog.file"];
        var question = imports["dialog.question"];

        function countEvents(count, expected, done) {
            if (count == expected)
                done();
            else
                throw new Error("Wrong Event Count: "
                    + count + " of " + expected);
        }

        expect.html.setConstructor(function(tab) {
            if (typeof tab == "object")
                return tab.pane.aml.getPage("editor::" + tab.editorType).$ext;
        });

        function changeTab(path, done) {
            var tab = tabs.findTab(path);
            if (!tab)
                return setTimeout(changeTab.bind(null, path, done), 10);

            tab.document.undoManager.once("change", function(){
                expect(tab.document.changed).to.ok;
                setTimeout(done, 0);
            });
            setTimeout(function() {
                tabs.focusTab(tab);
                tab.document.editor.ace.insert("test");
            });

            return tab;
        }

        var TIMEOUT = 15;
        var files = [];
        describe('save', function() {
            this.timeout(10000);

            before(function(done) {
                apf.config.setProperty("allow-select", false);
                apf.config.setProperty("allow-blur", false);

                files = ["/save1.txt", "/save2.txt", "/save3.txt"];

                bar.$ext.style.background = "rgba(220, 220, 220, 0.93)";
                bar.$ext.style.position = "fixed";
                bar.$ext.style.left = "20px";
                bar.$ext.style.right = "20px";
                bar.$ext.style.bottom = "20px";
                bar.$ext.style.height = "150px";

                document.body.style.marginBottom = "180px";

                tabs.once("ready", function(){
                    tabs.getPanes()[0].focus();
                    done();
                });
            });
            after(function(done) {
                async.each(files, function(path, next) {
                    fs.unlink(path, function(){
                        next();
                    });
                }, done);
            });

            describe("save", function(){
                before(function(done) {
                    var count = 0;
                    files.every(function(path, i) {
                        count++;
                        fs.writeFile(path, path, function(){
                            tabs.openFile(path, function(){
                                if (--count === 0)
                                    done();
                            });
                        });
                        return i == 2 ? false : true;
                    });
                });

                it('should save a tab that is changed', function(done) {
                    var path = "/save1.txt";
                    var count = 0;

                    var c1 = function(){ count++; };

                    save.on("beforeSave", c1);
                    save.on("afterSave", c1);

                    var tab = changeTab(path, function(){
                        save.save(tab, null, function(err) {
                            if (err) throw err;
                            expect(tab.document.changed).to.not.ok;

                            fs.readFile(path, function(err, data) {
                                if (err) throw err;
                                expect(data).to.equal("test" + path);
                                expect(count).to.equal(2);
                                save.off("beforeSave", c1);
                                save.off("afterSave", c1);
                                done();
                            });
                        });
                    });
                });
                it('should queue saves when called sequentially', function(done) {
                    var tab = tabs.focussedTab;
                    var count = 0;
                    save.save(tab, null, function(err) {
                        if (err) throw err;
                        expect(count).to.equal(0);
                        count++;
                    });
                    tab.editor.ace.insert("test");
                    setTimeout(function() {
                        save.save(tab, null, function(err) {
                            if (err) throw err;
                            expect(count).to.equal(1);
                            done();
                        });
                    });
                });
                it('should save a tab at a new path/filename', function(done) {
                    var tab = changeTab("/save2.txt", function(){
                        var path = "/save2b.txt";
                        files.push(path); // cleanup

                        save.save(tab, { path: path }, function(err) {
                            if (err) throw err;

                            expect(tab.path).to.equal(path);
                            expect(tab.document.changed).to.not.ok;

                            fs.readFile(path, function(err, data) {
                                if (err) throw err;
                                expect(data).to.equal("test/save2.txt");

                                fs.unlink(path, function(){
                                    setTimeout(function(){
                                        // give some time for tab to finish animation
                                        expect(tabs.getTabs().indexOf(tab)).to.equal(-1);
                                        done();
                                    }, 10);
                                });
                            });
                        });
                    });
                });
                it('should show the saveAs dialog when saving a newfile without path in the options', function(done) {
                    var path = "/shouldnotsave.txt";
                    files.push(path); //cleanup

                    tabs.open({
                        active: true,
                        path: path,
                        document: {
                            value: "test",
                            meta: {
                                newfile: true
                            }
                        }
                    }, function(err, tab) {
                        save.save(tab, null, function(err) {
                            expect(seen).to.ok;
                            tab.close();
                            done();
                        });
                    });

                    var seen = false;
                    setTimeout(function(){
                        var win = filesave.getElement("window");
                        var input = filesave.getElement("txtFilename");
                        expect(win.visible).to.ok;
                        expect(input.value).to.equal(path.substr(1));
                        seen = true;
                        win.hide();
                    }, TIMEOUT);
                });
                it('should not show the saveAs dialog when saving a newfile with path in the options', function(done) {
                    var path = "/shouldnotsave.txt";

                    tabs.open({
                        active: true,
                        document: {
                            value: "test",
                            meta: {
                                newfile: true
                            }
                        }
                    }, function(err, tab) {
                        save.save(tab, { path: path}, function(err) {
                            expect(tab.document.changed).not.ok;
                            expect(tab.document.meta.newfile).not.ok;
                            tab.close();
                            done();
                        });
                    });
                });
                it('should be triggered when closing a changed tab', function(done) {
                    var path = "/save3.txt";
                    var tab = changeTab(path, function(){
                        save.once("beforeWarn", function(){
                            question.once("show", function(){
                                save.once("afterSave", function(){
                                    fs.readFile(path, function(err, data) {
                                        if (err) throw err;
                                        expect(data).to.equal("test" + path);
                                        done();
                                    });
                                });

                                question.getElement("yes").dispatchEvent("click");
                            });
                        });

                        tab.close();
                    });
                });
                it('should not be triggered when closing an unchanged tab', function(done) {
                    var path = "/save1.txt";
                    var tab = tabs.findTab(path);
                    save.once("beforeWarn", function(){
                        if (tab)
                            throw new Error();
                    });
                    tab.close();
                    setTimeout(function(){
                        tab = tabs.findTab(path);
                        expect(tab).to.not.ok;
                        done();
                    });
                });
                it('should not be triggered when closing a new empty file', function(done) {
                    tabs.open({
                        active: true,
                        document: {
                            value: "",
                            meta: {
                                newfile: true
                            }
                        }
                    }, function(err, tab) {
                        save.once("beforeWarn", function(){
                            throw new Error();
                        });

                        tab.close();
                        setTimeout(function(){
                            tab = tabs.findTab(tab.path);
                            expect(tab).to.not.ok;
                            done();
                        });
                    });
                });
            });
            describe("saveAs", function(){
                before(function(done) {
                    files.every(function(path, i) {
                        fs.writeFile(path, path, function(){
                            tabs.openFile(path, function(){
                                if (path == files[2])
                                    done();
                            });
                        });
                        return i == 2 ? false : true;
                    });
                });
                after(function(done) {
                    tabs.getTabs().forEach(function(tab) {
                        tab.unload();
                    });
                    done();
                });

                it('should save a file under a new filename', function(done) {
                    var tab = tabs.focussedTab;
                    files.push("/save1b.txt");
                    fs.unlink("/save1b.txt", function(){
                        save.saveAs(tab, function(err) {
                            expect(err).to.not.ok
                            expect(seen).to.ok
                            done();
                        });

                        var seen = false;
                        setTimeout(function(){
                            var win = filesave.getElement("window");
                            expect(win.visible).to.ok;
                            seen = true;
                            filesave.getElement("txtFilename").setValue("save1b.txt");
                            filesave.getElement("btnChoose").dispatchEvent("click");
                        }, TIMEOUT);
                    });
                });
                it('should trigger saveAs and then cancel it', function(done) {
                    var tab = tabs.focussedTab;
                    save.saveAs(tab, function(err) {
                        expect(err).to.ok
                        expect(seen).to.ok
                        done();
                    });

                    var seen = false;
                    setTimeout(function(){
                        var win = filesave.getElement("window");
                        expect(win.visible).to.ok;
                        seen = true;
                        win.hide();
                    }, TIMEOUT);
                });
            });
            describe("revertToSaved", function(){
                before(function(done) {
                    files.every(function(path, i) {
                        fs.writeFile(path, path, function(){
                            tabs.openFile(path, function(){
                                if (path == files[2]) {
                                    done();
                                }
                            });
                        });
                        return i == 2 ? false : true;
                    });
                });
                after(function(done) {
                    tabs.getTabs().forEach(function(tab) {
                        tab.unload();
                    });
                    done();
                });

                it('should revert a change tab', function(done) {
                    var tab = changeTab("/save1.txt", function(){
                        save.revertToSaved(tab, function(err) {
                            expect(err).to.not.ok;
                            setTimeout(function(){
                                expect(tab.document.changed).to.not.ok
                                expect(tab.document.value).to.equal("/save1.txt");
                                expect(tab.document.undoManager.length).to.equal(2);
                                expect(tab.document.undoManager.position).to.equal(1);
                                expect(tab.document.undoManager.isAtBookmark()).to.ok;
                                expect(tab.classList.names.indexOf("loading")).to.equal(-1);
                                done();
                            }, TIMEOUT);
                        });
                    });
                });
            });
            describe("saveAll", function(){
                before(function(done) {
                    var count = 0;

                    files.every(function(path, i) {
                        count++;

                        fs.writeFile(path, path, function(){
                            tabs.openFile(path, function(){
                                if (--count === 0)
                                    done();
                            });
                        });
                        return i == 2 ? false : true;
                    });
                });
                after(function(done) {
                    tabs.getTabs().forEach(function(tab) {
                        tab.unload();
                    });
                    done();
                });

                it('should save all changed files', function(done) {
                    var page3 = tabs.findTab("/save3.txt");
                    var page1 = changeTab("/save1.txt", function(){
                        var page2 = changeTab("/save2.txt", function(){
                            expect(page1.document.changed).to.ok;
                            expect(page2.document.changed).to.ok;
                            expect(page3.document.changed).to.not.ok;

                            save.saveAll(function(err) {
                                if (err) throw err;

                                expect(page1.document.changed).to.not.ok;
                                expect(page2.document.changed).to.not.ok;
                                expect(page3.document.changed).to.not.ok;
                                done();
                            });
                        });
                    });
                });
            });
            describe("saveAllInteractive", function(){
                before(function(done) {
                    files.every(function(path, i) {
                        fs.writeFile(path, path, function(){
                            tabs.openFile(path, function(){
                                if (path == files[2])
                                    done();
                            });
                        });
                        return i == 2 ? false : true;
                    });
                });
                after(function(done) {
                    tabs.getTabs().forEach(function(tab) {
                        tab.unload();
                    });
                    done();
                });

                it('should be triggered when closing multiple pages that are changed', function(done) {
                    var page1 = changeTab("/save1.txt", function(){
                        var page2 = changeTab("/save2.txt", function(){
                            var page3 = changeTab("/save3.txt", function(){
                                var pages = [page1, page2, page3];

                                save.saveAllInteractive(pages, function(result) {
                                    expect(result).to.equal(save.YESTOALL);
                                    done();
                                });

                                question.once("show", function(){
                                    question.getElement("yestoall").dispatchEvent("click");
                                });
                            });
                        });
                    });
                });
            });
            if (!onload.remain) {
                describe("unload()", function(){
                    it('should destroy all ui elements when it is unloaded', function(done) {
                        save.unload();
                        done();
                    });
                });

                //@todo Idea: show in the tabs whether the editor is running atm
                // @todo test fs integration

                after(function(done) {
                    document.body.style.marginBottom = "";
                    tabs.unload();
                    done();
                });
            }
        });

        onload && onload();
    }
});<|endoftext|>


<commit_before>;
/**
 * Respond.to.js
 * Copyright 2014 Collin Bourdage.
 *
 * Lightweight javascript library to help facilitate javascript development
 * for responsive development. Implements simple api to call, retrieve, and
 * add callbacks to a stack of media query objects.
 *
 * Stack object looks like the following:
 * array(
 * 		'960' : array(object, object),
 *      '760' : array(object, object)
 * ));
 */
(function() {
	/** @var window */
	var root = this;
	var Respond = root.Respond = {};

	/**
	 * Pushes a new object based on a key onto the media stack
	 *
	 * @param mqString String
	 * @param obj Object
	 * @return {*}
	 * @private
	 */
	Respond._push = function(mqString, obj) {
		var key = this._purify(mqString);
		this._mediaStack || (this._mediaStack = {});
		this._mediaStack[key] || (this._mediaStack[key] = {mql : null, items : []});

		if (!this._mediaStack[key].mql) {
			if (root.matchMedia) {
				this._mediaStack[key].mql = root.matchMedia(mqString);
				this._mediaStack[key].mql.addListener(respondTo);
			} else {
				this._mediaStack[key].mql = {keyValue: null}; // ie8 fix
			}

			/**
			 * Store array key on the mql object for lookup later because of an
			 * inconsistency with how browsers handle media queries after instantiation:
			 *  	screen and (min-width: 700px) and (max-width: 900px)
			 * is converted to the following on the mql object:
			 *  	screen and (max-width: 900px) and (min-width: 700px)
			 */
			this._mediaStack[key].mql.keyValue = key;
		}

		obj.ready = true;
		this._mediaStack[key].items.push(obj);
		return this;
	};

	/**
	 * Cleans keys for object index by replacing the spaces
	 * with a more acceptable character
	 *
	 * @param key
	 * @param replacement (optional)
	 * @returns {string}
	 * @private
	 */
	Respond._purify = function (key, replacement) {
		replacement || (replacement = '_');
		return key.toLowerCase().replace(/[\s\-:()]/g, replacement).replace(/__/g, replacement).replace(/(_)$/, '');
	};

	/**
	 * Proxy function for adding listener to media query list.
	 *
	 * @param mql window.MediaQueryList
	 */
	function respondTo(mql) {
		Respond._respond(mql);
	}

	/**
	 * Responds to a given media query list object
	 *
	 * @private
	 * @param mql window.MediaQueryList
 	 * @param namespace String
	 */
	Respond._respond = function(mql, namespace) {
		var key = mql.keyValue;

		// ie9 can't store extra data on the mql object, so we purify the mql.media string
		if (navigator.userAgent.match(/MSIE 9.0/)) {
			key = this._purify(mql.media);
		}

		if (!this._mediaStack[key]) return;

		// If ie8, lets run the "default" condition - we ain't supportin' it, sorry.
		if (navigator.userAgent.match(/MSIE 8.0/)) {
			for (var i = 0; i < this._mediaStack[key].items.length; i++) {
				var _item = this._mediaStack[key].items[i],
					_fallback = _item['fallback'] || 'if';
				if (typeof _item[_fallback] === 'function') {
					if (!namespace || _item['namespace'] == namespace) {
						_item[_fallback]();
					}
				}
			}
			return this;
		}

		var _fnCallback = mql.matches ? 'if' : 'else';

		for (var i = 0; i < this._mediaStack[key].items.length; i++) {
			var _item = this._mediaStack[key].items[i];
			if (typeof _item[_fnCallback] === 'function') {
				if (!namespace || _item['namespace'] == namespace) {
					_item[_fnCallback]();
				}
			}
		}
		return this;
	};

	/**
	 * Returns a object based on a namespace and an optional
	 * media index.
	 *
	 * @param ns String
	 * @param mqString String
	 * @return {*}
	 * @private
	 */
	Respond._retrieve = function(ns, mqString) {
		if (!this._mediaStack) return;

		var _temp = [];
		if (!mqString) {
			for (var key in this._mediaStack) {
				for (var i = 0; i < this._mediaStack[key].items.length; i++) {
					_temp.push(this._mediaStack[key].items[i]);
				}
			}
		} else {
			var key = this._purify(mqString);
			if (!this._mediaStack[key]) return;
			_temp = this._mediaStack[key].items;
		}

		// find namespace
		for (var i = 0; i < _temp.length; i++) {
			if (_temp[i].namespace === ns) {
				return _temp[i];
			}
		}
	};

	/**
	 * Adds the corresponding object to the media stack
	 *
	 * @param obj Object
	 * @return {*}
	 */
	Respond.to = function(obj) {
		if (obj.length) {
			for (var i = 0; i < obj.length; i++) {
				this.to(obj[i]);
			}
		} else {
			var _temp = this._retrieve(obj.namespace, obj.media);
			if (typeof _temp === 'undefined') {
				_temp = this._push(obj.media, obj)
							._retrieve(obj.namespace, obj.media);
				if (_temp.ready) {
					this._respond(this._mediaStack[this._purify(obj.media)].mql, obj.namespace);
					_temp.ready = false;
				}
			}
		}
		return this;
	};

	/**
	 * Must be called to mark all ready and to make the initial
	 * media respond call.
	 */
	Respond.ready = function() {
		for (var key in this._mediaStack) {
			this._respond(this._mediaStack[key].mql);
		}
		return this;
	};

	/**
	 * Returns the media stack object
	 *
	 * @param mqString String
	 * @return {*}
	 */
	Respond.getStack = function(mqString) {
		return this._mediaStack[mqString] || this._mediaStack;
	};

	/**
	 * Removes a objects from the media stack
	 *
	 * @param mqString String
	 * @param ns String (optional)
	 * @return {*}
	 */
	Respond.remove = function(mqString, ns) {
		var key = this._purify(mqString);

		if (!this._mediaStack.length && !this._mediaStack[key]) return;

		if (!ns) {
			this._mediaStack[key].mql.removeListener(respondTo);
			delete this._mediaStack[key];
			return this;
		}

		for (var i = 0; i < this._mediaStack[key].items.length; i++) {
			if (this._mediaStack[key].items[i].namespace === ns) {
				delete this._mediaStack[key].items[i];
				this._mediaStack[key].items.splice(i, 1);
			}
		}
		return this;
	};

	/**
	 * Calls a specific ns, type, media reference
	 *
	 * @param ns String
	 * @param type String
 	 * @param mqString String (optional)
	 * @return {*}
	 */
	Respond.call = function(ns, type, mqString) {
		try {
			if (mqString && type) {
				(this._retrieve(ns, mqString))[type](this);
			} else if (type) {
				(this._retrieve(ns))[type](this);
			} else {
				this._respond(this._mediaStack[this._purify((this._retrieve(ns)).media)].mql, ns);
			}
		} catch (e) {
			console.error(e);
		}
		return this;
	};

}).call(this);
<commit_msg>Update repond.to.js<commit_after>;
/**
 * Respond.to.js
 * Copyright 2014 Collin Bourdage.
 *
 * Lightweight javascript library to help facilitate javascript development
 * for responsive development. Implements simple api to call, retrieve, and
 * add callbacks to a stack of media query objects.
 *
 * Stack object looks like the following:
 * array(
 * 		'960' : array(object, object),
 *      '760' : array(object, object)
 * ));
 */
(function() {
	/** @var window */
	var root = this;
	var Respond = root.Respond = {};

	/**
	 * Pushes a new object based on a key onto the media stack
	 *
	 * @param mqString String
	 * @param obj Object
	 * @return {*}
	 * @private
	 */
	Respond._push = function(mqString, obj) {
		var key = this._purify(mqString);
		this._mediaStack || (this._mediaStack = {});
		this._mediaStack[key] || (this._mediaStack[key] = {mql : null, items : []});

		if (!this._mediaStack[key].mql) {
			if (root.matchMedia) {
				this._mediaStack[key].mql = root.matchMedia(mqString);
				this._mediaStack[key].mql.addListener(respondTo);
			} else {
				this._mediaStack[key].mql = {keyValue: null}; // ie8 fix
			}

			/**
			 * Store array key on the mql object for lookup later because of an
			 * inconsistency with how browsers handle media queries after instantiation:
			 *  	screen and (min-width: 700px) and (max-width: 900px)
			 * is converted to the following on the mql object:
			 *  	screen and (max-width: 900px) and (min-width: 700px)
			 */
			this._mediaStack[key].mql.keyValue = key;
		}

		obj.ready = true;
		this._mediaStack[key].items.push(obj);
		return this;
	};

	/**
	 * Cleans keys for object index by replacing the spaces
	 * with a more acceptable character
	 *
	 * @param key
	 * @param replacement (optional)
	 * @returns {string}
	 * @private
	 */
	Respond._purify = function (key, replacement) {
		replacement || (replacement = '_');
		return key.toLowerCase().replace(/[\s\-:()]/g, replacement).replace(/__/g, replacement).replace(/(_)$/, '');
	};

	/**
	 * Proxy function for adding listener to media query list.
	 *
	 * @param mql window.MediaQueryList
	 */
	function respondTo(mql) {
		Respond._respond(mql);
	}

	/**
	 * Responds to a given media query list object
	 *
	 * @private
	 * @param mql window.MediaQueryList
 	 * @param namespace String
	 */
	Respond._respond = function(mql, namespace) {
		var key = mql.keyValue || mql.target.keyValue;

		// ie9 can't store extra data on the mql object, so we purify the mql.media string
		if (navigator.userAgent.match(/MSIE 9.0/)) {
			key = this._purify(mql.media);
		}

		if (!this._mediaStack[key]) return;

		// If ie8, lets run the "default" condition - we ain't supportin' it, sorry.
		if (navigator.userAgent.match(/MSIE 8.0/)) {
			for (var i = 0; i < this._mediaStack[key].items.length; i++) {
				var _item = this._mediaStack[key].items[i],
					_fallback = _item['fallback'] || 'if';
				if (typeof _item[_fallback] === 'function') {
					if (!namespace || _item['namespace'] == namespace) {
						_item[_fallback]();
					}
				}
			}
			return this;
		}

		var _fnCallback = mql.matches ? 'if' : 'else';

		for (var i = 0; i < this._mediaStack[key].items.length; i++) {
			var _item = this._mediaStack[key].items[i];
			if (typeof _item[_fnCallback] === 'function') {
				if (!namespace || _item['namespace'] == namespace) {
					_item[_fnCallback]();
				}
			}
		}
		return this;
	};

	/**
	 * Returns a object based on a namespace and an optional
	 * media index.
	 *
	 * @param ns String
	 * @param mqString String
	 * @return {*}
	 * @private
	 */
	Respond._retrieve = function(ns, mqString) {
		if (!this._mediaStack) return;

		var _temp = [];
		if (!mqString) {
			for (var key in this._mediaStack) {
				for (var i = 0; i < this._mediaStack[key].items.length; i++) {
					_temp.push(this._mediaStack[key].items[i]);
				}
			}
		} else {
			var key = this._purify(mqString);
			if (!this._mediaStack[key]) return;
			_temp = this._mediaStack[key].items;
		}

		// find namespace
		for (var i = 0; i < _temp.length; i++) {
			if (_temp[i].namespace === ns) {
				return _temp[i];
			}
		}
	};

	/**
	 * Adds the corresponding object to the media stack
	 *
	 * @param obj Object
	 * @return {*}
	 */
	Respond.to = function(obj) {
		if (obj.length) {
			for (var i = 0; i < obj.length; i++) {
				this.to(obj[i]);
			}
		} else {
			var _temp = this._retrieve(obj.namespace, obj.media);
			if (typeof _temp === 'undefined') {
				_temp = this._push(obj.media, obj)
							._retrieve(obj.namespace, obj.media);
				if (_temp.ready) {
					this._respond(this._mediaStack[this._purify(obj.media)].mql, obj.namespace);
					_temp.ready = false;
				}
			}
		}
		return this;
	};

	/**
	 * Must be called to mark all ready and to make the initial
	 * media respond call.
	 */
	Respond.ready = function() {
		for (var key in this._mediaStack) {
			this._respond(this._mediaStack[key].mql);
		}
		return this;
	};

	/**
	 * Returns the media stack object
	 *
	 * @param mqString String
	 * @return {*}
	 */
	Respond.getStack = function(mqString) {
		return this._mediaStack[mqString] || this._mediaStack;
	};

	/**
	 * Removes a objects from the media stack
	 *
	 * @param mqString String
	 * @param ns String (optional)
	 * @return {*}
	 */
	Respond.remove = function(mqString, ns) {
		var key = this._purify(mqString);

		if (!this._mediaStack.length && !this._mediaStack[key]) return;

		if (!ns) {
			this._mediaStack[key].mql.removeListener(respondTo);
			delete this._mediaStack[key];
			return this;
		}

		for (var i = 0; i < this._mediaStack[key].items.length; i++) {
			if (this._mediaStack[key].items[i].namespace === ns) {
				delete this._mediaStack[key].items[i];
				this._mediaStack[key].items.splice(i, 1);
			}
		}
		return this;
	};

	/**
	 * Calls a specific ns, type, media reference
	 *
	 * @param ns String
	 * @param type String
 	 * @param mqString String (optional)
	 * @return {*}
	 */
	Respond.call = function(ns, type, mqString) {
		try {
			if (mqString && type) {
				(this._retrieve(ns, mqString))[type](this);
			} else if (type) {
				(this._retrieve(ns))[type](this);
			} else {
				this._respond(this._mediaStack[this._purify((this._retrieve(ns)).media)].mql, ns);
			}
		} catch (e) {
			console.error(e);
		}
		return this;
	};

}).call(this);
<|endoftext|>


<commit_before>'use strict';

module.exports = function (domjs) {
	domjs._directives._element.fixed = function () {
		var element = this, style = element.style, isFixed;
		window.addEventListener('scroll', function () {
			if (window.pageYOffset >= element.offsetTop) {
				if (isFixed) return;
				style.position = 'fixed';
				style.top = '0';
				isFixed = true;
				return;
			}
			if (!isFixed) return;
			style.position = style.top = '';
			isFixed = false;
		}, false);
	};
};
<commit_msg>Fix `fixed` directive internal logic<commit_after>'use strict';

module.exports = function (domjs) {
	domjs._directives._element.fixed = function () {
		var element = this, style = element.style, isFixed, triggerPos;
		window.addEventListener('scroll', function () {
			if (window.pageYOffset >= (isFixed ? triggerPos : element.offsetTop)) {
				if (isFixed) return;
				triggerPos = element.offsetTop;
				style.position = 'fixed';
				style.top = '0';
				isFixed = true;
				return;
			}
			if (!isFixed) return;
			style.position = style.top = '';
			isFixed = false;
		}, false);
	};
};
<|endoftext|>


<commit_before>#!/usr/bin/env node
var fs = require('fs')
var path = require('path')
var execSync = require('child_process').execSync
var yargs = require('yargs')

var argv = yargs.options({
  'run-only': {
    type: 'boolean',
    default: false
  },
  'entry-point': {
    type: 'string'
  }
}).argv

console.log('Checking if jsreport installed')

try {
  fs.statSync(path.join(process.cwd(), 'node_modules', 'jsreport'))
} catch (e) {
  console.log('Installing the latest jsreport, this takes few minutes')
  execSync('npm install jsreport --no-save', { stdio: [0, 1, 2] })
}

function tryRequire (module) {
  try {
    return fs.statSync(module)
  } catch (e) {
    return false
  }
}

function installStudio (p) {
  console.log('Installing jsreport-studio dev dependencies at ' + p)
  return execSync('npm install', { stdio: [0, 1, 2], cwd: p })
}

function installStudioIfRequired (p) {
  var packageJson
  try {
    packageJson = JSON.parse(fs.readFileSync(path.join(p, 'package.json'), 'utf8'))
  } catch (e) {
    return
  }

  for (var k in packageJson.devDependencies) {
    if (!tryRequire(path.join(p, 'node_modules', k))) {
      // somehow npm install failes on EBUSY error if this field is not deleted
      delete packageJson._requiredBy
      fs.writeFileSync(path.join(p, 'package.json'), JSON.stringify(packageJson, null, 2), 'utf8')
      return installStudio(p)
    }
  }
}

if (!argv.runOnly) {
  console.log('Making sure jsreport-studio has dev dependencies installed')
  installStudioIfRequired(path.join(process.cwd(), 'node_modules', 'jsreport', 'node_modules', 'jsreport-studio'))
  installStudioIfRequired(path.join(process.cwd(), 'node_modules', 'jsreport-studio'))
}

console.log('Starting ...')

if (!argv.runOnly) {
  process.env.NODE_ENV = 'jsreport-development'
}

if (!argv.entryPoint) {
  var jsreport = require(path.join(process.cwd(), 'node_modules', 'jsreport'))
  jsreport().init().catch(function (e) {
    console.error(e)
  })
} else {
  var entryPath = path.resolve(process.cwd(), argv.entryPoint)

  console.log('Using custom entry point at ' + entryPath)
  require(entryPath)
}
<commit_msg>always use process.cwd as rootDirectory<commit_after>#!/usr/bin/env node
var fs = require('fs')
var path = require('path')
var execSync = require('child_process').execSync
var yargs = require('yargs')

var argv = yargs.options({
  'run-only': {
    type: 'boolean',
    default: false
  },
  'entry-point': {
    type: 'string'
  }
}).argv

console.log('Checking if jsreport installed')

try {
  fs.statSync(path.join(process.cwd(), 'node_modules', 'jsreport'))
} catch (e) {
  console.log('Installing the latest jsreport, this takes few minutes')
  execSync('npm install jsreport --no-save', { stdio: [0, 1, 2] })
}

function tryRequire (module) {
  try {
    return fs.statSync(module)
  } catch (e) {
    return false
  }
}

function installStudio (p) {
  console.log('Installing jsreport-studio dev dependencies at ' + p)
  return execSync('npm install', { stdio: [0, 1, 2], cwd: p })
}

function installStudioIfRequired (p) {
  var packageJson
  try {
    packageJson = JSON.parse(fs.readFileSync(path.join(p, 'package.json'), 'utf8'))
  } catch (e) {
    return
  }

  for (var k in packageJson.devDependencies) {
    if (!tryRequire(path.join(p, 'node_modules', k))) {
      // somehow npm install failes on EBUSY error if this field is not deleted
      delete packageJson._requiredBy
      fs.writeFileSync(path.join(p, 'package.json'), JSON.stringify(packageJson, null, 2), 'utf8')
      return installStudio(p)
    }
  }
}

if (!argv.runOnly) {
  console.log('Making sure jsreport-studio has dev dependencies installed')
  installStudioIfRequired(path.join(process.cwd(), 'node_modules', 'jsreport', 'node_modules', 'jsreport-studio'))
  installStudioIfRequired(path.join(process.cwd(), 'node_modules', 'jsreport-studio'))
}

console.log('Starting ...')

if (!argv.runOnly) {
  process.env.NODE_ENV = 'jsreport-development'
}

if (!argv.entryPoint) {
  var jsreport = require(path.join(process.cwd(), 'node_modules', 'jsreport'))
  jsreport({
    rootDirectory: process.cwd()
  }).init().catch(function (e) {
    console.error(e)
  })
} else {
  var entryPath = path.resolve(process.cwd(), argv.entryPoint)

  console.log('Using custom entry point at ' + entryPath)
  require(entryPath)
}
<|endoftext|>


<commit_before>var position = 2;
var title = "Custome plugin row";
var callback = function(changeNo) {
  var widget = document.createElement("button");
  widget.innerHTML = "click me!";
  widget.onclick = function() {
	  alert("Welcome in change: " + changeNo);
  };
  return widget;
}

gerrit.onChangeScreen().addChangeInfoRow(position, title, callback);<commit_msg>Use more consistent API<commit_after>var position = 2;
var title = "Custome plugin row";
var callback = function(changeNo) {
  var widget = document.createElement("button");
  widget.innerHTML = "click me!";
  widget.onclick = function() {
	  alert("Welcome in change: " + changeNo);
  };
  return widget;
}

gerrit.onChangeScreen.insertRowToChangeInfoTable(position, title, callback);<|endoftext|>


<commit_before>// ==UserScript==
// @name         RohBot Currency Converter
// @version      1.5
// @description  Allows the user to select their currency and then converts any found currencies to the one the user selected
// @author       Spans
// @match        https://rohbot.net
// @grant        none
// @updateURL	 https://raw.githubusercontent.com/Spanfile/RohBot-Currency-Converter/master/converter.js
// @require		 http://openexchangerates.github.io/money.js/money.min.js
// @require		 http://code.jquery.com/jquery-2.1.4.min.js
// ==/UserScript==

// first of all, setup the currency conversion
$.getJSON("https://api.fixer.io/latest", function(data) {
	if (typeof fx !== "undefined" && fx.rates) {
		fx.rates = data.rates;
		fx.base = data.base;
	} else {
		var fxSetup = {
			rates: data.rates,
			base: base.rates
		};
	}

	//console.log("Currency test: €1 = $" + fx(1).from("EUR").to("USD"));
});

chatMgr.lineFilter.add(function(line, prepend, e) {
	line.Content = applyConversions(line.Content);
});

var user = "eur";

// the £ is for £
var currencies = {
	usd: { regex: /(?:\s|^)\$(\d+(?:(?:\.|,)\d+)?)(?=\s|$)/ig, name: "USD" },
	eur: { regex: /(?:\s|^)(\d+(?:(?:\.|,)\d+)?)€(?=\s|$)/ig, name: "EUR" },
	gbp: { regex: /(?:\s|^)(\d+(?:(?:\.|,)\d+)?)£(?=\s|$)/ig, name: "GBP" }
};

function applyConversions(message) {
	var results = [];
	var userCurrency = currencies[user.toLowerCase()]; // toLowerCase() in case it's in upper case

	// try to find and convert any currencies except the users currency found in the message to the users currency
	for (var key in currencies) {
		if (currencies.hasOwnProperty(key)) { // hasOwnProperty() makes sure we don't loop over stuff inherited from the object's prototype
			var currency = currencies[key];

			if (currency.name != userCurrency.name) {
				var result = commonConversion(message, currency, userCurrency);

				if (result.length > 0) {
					results.push(result);
				}
			}
		}
	}

	// since the converters can return multiple conversions, flatten the results
	// the result looks like [[{stuff here}, {stuff here}], [{stuff here}, {stuff here}]]
	// flattening it turns it into [{stuff here}, {stuff here}, {stuff here}, {stuff here}]
	var flattened = [].concat.apply([], results);

	// sort them
	flattened.sort(function(a, b) {
		if (a.index > b.index) {
			return 1;
		}

		if (a.index < b.index) {
			return -1;
		}

		return 0;
	});

	var newMsg = message;
	var inserted = 0;
	// combine them all
	flattened.forEach(function(result) {
		var title = result.conversion.toLocaleString("en-IN", {style: "currency", currency: result.unit});
		var original = result.original;
		var begin = "";

		// because the js regex engine doesn't support positive lookbehinds, the regexes return the whitespace before every match
		// most of the time they do it unless the match is at the start of the message
		// in case there is a whitespace, remove it and have one added before the  tag
		if (original.substring(0, 1) == " ") {
			original = original.substring(1);
			begin = " ";
		}

		var toInsert = begin + "" + original + "";
		newMsg = newMsg.splice(result.index + inserted, result.original.length, toInsert);
		inserted += toInsert.length - result.original.length;
	});

	return newMsg;
}

function commonConversion(message, from, to) {
	var m;
	var results = [];
	while ((m = from.regex.exec(message)) !== null) {
		if (m.index === from.regex.lastIndex) {
			regex.lastIndex++;
		}

		var amount = Number(m[1].replace(',', '.')); // js wants dots as decimal separators
		var converted = Math.round(fx(amount).from(from.name).to(to.name) * 100) / 100; // two decimals is enough for currencies

		results[results.length] = {original:m[0], index:m.index, conversion:converted, unit:to.name};
	}

	return results;
}

String.prototype.splice = function(idx, rem, s) {
	return (this.slice(0, idx) + s + this.slice(idx + Math.abs(rem)));
};
<commit_msg>Added CAD, AUD, NZD and SEK<commit_after>// ==UserScript==
// @name         RohBot Currency Converter
// @version      1.6
// @description  Allows the user to select their currency and then converts any found currencies to the one the user selected
// @author       Spans
// @match        https://rohbot.net
// @grant        none
// @updateURL	 https://raw.githubusercontent.com/Spanfile/RohBot-Currency-Converter/master/converter.js
// @require		 http://openexchangerates.github.io/money.js/money.min.js
// @require		 http://code.jquery.com/jquery-2.1.4.min.js
// ==/UserScript==

// first of all, setup the currency conversion
$.getJSON("https://api.fixer.io/latest", function(data) {
	if (typeof fx !== "undefined" && fx.rates) {
		fx.rates = data.rates;
		fx.base = data.base;
	} else {
		var fxSetup = {
			rates: data.rates,
			base: base.rates
		};
	}

	//console.log("Currency test: €1 = $" + fx(1).from("EUR").to("USD"));
});

chatMgr.lineFilter.add(function(line, prepend, e) {
	line.Content = applyConversions(line.Content);
});

var user = "eur";

// the £ is for £
var currencies = {
	usd: { regex: /(?:\s|^)\$(\d+(?:(?:\.|,)\d+)?)(?=\s|$)/ig, name: "USD" },
	eur: { regex: /(?:\s|^)(\d+(?:(?:\.|,)\d+)?)€(?=\s|$)/ig, name: "EUR" },
	gbp: { regex: /(?:\s|^)(\d+(?:(?:\.|,)\d+)?)£(?=\s|$)/ig, name: "GBP" },
	cad: { regex: /(?:\s|^)CA\$(\d+(?:(?:\.|,)\d+)?)(?=\s|$)/ig, name: "CAD" },
	aud: { regex: /(?:\s|^)A\$(\d+(?:(?:\.|,)\d+)?)(?=\s|$)/ig, name: "AUD" },
	nzd: { regex: /(?:\s|^)NZ\$(\d+(?:(?:\.|,)\d+)?)(?=\s|$)/ig, name: "NZD" },
	sek: { regex: /(?:\s|^)(\d+(?:(?:\.|,)\d+)?) ?kr(?=\s|$)/ig, name: "SEK" },
};

function applyConversions(message) {
	var results = [];
	var userCurrency = currencies[user.toLowerCase()]; // toLowerCase() in case it's in upper case

	// try to find and convert any currencies except the users currency found in the message to the users currency
	for (var key in currencies) {
		if (currencies.hasOwnProperty(key)) { // hasOwnProperty() makes sure we don't loop over stuff inherited from the object's prototype
			var currency = currencies[key];

			if (currency.name != userCurrency.name) {
				var result = commonConversion(message, currency, userCurrency);

				if (result.length > 0) {
					results.push(result);
				}
			}
		}
	}

	// since the converters can return multiple conversions, flatten the results
	// the result looks like [[{stuff here}, {stuff here}], [{stuff here}, {stuff here}]]
	// flattening it turns it into [{stuff here}, {stuff here}, {stuff here}, {stuff here}]
	var flattened = [].concat.apply([], results);

	// sort them
	flattened.sort(function(a, b) {
		if (a.index > b.index) {
			return 1;
		}

		if (a.index < b.index) {
			return -1;
		}

		return 0;
	});

	var newMsg = message;
	var inserted = 0;
	// combine them all
	flattened.forEach(function(result) {
		var title = result.conversion.toLocaleString("en-IN", {style: "currency", currency: result.unit});
		var original = result.original;
		var begin = "";

		// because the js regex engine doesn't support positive lookbehinds, the regexes return the whitespace before every match
		// most of the time they do it unless the match is at the start of the message
		// in case there is a whitespace, remove it and have one added before the  tag
		if (original.substring(0, 1) == " ") {
			original = original.substring(1);
			begin = " ";
		}

		var toInsert = begin + "" + original + "";
		newMsg = newMsg.splice(result.index + inserted, result.original.length, toInsert);
		inserted += toInsert.length - result.original.length;
	});

	return newMsg;
}

function commonConversion(message, from, to) {
	var m;
	var results = [];
	while ((m = from.regex.exec(message)) !== null) {
		if (m.index === from.regex.lastIndex) {
			regex.lastIndex++;
		}

		var amount = Number(m[1].replace(',', '.')); // js wants dots as decimal separators
		var converted = Math.round(fx(amount).from(from.name).to(to.name) * 100) / 100; // two decimals is enough for currencies

		results[results.length] = {original:m[0], index:m.index, conversion:converted, unit:to.name};
	}

	return results;
}

String.prototype.splice = function(idx, rem, s) {
	return (this.slice(0, idx) + s + this.slice(idx + Math.abs(rem)));
};
<|endoftext|>


<commit_before>"use strict";

var _Promise = require('bluebird');

var Oakpubsub = {};

Oakpubsub.init = function init(options) {

    Oakpubsub.gcloud = require('gcloud')({
      projectId: options.id,
      keyFilename: options.keyfile //TODO allow GCE scopes
    });

    Oakpubsub.pubsub = Oakpubsub.gcloud.pubsub();
}

Oakpubsub.getTopic = function getTopic(topic_title, options) {
    return Oakpubsub.pubsub.topic(topic_title, options);
}

Oakpubsub.ReallyPubSubscribe = function ReallyPubSubscribe(topic, subscription_id) {

    return Oakpubsub.CreateSubscription(topic, subscription_id)
    .catch(function(error) {

        if (error.code !== 409) {   //409: Resource already exists in the project
            throw error;
        }
        return topic.subscription(subscription_id);
    })
}

Oakpubsub.CreateSubscription = function CreateSubscription(topic, subscription_id) {

    var f = function(resolve, reject) {
        topic.subscribe(subscription_id, function(err, subscription) {
            if (err) {
                return reject(err);
            }
            resolve (subscription);
        })
    }
    return new _Promise(f);
}

Oakpubsub.publish = function publish(topic, message) {

    var f = function(resolve, reject) {

        var onComplete = function(error, messageIds, apiResponse) {

            if (error) {
                return reject(error);
            }
            resolve([messageIds, apiResponse]);
        }
        topic.publish(message, onComplete);
    }
    return new _Promise(f);
}

//ackIds may be a single string or Array of strings
Oakpubsub.ack = function ack(subscription, ackIds) {

    var f = function(resolve, reject) {

        var onComplete = function(error, apiResponse) {

            if (error) {
                return reject(error);
            }
            resolve(apiResponse);
        }
        subscription.ack(ackIds, onComplete);
    }
    return new _Promise(f);
}

module.exports = Oakpubsub;<commit_msg>rename ReallySubscribe to getOrCreateSubscription<commit_after>"use strict";

var _Promise = require('bluebird');

var Oakpubsub = {};

Oakpubsub.init = function init(options) {

    Oakpubsub.gcloud = require('gcloud')({
      projectId: options.id,
      keyFilename: options.keyfile //TODO allow GCE scopes
    });

    Oakpubsub.pubsub = Oakpubsub.gcloud.pubsub();
}

Oakpubsub.getTopic = function getTopic(topic_title, options) {
    return Oakpubsub.pubsub.topic(topic_title, options);
}

Oakpubsub.getOrCreateSubscription = function getOrCreateSubscription(topic, subscription_id) {

    return Oakpubsub.CreateSubscription(topic, subscription_id)
    .catch(function(error) {

        if (!error.code || error.code !== 409) {   //409: Resource already exists in the project
            throw error;
        }
        return topic.subscription(subscription_id);
    })
}

Oakpubsub.CreateSubscription = function CreateSubscription(topic, subscription_id) {

    var f = function(resolve, reject) {
        topic.subscribe(subscription_id, function(err, subscription) {
            if (err) {
                return reject(err);
            }
            resolve (subscription);
        })
    }
    return new _Promise(f);
}

Oakpubsub.publish = function publish(topic, message) {

    var f = function(resolve, reject) {

        var onComplete = function(error, messageIds, apiResponse) {

            if (error) {
                return reject(error);
            }
            resolve([messageIds, apiResponse]);
        }
        topic.publish(message, onComplete);
    }
    return new _Promise(f);
}

//ackIds may be a single string or Array of strings
Oakpubsub.ack = function ack(subscription, ackIds) {

    var f = function(resolve, reject) {

        var onComplete = function(error, apiResponse) {

            if (error) {
                return reject(error);
            }
            resolve(apiResponse);
        }
        subscription.ack(ackIds, onComplete);
    }
    return new _Promise(f);
}

module.exports = Oakpubsub;<|endoftext|>


<commit_before>import {
  moduleForComponent,
  test
} from 'ember-qunit';

import Ember from 'ember';

moduleForComponent('md-tabs', {
  // Specify the other units that are required for this test
  // needs: ['component:foo', 'helper:bar']
  needs: [
  'component:md-tab',
  'component:md-tab-item',
  'component:md-tab-content',
  'component:md-tabs-content-wrapper',
  'component:md-tabs-wrapper',
  'service:media-queries',
  'service:sniffer',
  'service:ripple',
  'service:constants']
  //'template:md-tabs-content-wrapper']
});

test('it renders', function(assert) {
  assert.expect(2);

  var template = Ember.HTMLBars.compile(
    '{{#md-tabs md-border-bottom="" selectedIndex=0}}' +
      '{{#md-tabs-wrapper}}'+
              '{{#md-tab label="test"}}' +
                  '<md-tab-label>test</md-tab-label>' +
              '{{/md-tab}}' +
      '{{/md-tabs-wrapper}}' +
      '{{#md-tabs-content-wrapper}}' +
          '{{#md-tab-content}}' +
              '
' +
                  'test' +
                  '
' +
              '
' +
          '{{/md-tab-content}}' +
      '{{/md-tabs-content-wrapper}}' +
  '{{/md-tabs}}');

  // Creates the component instance
  var component = this.subject({
    template: template
  });
  assert.equal(component._state, 'preRender');

  // Renders the component to the page
  this.render();

  assert.equal(component._state, 'inDOM');
});
<commit_msg>Fix some tests for tabs<commit_after>import {
  moduleForComponent,
  test
}
from 'ember-qunit';

import Ember from 'ember';

moduleForComponent('md-tabs', {
  // Specify the other units that are required for this test
  // needs: ['component:foo', 'helper:bar']
  needs: [
      'component:md-tab',
      'component:md-tab-item',
      'component:md-tab-content',
      'component:md-tabs-content-wrapper',
      'component:md-tabs-wrapper',
      'service:media-queries',
      'service:sniffer',
      'service:ripple',
      'service:constants'
    ]
    //'template:md-tabs-content-wrapper']
});

var oneTabTemplate = Ember.HTMLBars.compile(
  '{{#md-tabs-wrapper}}' +
    '{{#md-tab label="tab 1"}}' +
      '<md-tab-label>tab 1</md-tab-label>' +
    '{{/md-tab}}' +
  '{{/md-tabs-wrapper}}' +
  '{{#md-tabs-content-wrapper}}' +
    '{{#md-tab-content}}' +
      '
' +
        'tab 1' +
        '
' +
      '
' +
    '{{/md-tab-content}}' +
  '{{/md-tabs-content-wrapper}}');

var twoTabTemplate = Ember.HTMLBars.compile(
  '{{#md-tabs-wrapper}}' +
    '{{#md-tab label="tab 1"}}' +
      '<md-tab-label>tab 1</md-tab-label>' +
    '{{/md-tab}}' +
    '{{#md-tab label="tab 2"}}' +
      '<md-tab-label>tab 2</md-tab-label>' +
    '{{/md-tab}}' +
  '{{/md-tabs-wrapper}}' +
  '{{#md-tabs-content-wrapper}}' +
    '{{#md-tab-content}}' +
      '
' +
        'tab 1' +
        '
' +
      '
' +
    '{{/md-tab-content}}' +
    '{{#md-tab-content}}' +
      '
' +
        'tab 2' +
        '
' +
      '
' +
    '{{/md-tab-content}}' +
  '{{/md-tabs-content-wrapper}}');

test('it renders', function(assert) {
  assert.expect(2);

  // Creates the component instance
  var component = this.subject({
    template: oneTabTemplate
  });
  assert.equal(component._state, 'preRender');

  // Renders the component to the page
  this.render();

  assert.equal(component._state, 'inDOM');
});

test('selects first tab by default', function(assert) {
  var component = this.subject({
    template: twoTabTemplate
  });

  this.render();

  var firstTab = this.$().find('md-tab-item').eq(0);
  var secondTab = this.$().find('md-tab-item').eq(1);

  assert.ok(firstTab.hasClass('md-active'), 'First tab is selected');
  assert.ok(!secondTab.hasClass('md-active'), 'Second tab is not selected');
});

test('selects and focuses a tab on click', function(assert) {
  var component = this.subject({
    template: twoTabTemplate
  });

  this.render();

  var e = Ember.$.Event('click');

  var secondTab = this.$().find('md-tab-item').eq(1);

  assert.ok(secondTab, 'Second tab exists');

  Ember.run(() => {
    secondTab.trigger(e);
  });

  assert.ok(secondTab.hasClass('md-active'), 'Second tab is selected');
  assert.equal(component.get('selectedIndex'), 1, 'Second tab is selected');

});

test('changing selected index changes active tab', function(assert) {
  var component = this.subject({
    template: twoTabTemplate
  });

  this.render();

  Ember.run(() => {
    component.set('selectedIndex', 1);
  });

  var firstTab = this.$().find('md-tab-item').eq(0);
  var secondTab = this.$().find('md-tab-item').eq(1);
  assert.ok(!firstTab.hasClass('md-active'), 'First tab is not selected');
  assert.ok(secondTab.hasClass('md-active'), 'Second tab is selected');

});<|endoftext|>


<commit_before>var myLab = myLab || {};

(function (ns) {

  var Hero = function () {
    this.initialize();
  };

  var HeroProto = Hero.prototype = new createjs.Container();

  // publis 'static' properties
  Hero.WIDTH = 32;
  Hero.HEIGHT = 32;

  // status of hero movement. For its value, see variables Hero.MOVE_*
  HeroProto.currentStatus = Hero.STATUS_MOVE_NONE;
  Hero.STATUS_MOVE_NONE = 0;
  Hero.STATUS_MOVE_NORTH = 10;
  Hero.STATUS_MOVE_EAST = 20;
  Hero.STATUS_MOVE_SOUTH = 30;
  Hero.STATUS_MOVE_WEST = 40;

  // Hero movement speed, in pixel per second
  HeroProto.speedX = 0;
  HeroProto.speedY = 0;
  Hero.MAX_SPEED = 50;
  Hero.MIN_SPEED = -Hero.MAX_SPEED;

  HeroProto.initialize = function() {
    // create sprite sheet
    var frameFrequency = 3;  // the bigger the 'slower'
    var baseUrl = 'assets/TheLight-raw/';
    var spriteSheet = new createjs.SpriteSheet({
      images: [
        baseUrl + 'char_e1.png',
        baseUrl + 'char_e2.png',
        baseUrl + 'char_e3.png',

        baseUrl + 'char_s1.png',
        baseUrl + 'char_s2.png',
        baseUrl + 'char_s3.png',

        baseUrl + 'char_w1.png',
        baseUrl + 'char_w2.png',
        baseUrl + 'char_w3.png',

        baseUrl + 'char_n1.png',
        baseUrl + 'char_n2.png',
        baseUrl + 'char_n3.png',
      ],
      frames: {
        'height': Hero.WIDTH,
        'width': Hero.HEIGHT
      },
      animations: {
        walk_e: {
          frames: [ 0, 1, 0, 2 ],
          frequency: frameFrequency
        },
        stand_e: {
          frames: [ 0 ]
        },

        walk_s: {
          frames: [ 3, 4, 3, 5 ],
          frequency: frameFrequency
        },
        stand_s: {
          frames: [ 3 ]
        },

        walk_w: {
          frames: [ 6, 7, 6, 8 ],
          frequency: frameFrequency
        },
        stand_w: {
          frames: [ 6 ]
        },

        walk_n: {
          frames: [ 9, 10, 9, 11 ],
          frequency: frameFrequency
        },
        stand_n: {
          frames: [ 9 ]
        }
      }
    });

    // create hero assets
    this._animation = new createjs.BitmapAnimation(spriteSheet);
    this.addChild(this._animation);
  };

  // Reset the hero position before the game begins
  HeroProto.reset = function (canvas) {
    // centerize the hero in the middle of screen
    this.x = (canvas.width / 2) - (Hero.WIDTH / 2);
    this.y = (canvas.height / 2) - (Hero.HEIGHT / 2);

    // store movement limit
    this.minX = 0;
    this.minY = 0;
    this.maxX = canvas.width - Hero.WIDTH;
    this.maxY = canvas.height - Hero.HEIGHT;

    // force status
    this.setStatus(Hero.STATUS_MOVE_NONE, true);
  };

  // Change the hero status. This will handle animation and movement
  // For parameter newStatus, see Hero.
  HeroProto.setStatus = function (newStatus, force) {
    var oldStatus = this._currentStatus;
    if ((oldStatus === newStatus) && !force) {
      // nothing happen
      return;
    }

    // TODO validate new status
    this._currentStatus = newStatus;
    console.log('Changing hero status to ', newStatus);

    this._changeMovement();
    this._changeAnimation();
  };

  // change hero speed & movement based on new current status
  HeroProto._changeMovement = function () {
    switch (this._currentStatus) {
    case Hero.STATUS_MOVE_NONE:
      this.speedX = this.speedY = 0;
      break;

    case Hero.STATUS_MOVE_WEST:
      this.speedX = Hero.MIN_SPEED;
      this.speedY = 0;
      break;

    case Hero.STATUS_MOVE_SOUTH:
      this.speedX = 0;
      this.speedY = Hero.MAX_SPEED;
      break;

    case Hero.STATUS_MOVE_EAST:
      this.speedX = Hero.MAX_SPEED;
      this.speedY = 0;
      break;

    case Hero.STATUS_MOVE_NORTH:
      this.speedX = 0;
      this.speedY = Hero.MIN_SPEED;
      break;
    }
  };

  // change and play new animation based on new current status
  HeroProto._changeAnimation = function () {
    // mapping between status and animation name
    var animationName;
    switch (this._currentStatus) {
    case Hero.STATUS_MOVE_NONE:
      // always stand facing south
      animationName = 'stand_s';
      break;

    case Hero.STATUS_MOVE_WEST:
      animationName = 'walk_w';
      break;

    case Hero.STATUS_MOVE_SOUTH:
      animationName = 'walk_s';
      break;

    case Hero.STATUS_MOVE_EAST:
      animationName = 'walk_e';
      break;

    case Hero.STATUS_MOVE_NORTH:
      animationName = 'walk_n';
      break;
    }

    if (animationName) {
      this._animation.gotoAndPlay(animationName);
      console.log('Playing animation', animationName);
    }
  };

  // Update hero movement and other status
  HeroProto.update = function (event) {
    // update position
    var delta = event.delta * 0.001;
    this.x += (this.speedX * delta);
    this.y += (this.speedY * delta);
  };

  ns.Hero = Hero;
})(myLab);
<commit_msg>Round the position to prevent sprite blurring<commit_after>var myLab = myLab || {};

(function (ns) {

  var Hero = function () {
    this.initialize();
  };

  var HeroProto = Hero.prototype = new createjs.Container();

  // publis 'static' properties
  Hero.WIDTH = 32;
  Hero.HEIGHT = 32;

  // status of hero movement. For its value, see variables Hero.MOVE_*
  HeroProto.currentStatus = Hero.STATUS_MOVE_NONE;
  Hero.STATUS_MOVE_NONE = 0;
  Hero.STATUS_MOVE_NORTH = 10;
  Hero.STATUS_MOVE_EAST = 20;
  Hero.STATUS_MOVE_SOUTH = 30;
  Hero.STATUS_MOVE_WEST = 40;

  // Hero movement speed, in pixel per second
  HeroProto.speedX = 0;
  HeroProto.speedY = 0;
  Hero.MAX_SPEED = 50;
  Hero.MIN_SPEED = -Hero.MAX_SPEED;

  HeroProto.initialize = function() {
    // create sprite sheet
    var frameFrequency = 3;  // the bigger the 'slower'
    var baseUrl = 'assets/TheLight-raw/';
    var spriteSheet = new createjs.SpriteSheet({
      images: [
        baseUrl + 'char_e1.png',
        baseUrl + 'char_e2.png',
        baseUrl + 'char_e3.png',

        baseUrl + 'char_s1.png',
        baseUrl + 'char_s2.png',
        baseUrl + 'char_s3.png',

        baseUrl + 'char_w1.png',
        baseUrl + 'char_w2.png',
        baseUrl + 'char_w3.png',

        baseUrl + 'char_n1.png',
        baseUrl + 'char_n2.png',
        baseUrl + 'char_n3.png',
      ],
      frames: {
        'height': Hero.WIDTH,
        'width': Hero.HEIGHT
      },
      animations: {
        walk_e: {
          frames: [ 0, 1, 0, 2 ],
          frequency: frameFrequency
        },
        stand_e: {
          frames: [ 0 ]
        },

        walk_s: {
          frames: [ 3, 4, 3, 5 ],
          frequency: frameFrequency
        },
        stand_s: {
          frames: [ 3 ]
        },

        walk_w: {
          frames: [ 6, 7, 6, 8 ],
          frequency: frameFrequency
        },
        stand_w: {
          frames: [ 6 ]
        },

        walk_n: {
          frames: [ 9, 10, 9, 11 ],
          frequency: frameFrequency
        },
        stand_n: {
          frames: [ 9 ]
        }
      }
    });

    // create hero assets
    this._animation = new createjs.BitmapAnimation(spriteSheet);
    this.addChild(this._animation);
  };

  // Reset the hero position before the game begins
  HeroProto.reset = function (canvas) {
    // centerize the hero in the middle of screen
    this.x = (canvas.width / 2) - (Hero.WIDTH / 2);
    this.y = (canvas.height / 2) - (Hero.HEIGHT / 2);

    // store movement limit
    this.minX = 0;
    this.minY = 0;
    this.maxX = canvas.width - Hero.WIDTH;
    this.maxY = canvas.height - Hero.HEIGHT;

    // force status
    this.setStatus(Hero.STATUS_MOVE_NONE, true);
  };

  // Change the hero status. This will handle animation and movement
  // For parameter newStatus, see Hero.
  HeroProto.setStatus = function (newStatus, force) {
    var oldStatus = this._currentStatus;
    if ((oldStatus === newStatus) && !force) {
      // nothing happen
      return;
    }

    // TODO validate new status
    this._currentStatus = newStatus;
    console.log('Changing hero status to ', newStatus);

    this._changeMovement();
    this._changeAnimation();
  };

  // change hero speed & movement based on new current status
  HeroProto._changeMovement = function () {
    switch (this._currentStatus) {
    case Hero.STATUS_MOVE_NONE:
      this.speedX = this.speedY = 0;
      break;

    case Hero.STATUS_MOVE_WEST:
      this.speedX = Hero.MIN_SPEED;
      this.speedY = 0;
      break;

    case Hero.STATUS_MOVE_SOUTH:
      this.speedX = 0;
      this.speedY = Hero.MAX_SPEED;
      break;

    case Hero.STATUS_MOVE_EAST:
      this.speedX = Hero.MAX_SPEED;
      this.speedY = 0;
      break;

    case Hero.STATUS_MOVE_NORTH:
      this.speedX = 0;
      this.speedY = Hero.MIN_SPEED;
      break;
    }
  };

  // change and play new animation based on new current status
  HeroProto._changeAnimation = function () {
    // mapping between status and animation name
    var animationName;
    switch (this._currentStatus) {
    case Hero.STATUS_MOVE_NONE:
      // always stand facing south
      animationName = 'stand_s';
      break;

    case Hero.STATUS_MOVE_WEST:
      animationName = 'walk_w';
      break;

    case Hero.STATUS_MOVE_SOUTH:
      animationName = 'walk_s';
      break;

    case Hero.STATUS_MOVE_EAST:
      animationName = 'walk_e';
      break;

    case Hero.STATUS_MOVE_NORTH:
      animationName = 'walk_n';
      break;
    }

    if (animationName) {
      this._animation.gotoAndPlay(animationName);
      console.log('Playing animation', animationName);
    }
  };

  // Update hero movement and other status
  HeroProto.update = function (event) {
    // update position
    var delta = event.delta * 0.001;
    this.x += Math.floor(this.speedX * delta);
    this.y += Math.floor(this.speedY * delta);
  };

  ns.Hero = Hero;
})(myLab);
<|endoftext|>


<commit_before>goog.provide('og.Globus');

goog.require('og.webgl.Handler');
goog.require('og.Renderer');
goog.require('og.node.Planet');
goog.require('og.ellipsoid.wgs84');

/**
 * var globe = new og.Globus({
 *   viewExtent: new og.Extent(new og.LonLat(-180,-90), new og.LonLat(180,90)),
 *   ellipsoid: og.ellipsoid.wgs84,
 *   layers: [
 *     new og.layers.XYZ()
 *   ],
 *   terrains: [
 *     new og.terrain
 *   ],
 *   controls: [
 *     new og.controls.LayerSwitcher({autoActivated:true})
 *   ],
 *   name: "Earth",
 *   target: 'globus'
 */

og.Globus = function (options) {

    //Canvas creation.
    var _canvasId = og.Globus.CANVAS_ID_PREFIX + og.Globus.__id;
    var _canvas = document.createElement("canvas");
    _canvas.id = _canvasId;
    _canvas.style.width = "100%";
    _canvas.style.height = "100%";
    _canvas.style.display = "block";
    _canvas.style.opacity = "1.0";

    /**
     * @public
     * @type {Element}
     */
    this.div = document.getElementById(options.target);
    this.div.appendChild(_canvas);
    this.div.classList.add("ogViewport");
    function _disableWheel() { return false; };
    function _enableWheel() { return true; };
    this.div.onmouseenter = function () { document.onmousewheel = _disableWheel };
    this.div.onmouseleave = function () { document.onmousewheel = _enableWheel };

    //WegGL handler creation
    var _handler = new og.webgl.Handler(_canvasId, { alpha: false });
    _handler.init();

    /**
     * @public
     * @type {Element}
     */
    this.renderer = new og.Renderer(_handler);
    this.renderer.init();
    this.renderer.div = this.div;
    this.renderer.div.attributions = document.createElement("div");
    this.renderer.div.attributions.classList.add("ogAttribution");
    this.div.appendChild(this.renderer.div.attributions);

    //Skybox
    if (options.skybox) {
        this.renderer.addRenderNode(options.skybox);
    }

    /**
     * Planet node name. Access by this.renderer.<name>
     * @private
     * @type {String}
     */
    this._planetName = options.name ? options.name : og.Globus.PLANET_NAME_PREFIX + og.Globus.__id;

    /**
     * Planet node
     * @public
     * @type {Object}
     */
    this.planet = new og.node.Planet(this._planetName, options.ellipsoid ? options.ellipsoid : og.ellipsoid.wgs84);
    if (options.layers) {
        this.planet.addLayers(options.layers);
    }

    //Attach terrain provider
    if (options.terrain) {
        this.planet.setTerrainProvider(options.terrain);
    }

    this.renderer.addRenderNode(this.planet);

    //Add controls
    if (options.controls) {
        this.renderer.addControls(options.controls)
    }

    og.Globus.__id++;

    //TODO: view center, altitude, extent
    if (options.viewExtent) {
        this.planet.viewToExtent(options.viewExtent);
    }

    //Run!
    if (isUndefined(options.autoActivate) || options.autoActivate)
        this.renderer.start();
};

/**
 * og.Globus static variables
 *
 */
og.Globus.__id = 1;
og.Globus.CANVAS_ID_PREFIX = "globus_viewport_";
og.Globus.PLANET_NAME_PREFIX = "globus_planet_";

function isUndefined(obj) {
    return obj === void 0;
};<commit_msg>Screen fading.<commit_after>goog.provide('og.Globus');

goog.require('og.webgl.Handler');
goog.require('og.Renderer');
goog.require('og.node.Planet');
goog.require('og.ellipsoid.wgs84');

/**
 * var globe = new og.Globus({
 *   viewExtent: new og.Extent(new og.LonLat(-180,-90), new og.LonLat(180,90)),
 *   ellipsoid: og.ellipsoid.wgs84,
 *   layers: [
 *     new og.layers.XYZ()
 *   ],
 *   terrains: [
 *     new og.terrain
 *   ],
 *   controls: [
 *     new og.controls.LayerSwitcher({autoActivated:true})
 *   ],
 *   name: "Earth",
 *   target: 'globus'
 */

og.Globus = function (options) {

    //Canvas creation.
    var _canvasId = og.Globus.CANVAS_ID_PREFIX + og.Globus.__id;
    var _canvas = document.createElement("canvas");
    _canvas.id = _canvasId;
    _canvas.style.width = "100%";
    _canvas.style.height = "100%";
    _canvas.style.display = "block";
    _canvas.style.opacity = "1.0";

    /**
     * @public
     * @type {Element}
     */
    this.div = document.getElementById(options.target);
    this.div.appendChild(_canvas);
    this.div.classList.add("ogViewport");
    function _disableWheel() { return false; };
    function _enableWheel() { return true; };
    this.div.onmouseenter = function () { document.onmousewheel = _disableWheel };
    this.div.onmouseleave = function () { document.onmousewheel = _enableWheel };

    //WegGL handler creation
    var _handler = new og.webgl.Handler(_canvasId, { alpha: false });
    _handler.init();

    /**
     * @public
     * @type {Element}
     */
    this.renderer = new og.Renderer(_handler);
    this.renderer.init();
    this.renderer.div = this.div;
    this.renderer.div.attributions = document.createElement("div");
    this.renderer.div.attributions.classList.add("ogAttribution");
    this.div.appendChild(this.renderer.div.attributions);

    //Skybox
    if (options.skybox) {
        this.renderer.addRenderNode(options.skybox);
    }

    /**
     * Planet node name. Access by this.renderer.<name>
     * @private
     * @type {String}
     */
    this._planetName = options.name ? options.name : og.Globus.PLANET_NAME_PREFIX + og.Globus.__id;

    /**
     * Planet node
     * @public
     * @type {Object}
     */
    this.planet = new og.node.Planet(this._planetName, options.ellipsoid ? options.ellipsoid : og.ellipsoid.wgs84);
    if (options.layers) {
        this.planet.addLayers(options.layers);
    }

    //Attach terrain provider
    if (options.terrain) {
        this.planet.setTerrainProvider(options.terrain);
    }

    this.renderer.addRenderNode(this.planet);

    //Add controls
    if (options.controls) {
        this.renderer.addControls(options.controls)
    }

    og.Globus.__id++;

    //TODO: view center, altitude, extent
    if (options.viewExtent) {
        this.planet.viewToExtent(options.viewExtent);
    }

    var opacityCounter = 0;
    var fadeHandler = null;
    var stopHandler = null;

    this.fadeIn = function (duration) {
        clearInterval(stopHandler);
        clearInterval(fadeHandler);
        _canvas.style.opacity = 0.0;
        opacityCounter = 0.0;
        var delta = 10.0;
        var d = 1.0 / (duration / delta);

        fadeHandler = setInterval(function () {
            opacityCounter += d;
            if (opacityCounter >= 1) {
                opacityCounter = 1.0;
                clearInterval(fadeHandler);
            }
            _canvas.style.opacity = opacityCounter;
        }, delta);
    };

    this.fadeOut = function (duration) {
        clearInterval(stopHandler);
        clearInterval(fadeHandler);
        _canvas.style.opacity = 1.0;
        opacityCounter = 1.0;
        var delta = 10.0;
        var d = 1 / (duration / delta);

        fadeHandler = setInterval(function () {
            opacityCounter -= d;
            if (opacityCounter <= 0.0) {
                opacityCounter = 0.0;
                clearInterval(fadeHandler);
            }
            _canvas.style.opacity = opacityCounter;
        }, delta);

    };

    //Run!
    if (isUndefined(options.autoActivate) || options.autoActivate)
        this.renderer.start();
};

/**
 * og.Globus static variables
 *
 */
og.Globus.__id = 1;
og.Globus.CANVAS_ID_PREFIX = "globus_viewport_";
og.Globus.PLANET_NAME_PREFIX = "globus_planet_";

function isUndefined(obj) {
    return obj === void 0;
};<|endoftext|>