<commit_before>
u.frederik = function() {
//	u.bug("activate frederik")

//	u.xInObject(window._jes_text);
	window._frederik = u.ae(document.body, "div", {"class":"frederik"});
	window._frederik._base_size = parseInt(u.gcs(document.body, "font-size"));
	window._frederik._toolbar = u.ae(window._frederik, "div", {"class":"toolbar", "html":"
FREDERIK!
"});

	window._frederik._focus = function() {
		u.e.addEvent(this, "keydown", window._frederik._update);
	}
	window._frederik._blur = function() {
		u.e.removeEvent(this, "keydown", window._frederik._update);
	}

	window._frederik._update = function(event) {

		event = event ? event : window.event;
		if(event.keyCode == 38) {
			if((event.ctrlKey || event.metaKey || event.shiftKey)) {
				this.value = (parseInt(this.value)+10);
			}
			else {
				this.value = (parseInt(this.value)+1);
			}
		}
		else if(event.keyCode == 40) {
			if((event.ctrlKey || event.metaKey || event.shiftKey)) {
				this.value = (parseInt(this.value)-10);
			}
			else {
				this.value = (parseInt(this.value)-1);
			}
		}
		window._jes_text.nodes[0].text_settings[this.node.s_tag][this.node.s_size] = this.value/window._frederik._base_size;

		window._jes_text.precalculate();
		window._jes_text.scale();
//		u.xInObject(window._jes_text.nodes[0].text_settings[this.node.s_tag]);

	}

	var i, node;
	for(i = 0; node = window._jes_text.nodes[i]; i++) {
		if(node.parentNode && node.offsetHeight) {

			var tag_index = 1;
			for(tag in node.text_settings) {
				var settings = node.text_settings[tag];

				var _tag = u.ae(window._frederik, "div", {"class":"tag tag"+tag_index});
				var tag_index = tag_index+1;

				// inject levers for each tag

				// min lever
				_tag._min = u.ae(_tag, "div", {"class":"min"});
				_tag._min.s_tag = tag;
				_tag._min.s_width = "min_width";
				_tag._min.s_size = "min_size";

				// _tag._min.width_setting = settings.min_width;
				// _tag._min.size_setting = settings.min_size;

				_tag._min.tag = u.ae(_tag._min, "div", {"class":"head"});
				u.ae(_tag._min.tag, "h2", {"html":tag+" min"});
				var w = u.ae(_tag._min.tag, "div", {"class":"width", "html":"width:"});
				var s = u.ae(_tag._min.tag, "div", {"class":"size", "html":"size:"});

				_tag._min._width = u.ae(w, "span", {"class":"width", "html":settings.min_width});
				_tag._min._size = u.ae(s, "input", {"class":"size", "value":settings.min_size*window._frederik._base_size});
				_tag._min._size.node = _tag._min;

				u.e.addEvent(_tag._min._size, "focus", window._frederik._focus);
				u.e.addEvent(_tag._min._size, "blur", window._frederik._blur);

				// position lever
				u.as(_tag._min, "left", settings.min_width+"px");

				// max lever
				_tag._max = u.ae(_tag, "div", {"class":"max"});
				_tag._max.s_tag = tag;
				_tag._max.s_width = "max_width";
				_tag._max.s_size = "max_size";

				// _tag._max.width_setting = settings.max_width;
				// _tag._max.size_setting = settings.max_size;

				_tag._max.tag = u.ae(_tag._max, "div", {"class":"head"});
				u.ae(_tag._max.tag, "h2", {"html":tag+" max"});
				var w = u.ae(_tag._max.tag, "div", {"class":"width", "html":"width:"});
				var s = u.ae(_tag._max.tag, "div", {"class":"size", "html":"size:"});

				_tag._max._width = u.ae(w, "span", {"class":"width", "html":settings.max_width});
				_tag._max._size = u.ae(s, "input", {"class":"size", "value":settings.max_size*window._frederik._base_size});
				_tag._max._size.node = _tag._max;

				u.e.addEvent(_tag._max._size, "focus", window._frederik._focus);
				u.e.addEvent(_tag._max._size, "blur", window._frederik._blur);

				// position lever
				u.as(_tag._max, "left", settings.max_width+"px");

				// enable drag
				u.frederikEnableDrag(_tag._min);
				u.frederikEnableDrag(_tag._max);

			}
		}
	}

}

u.frederikEnableDrag = function(node) {

	// click
	u.e.click(node);
	node.moved = function(event) {
		u.e.kill(event);
		// mouse offset to top/left corner
		this._offset_x = u.absX(this) - u.eventX(event);
		this._offset_y = u.absY(this) - u.eventY(event);

		document.body._frederik_is_dragging = this;

		// follow mouse events
		u.e.addMoveEvent(document.body, u.frederikDrag);
		u.e.addEndEvent(document.body, u.frederikDrop);
	}

	node._hessitate_at = {
		"600":true,
		"800":true,
		"960":true,
		"1024":true,
		"1366":true,
		"1280":true,
		"1600":true,
		"1920":true
	}
}

u.frederikDrag = function(event) {

	var node = document.body._frederik_is_dragging;

	var x = u.eventX(event)+node._offset_x;

	window._jes_text.nodes[0].text_settings[node.s_tag][node.s_width] = x;
	// if x is hessitation point, start timer
	// TODO: extend to check if number is passed since last event
	if(node._hessitate_at[x]) {
		node._width.innerHTML = x;
		node._hessitate_for = 17;
	}

	if(node && !node._hessitate_for) {
		node._width.innerHTML = x;
		u.as(node, "left", x + "px");
	}
	if(node._hessitate_for) {
		node._hessitate_for = node._hessitate_for-1;
	}

	window._jes_text.precalculate();
	window._jes_text.scale();

//	u.bug(window._jes_text.nodes[0].min_width);
//	u.xInObject(window._jes_text.nodes[0].text_settings["h1"]);
//	u.bug(node.width_setting);
}
u.frederikDrop = function() {
	u.e.removeMoveEvent(document.body, u.frederikDrag);
	u.e.removeEndEvent(document.body, u.frederikDrop);

	document.body._frederik_is_dragging = false;
}

// login to FREDERIK
u.isFrederik = function(event) {

	this._is_really_frederik = this._is_really_frederik ? this._is_really_frederik : [];
	event = event ? event : window.event;
	var key = String.fromCharCode(event.keyCode);

	// add key and test
	this._is_really_frederik.push(key);
	if(this._is_really_frederik.join("").toLowerCase() == "frederik") {

		u.e.removeEvent(document, "keydown", u.isFrederik);
		u.frederik();
	}
	// still on track
	else if(!("frederik").match(this._is_really_frederik.join("").toLowerCase())) {
		this._is_really_frederik = [];
	}

}

u.e.addEvent(document, "keydown", u.isFrederik);
<commit_msg>added frederik toggle<commit_after>
u.frederik = function() {
//	u.bug("activate frederik")

//	u.xInObject(window._jes_text);
	window._frederik = u.ae(document.body, "div", {"class":"frederik"});
	window._frederik._base_size = parseInt(u.gcs(document.body, "font-size"));
	window._frederik._toolbar = u.ae(window._frederik, "div", {"class":"toolbar", "html":"
FREDERIK!
"});

	window._frederik._focus = function() {
		u.e.addEvent(this, "keydown", window._frederik._update);
	}
	window._frederik._blur = function() {
		u.e.removeEvent(this, "keydown", window._frederik._update);
	}

	window._frederik._update = function(event) {

		event = event ? event : window.event;
		if(event.keyCode == 38) {
			if((event.ctrlKey || event.metaKey || event.shiftKey)) {
				this.value = (parseInt(this.value)+10);
			}
			else {
				this.value = (parseInt(this.value)+1);
			}
		}
		else if(event.keyCode == 40) {
			if((event.ctrlKey || event.metaKey || event.shiftKey)) {
				this.value = (parseInt(this.value)-10);
			}
			else {
				this.value = (parseInt(this.value)-1);
			}
		}
		window._jes_text.nodes[0].text_settings[this.node.s_tag][this.node.s_size] = this.value/window._frederik._base_size;

		window._jes_text.precalculate();
		window._jes_text.scale();
//		u.xInObject(window._jes_text.nodes[0].text_settings[this.node.s_tag]);

	}

	var i, node;
	for(i = 0; node = window._jes_text.nodes[i]; i++) {
		if(node.parentNode && node.offsetHeight) {

			var tag_index = 1;
			for(tag in node.text_settings) {
				var settings = node.text_settings[tag];

				var _tag = u.ae(window._frederik, "div", {"class":"tag tag"+tag_index});
				var tag_index = tag_index+1;

				// inject levers for each tag

				// min lever
				_tag._min = u.ae(_tag, "div", {"class":"min"});
				_tag._min.s_tag = tag;
				_tag._min.s_width = "min_width";
				_tag._min.s_size = "min_size";

				// _tag._min.width_setting = settings.min_width;
				// _tag._min.size_setting = settings.min_size;

				_tag._min.tag = u.ae(_tag._min, "div", {"class":"head"});
				u.ae(_tag._min.tag, "h2", {"html":tag+" min"});
				var w = u.ae(_tag._min.tag, "div", {"class":"width", "html":"width:"});
				var s = u.ae(_tag._min.tag, "div", {"class":"size", "html":"size:"});

				_tag._min._width = u.ae(w, "span", {"class":"width", "html":settings.min_width});
				_tag._min._size = u.ae(s, "input", {"class":"size", "value":settings.min_size*window._frederik._base_size});
				_tag._min._size.node = _tag._min;

				u.e.addEvent(_tag._min._size, "focus", window._frederik._focus);
				u.e.addEvent(_tag._min._size, "blur", window._frederik._blur);

				// position lever
				u.as(_tag._min, "left", settings.min_width+"px");

				// max lever
				_tag._max = u.ae(_tag, "div", {"class":"max"});
				_tag._max.s_tag = tag;
				_tag._max.s_width = "max_width";
				_tag._max.s_size = "max_size";

				// _tag._max.width_setting = settings.max_width;
				// _tag._max.size_setting = settings.max_size;

				_tag._max.tag = u.ae(_tag._max, "div", {"class":"head"});
				u.ae(_tag._max.tag, "h2", {"html":tag+" max"});
				var w = u.ae(_tag._max.tag, "div", {"class":"width", "html":"width:"});
				var s = u.ae(_tag._max.tag, "div", {"class":"size", "html":"size:"});

				_tag._max._width = u.ae(w, "span", {"class":"width", "html":settings.max_width});
				_tag._max._size = u.ae(s, "input", {"class":"size", "value":settings.max_size*window._frederik._base_size});
				_tag._max._size.node = _tag._max;

				u.e.addEvent(_tag._max._size, "focus", window._frederik._focus);
				u.e.addEvent(_tag._max._size, "blur", window._frederik._blur);

				// position lever
				u.as(_tag._max, "left", settings.max_width+"px");

				// enable drag
				u.frederikEnableDrag(_tag._min);
				u.frederikEnableDrag(_tag._max);

			}
		}
	}

}

u.frederikEnableDrag = function(node) {

	// click
	u.e.click(node);
	node.moved = function(event) {
		u.e.kill(event);
		// mouse offset to top/left corner
		this._offset_x = u.absX(this) - u.eventX(event);
		this._offset_y = u.absY(this) - u.eventY(event);

		document.body._frederik_is_dragging = this;

		// follow mouse events
		u.e.addMoveEvent(document.body, u.frederikDrag);
		u.e.addEndEvent(document.body, u.frederikDrop);
	}

	node._hessitate_at = {
		"600":true,
		"800":true,
		"960":true,
		"1024":true,
		"1366":true,
		"1280":true,
		"1600":true,
		"1920":true
	}
}

u.frederikDrag = function(event) {

	var node = document.body._frederik_is_dragging;

	var x = u.eventX(event)+node._offset_x;

	window._jes_text.nodes[0].text_settings[node.s_tag][node.s_width] = x;
	// if x is hessitation point, start timer
	// TODO: extend to check if number is passed since last event
	if(node._hessitate_at[x]) {
		node._width.innerHTML = x;
		node._hessitate_for = 17;
	}

	if(node && !node._hessitate_for) {
		node._width.innerHTML = x;
		u.as(node, "left", x + "px");
	}
	if(node._hessitate_for) {
		node._hessitate_for = node._hessitate_for-1;
	}

	window._jes_text.precalculate();
	window._jes_text.scale();

//	u.bug(window._jes_text.nodes[0].min_width);
//	u.xInObject(window._jes_text.nodes[0].text_settings["h1"]);
//	u.bug(node.width_setting);
}
u.frederikDrop = function() {
	u.e.removeMoveEvent(document.body, u.frederikDrag);
	u.e.removeEndEvent(document.body, u.frederikDrop);

	document.body._frederik_is_dragging = false;
}

// login to FREDERIK
u.isFrederik = function(event) {

	this._is_really_frederik = this._is_really_frederik ? this._is_really_frederik : [];
	event = event ? event : window.event;
	var key = String.fromCharCode(event.keyCode);

	// add key and test
	this._is_really_frederik.push(key);
	if(this._is_really_frederik.join("").toLowerCase() == "frederik") {

		u.e.removeEvent(document, "keydown", u.isFrederik);

		u.e.addEvent(document, "keydown", u.toggleFrederik);
		u.frederik();
	}
	// still on track
	else if(!("frederik").match(this._is_really_frederik.join("").toLowerCase())) {
		this._is_really_frederik = [];
	}

}

// login to FREDERIK
u.toggleFrederik = function(event) {
	event = event ? event : window.event;
	if(event.keyCode == 27) {
		if(u.gcs(window._frederik, "display") == "none") {
			u.as(window._frederik, "display", "block");
		}
		else {
			u.as(window._frederik, "display", "none");
		}
	}
}

u.e.addEvent(document, "keydown", u.isFrederik);
<|endoftext|>


<commit_before>"use strict";

var expect = require("expect.js"),
    STATICS = require("../../lib/client/ALAMID_CLIENT_CONST.js"),
    path = require("path"),
    compile = require("nodeclass").compile,
    DisplayObject = require("../../lib/client/DisplayObject.class.js"),
    ExtendedByDisplayObject = require("./mocks/ExtendedByDisplayObject.class.js");

describe("DisplayObject", function () {

    describe("# construct()", function () {

        it("should throw an error if no template is given", function () {
            expect(function () { var dO = new DisplayObject(); }).to.throwError();
        });

    });

    var $form,
        form,
        formTemplate,

        $submitButton,
        submitButton,
        submitButtonTemplate,

        displayObject,
        formDisplayObject,
        submitButtonDisplayObject;

    beforeEach(function () {
        form = DOMNodeMocks.getForm();
        $form = jQuery(form);
        formTemplate = DOMNodeMocks.getFormString();

        submitButton = DOMNodeMocks.getSubmitButton();
        $submitButton = jQuery(submitButton);
        submitButtonTemplate = DOMNodeMocks.getSubmitButtonString();

        displayObject = new DisplayObject(formTemplate);
        submitButtonDisplayObject = new ExtendedByDisplayObject(submitButtonTemplate);
        formDisplayObject = new ExtendedByDisplayObject(formTemplate);
    });

    describe("# getNode()", function () {

        it("should be an [object HTMLFormElement]", function () {
            expect(displayObject.getNode().toString()).to.be.equal("[object HTMLFormElement]");
        });

    });

    describe("# getNodeMap()", function () {

        it("should return an object", function () {
            //expect(displayObject.getNodeMap()).to.be.an(Object);
        });

        it("should return a map of nodes with a 'form'-, 'input-a'-, 'input-b'-, 'input-c'- node ", function () {
            var nodeMap = displayObject.getNodeMap();

            expect(nodeMap.form.toString()).to.be.equal("[object HTMLFormElement]");
            expect(nodeMap["input-a"].toString() === "[object HTMLInputElement]").to.be(true);
            expect(nodeMap["input-c"].toString() === "[object HTMLInputElement]").to.be(true);
            expect(nodeMap["input-c"].toString() === "[object HTMLInputElement]").to.be(true);
        });

    });

    describe("# _append()", function () {

        it("should throw an Error if an object not kind of DisplayObject is given", function () {
            expect(function () {
                formDisplayObject.append({});
            }).to.throwError();
        });

        it("should throw an Error if a not existent node name was passed to at()", function () {
            expect(function () {
                formDisplayObject.append(submitButtonDisplayObject).at("not_existing_node");
            }).to.throwError();
        });

        it("should return an object providing a function at()", function () {
            expect(formDisplayObject.append(submitButtonDisplayObject).at).to.be.a(Function);
        });

    });

    describe("# at()", function () {

        it("should return a reference to itself", function () {
            expect(formDisplayObject.append(submitButtonDisplayObject).at("form")).to.be.equal(formDisplayObject);
        });

        it("should append submit-button to form", function () {
            formDisplayObject.append(submitButtonDisplayObject).at("form");

            var $lastChild = jQuery(formDisplayObject.getNode()).find(":last-child"),
                lastChild = $lastChild[0];

            expect(lastChild.toString()).to.be.equal(submitButtonDisplayObject.getNode().toString());
            expect($lastChild.val()).to.be.equal(submitButtonDisplayObject.getNode().value);
        });

    });

    describe("# addNodeEvents()", function () {
        it("should throw an Error if you try to attach events to a not existing node", function () {

            expect(function () {
                displayObject.addNodeEvents({
                    "not_existing_node": {
                        "click": function () {
                            //do nothing
                        }
                    }
                });
            }).to.throwError();
        });

    });

    describe("# destroy()", function () {

        it("should return a reference to itself", function () {
            expect(submitButtonDisplayObject.destroy()).to.be.equal(submitButtonDisplayObject);
        });

        it("should remove itself from parent node", function () {
            formDisplayObject.append(submitButtonDisplayObject).at("form");
            submitButtonDisplayObject.destroy();
            expect(jQuery(formDisplayObject.getNode()).find("[type='submit']").length).to.be.equal(0);
        });

        it("should be still possible to trigger attached events after # destroy()", function (done) {
            submitButtonDisplayObject.addNodeEvents({
                "submit-button": {
                    "click": function () {
                        done();
                    }
                }
            });

            formDisplayObject.append(submitButtonDisplayObject).at("form");

            submitButtonDisplayObject.destroy();

            jQuery(submitButtonDisplayObject.getNode()).click();
        });

        it("should be possible to re-append a destroyed DisplayObject", function () {
            formDisplayObject.append(submitButtonDisplayObject).at("form");
            submitButtonDisplayObject.destroy();
            formDisplayObject.append(submitButtonDisplayObject).at("form");

            expect(
                jQuery(formDisplayObject.getNode()).find("[type='submit']")[0].toString()
            ).to.be.equal(submitButtonDisplayObject.getNode().toString());
        });

    });

    describe("# dispose()", function () {

        it("should return a reference to itself", function () {
            expect(submitButtonDisplayObject.dispose()).to.be(submitButtonDisplayObject);
        });

        it("should remove itself from parent node", function () {
            formDisplayObject.append(submitButtonDisplayObject).at("form");
            submitButtonDisplayObject.dispose();
            expect(jQuery(formDisplayObject.getNode()).find("[type='submit']").length).to.be.equal(0);
        });

        it("should NOT be possible to trigger before attached events after # dispose()", function (done) {
            submitButtonDisplayObject.addNodeEvents({
                "submit-button": {
                    "click": function () {
                        done();
                    }
                }
            });

            formDisplayObject.append(submitButtonDisplayObject).at("form");

            submitButtonDisplayObject.dispose();

            jQuery(submitButtonDisplayObject.getNode()).click();

            done();
        });

        it("should be possible to re-append a disposed DisplayObject", function () {
            formDisplayObject.append(submitButtonDisplayObject).at("form");
            submitButtonDisplayObject.dispose();
            formDisplayObject.append(submitButtonDisplayObject).at("form");

            expect(
                jQuery(formDisplayObject.getNode()).find("[type='submit']")[0].toString()
            ).to.be.equal(submitButtonDisplayObject.getNode().toString());
        });
    });

    describe("# hide()", function () {

        it("node should have the attribute class with at least " + STATICS.HIDE_CLASS + " as value", function () {
            displayObject.hide();
            expect(jQuery(displayObject.getNode()).hasClass(STATICS.HIDE_CLASS)).to.be(true);
        });
    });

    describe("# display()", function () {

        it("node should NOT have the attribute class with " + STATICS.HIDE_CLASS + " as value", function () {
            displayObject.display();
            expect(jQuery(displayObject.getNode()).hasClass(STATICS.HIDE_CLASS)).to.be(false);
        });

    });

    describe("# isDisplayed()", function () {

        it("should be true by default value", function () {
            expect(displayObject.isDisplayed()).to.be(true);
        });

        it("should be false after # hide()", function () {
            displayObject.hide();
            expect(displayObject.isDisplayed()).to.be(false);
        });

        it("should be true after # hide() and then # display()", function () {
            displayObject.hide();
            displayObject.display();
            expect(displayObject.isDisplayed()).to.be(true);
        });

    });

    describe("# isAppended()", function () {

        var formDisplayObject,
            submitButtonDisplayObject;

        beforeEach(function () {
            formDisplayObject = new ExtendedByDisplayObject(formTemplate);
            submitButtonDisplayObject = new ExtendedByDisplayObject(submitButtonTemplate);

            formDisplayObject.append(submitButtonDisplayObject).at("form");
        });

        it("should be false by default (=just created and not appended anywhere)", function () {
            expect(formDisplayObject.isAppended()).to.be(false);
        });

        it("should be true after appending it anywhere", function () {
            expect(submitButtonDisplayObject.isAppended()).to.be(true);
        });

        it("should be false after # destroy()", function () {
            submitButtonDisplayObject.destroy();
            expect(submitButtonDisplayObject.isAppended()).to.be(false);
        });

        it("should be false after # dispose()", function () {
            submitButtonDisplayObject.dispose();
            expect(submitButtonDisplayObject.isAppended()).to.be(false);
        });
    });
});<commit_msg>Added a further test for addNodeEvents()<commit_after>"use strict";

var expect = require("expect.js"),
    STATICS = require("../../lib/client/ALAMID_CLIENT_CONST.js"),
    path = require("path"),
    compile = require("nodeclass").compile,
    DisplayObject = require("../../lib/client/DisplayObject.class.js"),
    ExtendedByDisplayObject = require("./mocks/ExtendedByDisplayObject.class.js");

describe("DisplayObject", function () {

    describe("# construct()", function () {

        it("should throw an error if no template is given", function () {
            expect(function () { var dO = new DisplayObject(); }).to.throwError();
        });

    });

    var $form,
        form,
        formTemplate,

        $submitButton,
        submitButton,
        submitButtonTemplate,

        displayObject,
        formDisplayObject,
        submitButtonDisplayObject;

    beforeEach(function () {
        form = DOMNodeMocks.getForm();
        $form = jQuery(form);
        formTemplate = DOMNodeMocks.getFormString();

        submitButton = DOMNodeMocks.getSubmitButton();
        $submitButton = jQuery(submitButton);
        submitButtonTemplate = DOMNodeMocks.getSubmitButtonString();

        displayObject = new DisplayObject(formTemplate);
        submitButtonDisplayObject = new ExtendedByDisplayObject(submitButtonTemplate);
        formDisplayObject = new ExtendedByDisplayObject(formTemplate);
    });

    describe("# getNode()", function () {

        it("should be an [object HTMLFormElement]", function () {
            expect(displayObject.getNode().toString()).to.be.equal("[object HTMLFormElement]");
        });

    });

    describe("# getNodeMap()", function () {

        it("should return an object", function () {
            //expect(displayObject.getNodeMap()).to.be.an(Object);
        });

        it("should return a map of nodes with a 'form'-, 'input-a'-, 'input-b'-, 'input-c'- node ", function () {
            var nodeMap = displayObject.getNodeMap();

            expect(nodeMap.form.toString()).to.be.equal("[object HTMLFormElement]");
            expect(nodeMap["input-a"].toString() === "[object HTMLInputElement]").to.be(true);
            expect(nodeMap["input-c"].toString() === "[object HTMLInputElement]").to.be(true);
            expect(nodeMap["input-c"].toString() === "[object HTMLInputElement]").to.be(true);
        });

    });

    describe("# _append()", function () {

        it("should throw an Error if an object not kind of DisplayObject is given", function () {
            expect(function () {
                formDisplayObject.append({});
            }).to.throwError();
        });

        it("should throw an Error if a not existent node name was passed to at()", function () {
            expect(function () {
                formDisplayObject.append(submitButtonDisplayObject).at("not_existing_node");
            }).to.throwError();
        });

        it("should return an object providing a function at()", function () {
            expect(formDisplayObject.append(submitButtonDisplayObject).at).to.be.a(Function);
        });

    });

    describe("# at()", function () {

        it("should return a reference to itself", function () {
            expect(formDisplayObject.append(submitButtonDisplayObject).at("form")).to.be.equal(formDisplayObject);
        });

        it("should append submit-button to form", function () {
            formDisplayObject.append(submitButtonDisplayObject).at("form");

            var $lastChild = jQuery(formDisplayObject.getNode()).find(":last-child"),
                lastChild = $lastChild[0];

            expect(lastChild.toString()).to.be.equal(submitButtonDisplayObject.getNode().toString());
            expect($lastChild.val()).to.be.equal(submitButtonDisplayObject.getNode().value);
        });

    });

    describe("# addNodeEvents()", function () {

        it("should throw an Error if you try to attach events to a not existing node", function () {
            expect(function () {
                displayObject.addNodeEvents({
                    "not_existing_node": {
                        "click": function () {
                            //do nothing
                        }
                    }
                });
            }).to.throwError();
        });

        it("should attach Events to nodes", function () {
            var focusEvent = "untriggred",
                blurEvent = "untriggered",
                $inputA = jQuery(formDisplayObject.getNode()).find("[data-node='input-a']"),
                $inputB = jQuery(formDisplayObject.getNode()).find("[data-node='input-b']");

            formDisplayObject.addNodeEvents({
                "input-a": {
                    "focus": function () {
                        focusEvent = "triggered";
                    }
                },
                "input-b": {
                    "blur": function () {
                        blurEvent = "triggered";
                    }
                }
            });

            $inputA.focus();
            $inputB.blur();

            expect(focusEvent).to.be.equal("triggered");
            expect(blurEvent).to.be.equal("triggered");
        });

    });

    describe("# destroy()", function () {

        it("should return a reference to itself", function () {
            expect(submitButtonDisplayObject.destroy()).to.be.equal(submitButtonDisplayObject);
        });

        it("should remove itself from parent node", function () {
            formDisplayObject.append(submitButtonDisplayObject).at("form");
            submitButtonDisplayObject.destroy();
            expect(jQuery(formDisplayObject.getNode()).find("[type='submit']").length).to.be.equal(0);
        });

        it("should be still possible to trigger attached events after # destroy()", function (done) {
            submitButtonDisplayObject.addNodeEvents({
                "submit-button": {
                    "click": function () {
                        done();
                    }
                }
            });

            formDisplayObject.append(submitButtonDisplayObject).at("form");

            submitButtonDisplayObject.destroy();

            jQuery(submitButtonDisplayObject.getNode()).click();
        });

        it("should be possible to re-append a destroyed DisplayObject", function () {
            formDisplayObject.append(submitButtonDisplayObject).at("form");
            submitButtonDisplayObject.destroy();
            formDisplayObject.append(submitButtonDisplayObject).at("form");

            expect(
                jQuery(formDisplayObject.getNode()).find("[type='submit']")[0].toString()
            ).to.be.equal(submitButtonDisplayObject.getNode().toString());
        });

    });

    describe("# dispose()", function () {

        it("should return a reference to itself", function () {
            expect(submitButtonDisplayObject.dispose()).to.be(submitButtonDisplayObject);
        });

        it("should remove itself from parent node", function () {
            formDisplayObject.append(submitButtonDisplayObject).at("form");
            submitButtonDisplayObject.dispose();
            expect(jQuery(formDisplayObject.getNode()).find("[type='submit']").length).to.be.equal(0);
        });

        it("should NOT be possible to trigger before attached events after # dispose()", function (done) {
            submitButtonDisplayObject.addNodeEvents({
                "submit-button": {
                    "click": function () {
                        done();
                    }
                }
            });

            formDisplayObject.append(submitButtonDisplayObject).at("form");

            submitButtonDisplayObject.dispose();

            jQuery(submitButtonDisplayObject.getNode()).click();

            done();
        });

        it("should be possible to re-append a disposed DisplayObject", function () {
            formDisplayObject.append(submitButtonDisplayObject).at("form");
            submitButtonDisplayObject.dispose();
            formDisplayObject.append(submitButtonDisplayObject).at("form");

            expect(
                jQuery(formDisplayObject.getNode()).find("[type='submit']")[0].toString()
            ).to.be.equal(submitButtonDisplayObject.getNode().toString());
        });
    });

    describe("# hide()", function () {

        it("node should have the attribute class with at least " + STATICS.HIDE_CLASS + " as value", function () {
            displayObject.hide();
            expect(jQuery(displayObject.getNode()).hasClass(STATICS.HIDE_CLASS)).to.be(true);
        });
    });

    describe("# display()", function () {

        it("node should NOT have the attribute class with " + STATICS.HIDE_CLASS + " as value", function () {
            displayObject.display();
            expect(jQuery(displayObject.getNode()).hasClass(STATICS.HIDE_CLASS)).to.be(false);
        });

    });

    describe("# isDisplayed()", function () {

        it("should be true by default value", function () {
            expect(displayObject.isDisplayed()).to.be(true);
        });

        it("should be false after # hide()", function () {
            displayObject.hide();
            expect(displayObject.isDisplayed()).to.be(false);
        });

        it("should be true after # hide() and then # display()", function () {
            displayObject.hide();
            displayObject.display();
            expect(displayObject.isDisplayed()).to.be(true);
        });

    });

    describe("# isAppended()", function () {

        var formDisplayObject,
            submitButtonDisplayObject;

        beforeEach(function () {
            formDisplayObject = new ExtendedByDisplayObject(formTemplate);
            submitButtonDisplayObject = new ExtendedByDisplayObject(submitButtonTemplate);

            formDisplayObject.append(submitButtonDisplayObject).at("form");
        });

        it("should be false by default (=just created and not appended anywhere)", function () {
            expect(formDisplayObject.isAppended()).to.be(false);
        });

        it("should be true after appending it anywhere", function () {
            expect(submitButtonDisplayObject.isAppended()).to.be(true);
        });

        it("should be false after # destroy()", function () {
            submitButtonDisplayObject.destroy();
            expect(submitButtonDisplayObject.isAppended()).to.be(false);
        });

        it("should be false after # dispose()", function () {
            submitButtonDisplayObject.dispose();
            expect(submitButtonDisplayObject.isAppended()).to.be(false);
        });
    });
});<|endoftext|>


<commit_before>'use strict';

const logger           = require('../../util/logger'),
      promiseWhile     = require('../../util/promise').promiseWhile,
      ApiServerService = require('../services/api-server'),
      MessagesBroker   = require('../services/messages-broker'),
      tasksExecutor    = require('./tasks/executor'),
      ServerCodeModel  = require('../model');

const SESSION_TTL = 60; //60 secs
const SESSION_RENEWAL_INTERVAL = 45000; //45 secs

class DebugCodeRunner {
  constructor(opts) {
    this.options = opts;

    this.apiServer = new ApiServerService(opts.app, opts.backendless.apiServer);

    this.messageBroker = new MessagesBroker(opts.backendless.msgBroker, true);
    this.messageBroker.on('error', (err) => this.stop(err));
  }

  start() {
    logger.info('Starting Debug Code Runner...');

    return Promise.resolve()
      .then(() => this.buildModel())
      .then(() => this.messageBroker.init())
      .then(() => {
        return Promise.resolve()
          .then(() => this.registerRunner())
          .then(() => this.keepDebugSessionAlive())
          .then(() => this.registerHandlers())
          .then(() => this.registerServices())
          .then(() => this.listenTasksChannel())
          .catch(err => this.stop(err));
      });
  }

  buildModel() {
    this.model = ServerCodeModel.build(process.cwd(), this.options.app.exclude);

    if (this.model.isEmpty()) {
      throw new Error('Nothing to Debug');
    }
  }

  stop(err) {
    const stopTasks = [];

    if (!this.stopped) {
      if (err) {
        logger.error(err.message || err);
      }

      if (this.sessionRenewalTimer) {
        clearTimeout(this.sessionRenewalTimer);
      }

      if (this.debugSessionId) {
        stopTasks.push(this.apiServer.unregisterRunner());
      }

      stopTasks.push(this.messageBroker.end());

      this.stopped = true;
    }

    return Promise.all(stopTasks);
  }

  registerHandlers() {
    return this.apiServer.registerModel(this.model);
  }

  registerServices() {
    const services = this.model.services.values();

    if (services.length) {
      return this.apiServer.unregisterDebugServices()
        .then(() => this.apiServer.registerDebugServices(services));
    }
  }

  registerRunner() {
    return this.apiServer.registerRunner()
      .then(debugId => (this.debugSessionId = debugId));
  }

  keepDebugSessionAlive() {
    this.sessionRenewalTimer && clearTimeout(this.sessionRenewalTimer);

    this.sessionRenewalTimer = setTimeout(() => {
      this.messageBroker.expireKey(this.debugSessionId, SESSION_TTL, 'Debug Session ID')
        .then(() => this.keepDebugSessionAlive())
        .catch(err => {
          logger.error(err.message || err);

          if (!this.stopped) {
            logger.error('Oops.. Looks like we were disconnected. Trying to reconnect..');

            this.start();
          }
        });
    }, SESSION_RENEWAL_INTERVAL);
  }

  listenTasksChannel() {
    logger.info('Waiting for Server Code tasks..');

    const tasksQueue = this.options.app.id;
    const running = () => !this.stopped;

    promiseWhile(running, () => this.messageBroker.getTask(tasksQueue)
      .then(task => this.processTask(task))
      .catch(error => logger.error(error.message)));
  }

  processTask(task) {
    const msgBroker = this.messageBroker;

    function taskMsg(msg) {
      return `[${task.id}] ${msg}`;
    }

    function sendResult(result) {
      logger.info(taskMsg('Processing finished'));

      if (result) {
        logger.debug(taskMsg('Sending results to Redis'));

        msgBroker.setTaskResult(task, result)
          .then(() => logger.debug(taskMsg('Task results sent')));
      }
    }

    function logError(err) {
      logger.error(taskMsg(`Error during task execution. ${err.message || err}`));
    }

    logger.info(taskMsg('New task arrived!'));

    tasksExecutor.execute(task, this.options, this.model)
      .then(sendResult)
      .catch(logError);
  }
}

module.exports = function(opts) {
  return new DebugCodeRunner(opts);
};<commit_msg>fix (debug) model is empty after reconnect<commit_after>'use strict';

const logger           = require('../../util/logger'),
      promiseWhile     = require('../../util/promise').promiseWhile,
      ApiServerService = require('../services/api-server'),
      MessagesBroker   = require('../services/messages-broker'),
      tasksExecutor    = require('./tasks/executor'),
      ServerCodeModel  = require('../model');

const SESSION_TTL = 60; //60 secs
const SESSION_RENEWAL_INTERVAL = 45000; //45 secs

class DebugCodeRunner {
  constructor(opts) {
    this.options = opts;

    this.apiServer = new ApiServerService(opts.app, opts.backendless.apiServer);

    this.messageBroker = new MessagesBroker(opts.backendless.msgBroker, true);
    this.messageBroker.on('error', (err) => this.stop(err));
  }

  start() {
    logger.info('Starting Debug Code Runner...');

    return Promise.resolve()
      .then(() => this.buildModel())
      .then(() => this.messageBroker.init())
      .then(() => {
        return Promise.resolve()
          .then(() => this.registerRunner())
          .then(() => this.keepDebugSessionAlive())
          .then(() => this.registerHandlers())
          .then(() => this.registerServices())
          .then(() => this.listenTasksChannel())
          .catch(err => this.stop(err));
      });
  }

  buildModel() {
    if (!this.model) {
      this.model = ServerCodeModel.build(process.cwd(), this.options.app.exclude);

      if (this.model.isEmpty()) {
        throw new Error('Nothing to Debug');
      }
    }
  }

  stop(err) {
    const stopTasks = [];

    if (!this.stopped) {
      if (err) {
        logger.error(err.message || err);
      }

      if (this.sessionRenewalTimer) {
        clearTimeout(this.sessionRenewalTimer);
      }

      if (this.debugSessionId) {
        stopTasks.push(this.apiServer.unregisterRunner());
      }

      stopTasks.push(this.messageBroker.end());

      this.stopped = true;
    }

    return Promise.all(stopTasks);
  }

  registerHandlers() {
    return this.apiServer.registerModel(this.model);
  }

  registerServices() {
    const services = this.model.services.values();

    if (services.length) {
      return this.apiServer.unregisterDebugServices()
        .then(() => this.apiServer.registerDebugServices(services));
    }
  }

  registerRunner() {
    return this.apiServer.registerRunner()
      .then(debugId => (this.debugSessionId = debugId));
  }

  keepDebugSessionAlive() {
    this.sessionRenewalTimer && clearTimeout(this.sessionRenewalTimer);

    this.sessionRenewalTimer = setTimeout(() => {
      this.messageBroker.expireKey(this.debugSessionId, SESSION_TTL, 'Debug Session ID')
        .then(() => this.keepDebugSessionAlive())
        .catch(err => {
          logger.error(err.message || err);

          if (!this.stopped) {
            logger.error('Oops.. Looks like we were disconnected. Trying to reconnect..');

            this.start();
          }
        });
    }, SESSION_RENEWAL_INTERVAL);
  }

  listenTasksChannel() {
    logger.info('Waiting for Server Code tasks..');

    const tasksQueue = this.options.app.id;
    const running = () => !this.stopped;

    promiseWhile(running, () => this.messageBroker.getTask(tasksQueue)
      .then(task => this.processTask(task))
      .catch(error => logger.error(error.message)));
  }

  processTask(task) {
    const msgBroker = this.messageBroker;

    function taskMsg(msg) {
      return `[${task.id}] ${msg}`;
    }

    function sendResult(result) {
      logger.info(taskMsg('Processing finished'));

      if (result) {
        logger.debug(taskMsg('Sending results to Redis'));

        msgBroker.setTaskResult(task, result)
          .then(() => logger.debug(taskMsg('Task results sent')));
      }
    }

    function logError(err) {
      logger.error(taskMsg(`Error during task execution. ${err.message || err}`));
    }

    logger.info(taskMsg('New task arrived!'));

    tasksExecutor.execute(task, this.options, this.model)
      .then(sendResult)
      .catch(logError);
  }
}

module.exports = function(opts) {
  return new DebugCodeRunner(opts);
};<|endoftext|>


<commit_before>import React, { Component, PropTypes } from "react";
import { Glyphicon } from "react-bootstrap";
import classnames from "classnames";
import CSSModules from 'react-css-modules';

import DatePicker from "./components/datepicker/datepicker.js";
import Constants from "./constants/Constants.js";
import styles from './css/widget.css';

@CSSModules(styles, { allowMultiple: true })
export default class DatePicker extends Component {
  static propTypes = {
    subtractMonth: PropTypes.func.isRequired,
    viewDate: PropTypes.object.isRequired,
    viewMode: PropTypes.oneOfType([
      PropTypes.string,
      PropTypes.number
    ]),
    subtractYear: PropTypes.func.isRequired,
    subtractDecade: PropTypes.func.isRequired,
    widgetClasses: PropTypes.object,
    widgetStyle: PropTypes.object,
    showToday: PropTypes.bool,
    setViewYear: PropTypes.func.isRequired,
    setViewMonth: PropTypes.func.isRequired,
    setSelectedDate: PropTypes.func.isRequired,
    selectedDate: PropTypes.object.isRequired,
    minDate: PropTypes.object,
    maxDate: PropTypes.object,
    daysOfWeekDisabled: PropTypes.array,
    addMonth: PropTypes.func.isRequired,
    addDecade: PropTypes.func.isRequired,
    addYear: PropTypes.func.isRequired
  }

  render() {
    return (

            <DatePicker
              addDecade={this.props.addDecade}
              addMonth={this.props.addMonth}
              addYear={this.props.addYear}
              daysOfWeekDisabled={this.props.daysOfWeekDisabled}
              maxDate={this.props.maxDate}
              minDate={this.props.minDate}
              selectedDate={this.props.selectedDate}
              setSelectedDate={this.props.setSelectedDate}
              setViewMonth={this.props.setViewMonth}
              setViewYear={this.props.setViewYear}
              showToday={this.props.showToday}
              subtractDecade={this.props.subtractDecade}
              subtractMonth={this.props.subtractMonth}
              subtractYear={this.props.subtractYear}
              viewDate={this.props.viewDate}
              viewMode={this.props.viewMode}
            />

    );
  }
}
<commit_msg>removed old datepicker<commit_after><|endoftext|>


<commit_before>import React from 'react';
import classNames from 'classnames';
import { connect } from '@cerebral/react';
import { state } from 'cerebral/tags';
import Button from '../../components/Button/Button';
import flexStyles from '../../styles/modules/flex.module.scss';
import containerStyles from '../../styles/modules/container.module.scss';

const Home = ({ title }) => {
    return (

{title}

To get started, edit src/App.js and save to reload.

                    <Button label="Foo" /> is so ...

                    ... damn flexible!

    );
};

export default connect(
    {
        title: state`app.title`,
    },
    Home
);
<commit_msg>Update Home.js<commit_after>import React from 'react';
import classNames from 'classnames';
import { connect } from '@cerebral/react';
import { state } from 'cerebral/tags';
import Button from '../../components/Button/Button';
import flexStyles from '../../styles/modules/flex.module.scss';
import containerStyles from '../../styles/modules/container.module.scss';

const Home = ({ title }) => {
    return (

{title}

To get started, edit src/containers/App/App.js and save to reload.

                    <Button label="Foo" /> is so ...

                    ... damn flexible!

    );
};

export default connect(
    {
        title: state`app.title`,
    },
    Home
);
<|endoftext|>


<commit_before>function embedImage(imageSrc) {
    //This formatting is copied directly from thebombzen with slight modifications to make use of the DOM structure in HTML5

    var banner = document.createElement("DIV");
    banner.style.position = "fixed";
    banner.style.width = "100%";
    banner.style.margin = "0 0 0 -50%";
    banner.style.left = "50%";
    banner.style.visibility = "hidden";
    banner.style.textAlign = "center";
    banner.style.top = "15%";
    banner.onclick = function() {
        banner.style.visibility = "hidden";
    }

    var image = document.createElement("IMG");
    image.src = imageSrc;
    banner.appendChild(image);

    return banner;
}

function codeImagePair(combination, imageSrc) {
    var progress  = 0;
    var totalKeystrokes = combination.length;

    var image = embedImage(imageSrc);
    document.body.appendChild(image);

    var processInput = function(keyCode) {
        if(combination[progress] == keyCode) {
            progress++;
            if(progress >= totalKeystrokes) {
                image.style.visibility = "visible";
                progress = 0;
            }
        } else {
            progress = 0;
        }
    }

    var eventListener = function(e) {
        e = e || window.event;
        processInput(e.keyCode);
    }

    document.addEventListener("keydown", eventListener, false);
}

<commit_msg>added default code options to konamiCode.js to simplify use<commit_after>function embedImage(imageSrc) {
    //This formatting is copied directly from thebombzen with slight modifications to make use of the DOM structure in HTML5

    var banner = document.createElement("DIV");
    banner.style.position = "fixed";
    banner.style.width = "100%";
    banner.style.margin = "0 0 0 -50%";
    banner.style.left = "50%";
    banner.style.visibility = "hidden";
    banner.style.textAlign = "center";
    banner.style.top = "15%";
    banner.onclick = function() {
        banner.style.visibility = "hidden";
    }

    var image = document.createElement("IMG");
    image.src = imageSrc;
    banner.appendChild(image);

    return banner;
}

function codeImagePair(combination, imageSrc) {
    var progress  = 0;
    var totalKeystrokes = combination.length;

    var image = embedImage(imageSrc);
    document.body.appendChild(image);

    var processInput = function(keyCode) {
        if(combination[progress] == keyCode) {
            progress++;
            if(progress >= totalKeystrokes) {
                image.style.visibility = "visible";
                progress = 0;
            }
        } else {
            progress = 0;
        }
    }

    var eventListener = function(e) {
        e = e || window.event;
        processInput(e.keyCode);
    }

    document.addEventListener("keydown", eventListener, false);
}

var konami = [38,38,40,40,37,39,37,39,66,65];
var vvvvvv = [86,86,86,86,86,86];
<|endoftext|>


<commit_before>// Copsy, event-driven form validation for jQuery, using `$.Deferred`.
// Version 0.1
// (c) 2011 [Fred Arnoux](mailto:fred@farnoux.com)
// Released under the MIT license

(function ($) {

  //## Copsy object
  function Copsy(element, validators) {
    this.$element = $(element);
    this.validators = validators;
  }

  // Return the validator that didn't pass, `false` otherwise.
  Copsy.prototype.validate = function () {
    if ($.fn.copsy.skip(this.$element)) {
      return false;
    }

    var i, v, args, l = this.validators.length, value = this.$element.val();
    for (i = 0; i < l; i++) {
      v = this.validators[i];
      args = (v.test.length === 2) ? [this.$element, value] : [value];
      if (!v.test.apply(null, args)) {
        return v;
      }
    }
    return false;
  };

  //## Copsy jQuery plugin
  $.fn.copsy = function (options) {
    var $form = this,
        options = $.extend({}, $.fn.copsy.defaults, options);

    function getValidator(element, name) {
      // Is there validators matching this `name` ?
      var test, v = $.fn.copsy.validators[name];
      if (!v) {
        return null;
      }

      // Iterate over validators of type `name`
      $.each(v, function (selector, fn) {
        if (element.is(selector)) {
          test = fn;
          return false; // Break the loop
        }
      });

      return { name: name, test: test };
    }

    function getValidators(element) {
      var classnames = element.attr('class');
      if(classnames === undefined) {
        return null;
      }
      return $.map(classnames.split(/\s+/), function (name) {
        return getValidator(element, name) || null;
      });
    }

    // Get the Copsy object corresponding to the element
    function get(ele) {
      var c = $.data(ele, 'copsy');
      if (!c) {
        c = new Copsy(ele, getValidators(ele));
        $.data(ele, 'copsy', c);
      }
      return c;
    }

    // Validate a form input element
    function validate() {
      var element = $(this),
        // Validate element
        v = get(element).validate(),
        // Create a [Deferred object](http://api.jquery.com/category/deferred-object/) that wrap the validation result.
        promise = $.Deferred(function (dfd) {
          //* Deferred is rejected when validation fails.
          if (v) {
            dfd.reject(element, v.name);
          }
          //* Or susccessfully resolved otherwise.
          else {
            dfd.resolve(element);
          }
        // Finally the [Promise object](http://api.jquery.com/deferred.promise/) of the Deferred is returned.
        }).promise();

      // Add validation handlers to Promise object
      $.each($.fn.copsy.handlers, function () {
        this(promise);
      });

      return !v;
    }

    // When form is submitted, validate all its elements.
    function submit() {
      var valid = true;
      for(var i = 0, l = options.trigger.length; i < l; i += 2) {
        $form.find(options.trigger[i]).each(function () {
          valid = validate.apply(this) && valid;
        });
      }
      return valid;
    }

    for(var i = 0, l = options.trigger.length; i < l; i += 2) {
      // Bind events that trigger validation.
      this.find(options.trigger[i]).bind(options.trigger[i+1], validate);
    }

    // Bind form submit
    $form.submit(submit);

    return this;
  };

  $.fn.copsy.skip = function (element) {
    if (element.is(':hidden')) {
      return true;
    }
  };

  //### Default configuration
  $.fn.copsy.defaults = {
    // Different selectors and their corresponding trigger events.
    trigger: [
      ':radio', 'change',
      ':input:not(:radio)', 'blur change keyup'
    ]
  }

  // Array of available validator objects.
  $.fn.copsy.validators = {};
  // Array of validation handlers.
  $.fn.copsy.handlers = [];

  // Handy helper function to easily register new validators.
  // `id` is the unique id
  // `selector` is a CSS selector
  $.fn.copsy.addValidator = function (id, selector, fn) {
    var v = $.fn.copsy.validators[id];
    if (!v) {
      $.fn.copsy.validators[id] = v = {};
    }
    v[selector] = fn;
  };

  // Handy helper function to add new validation handlers.
  // `fn` argument is a handler function that should accept a Promise object as unique argument.
  $.fn.copsy.addHandler = function (fn) {
    if ($.isFunction(fn) && fn.length === 1) {
      $.fn.copsy.handlers.push(fn);
    }
  };

})(jQuery);

//
//## Configuration
//
(function ($) {
  //
  //### Define validators
  //
  $.fn.copsy.addValidator("mandatory", "input.mandatory", function (value) {
    return value && value.length > 0;
  });

  $.fn.copsy.addValidator("numeric", "input.numeric", function (value) {
    return value.length < 1 || /^\d+$/i.test(value);
  });

  $.fn.copsy.addValidator("email", "input.email", function (value) {
    return value.length < 1 || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test(value);
  });

  //
  //### Define validation messages
  //
  $.fn.copsy.message = {
    mandatory : "Please, specify",
    email : "Please, enter a valid email",
    numeric : "Please, enter only numeric values (0-9)"
  };

})(jQuery);<commit_msg>Remove `:submit` from the default eligible inputs<commit_after>// Copsy, event-driven form validation for jQuery, using `$.Deferred`.
// Version 0.1
// (c) 2011 [Fred Arnoux](mailto:fred@farnoux.com)
// Released under the MIT license

(function ($) {

  //## Copsy object
  function Copsy(element, validators) {
    this.$element = $(element);
    this.validators = validators;
  }

  // Return the validator that didn't pass, `false` otherwise.
  Copsy.prototype.validate = function () {
    if ($.fn.copsy.skip(this.$element)) {
      return false;
    }

    var i, v, args, l = this.validators.length, value = this.$element.val();
    for (i = 0; i < l; i++) {
      v = this.validators[i];
      args = (v.test.length === 2) ? [this.$element, value] : [value];
      if (!v.test.apply(null, args)) {
        return v;
      }
    }
    return false;
  };

  //## Copsy jQuery plugin
  $.fn.copsy = function (options) {
    var $form = this,
        options = $.extend({}, $.fn.copsy.defaults, options);

    function getValidator(element, name) {
      // Is there validators matching this `name` ?
      var test, v = $.fn.copsy.validators[name];
      if (!v) {
        return null;
      }

      // Iterate over validators of type `name`
      $.each(v, function (selector, fn) {
        if (element.is(selector)) {
          test = fn;
          return false; // Break the loop
        }
      });

      return { name: name, test: test };
    }

    function getValidators(element) {
      var classnames = element.attr('class');
      if(classnames === undefined) {
        return null;
      }
      return $.map(classnames.split(/\s+/), function (name) {
        return getValidator(element, name) || null;
      });
    }

    // Get the Copsy object corresponding to the element
    function get(ele) {
      var c = $.data(ele, 'copsy');
      if (!c) {
        c = new Copsy(ele, getValidators(ele));
        $.data(ele, 'copsy', c);
      }
      return c;
    }

    // Validate a form input element
    function validate() {
      var element = $(this),
        // Validate element
        v = get(element).validate(),
        // Create a [Deferred object](http://api.jquery.com/category/deferred-object/) that wrap the validation result.
        promise = $.Deferred(function (dfd) {
          //* Deferred is rejected when validation fails.
          if (v) {
            dfd.reject(element, v.name);
          }
          //* Or susccessfully resolved otherwise.
          else {
            dfd.resolve(element);
          }
        // Finally the [Promise object](http://api.jquery.com/deferred.promise/) of the Deferred is returned.
        }).promise();

      // Add validation handlers to Promise object
      $.each($.fn.copsy.handlers, function () {
        this(promise);
      });

      return !v;
    }

    // When form is submitted, validate all its elements.
    function submit() {
      var valid = true;
      for(var i = 0, l = options.trigger.length; i < l; i += 2) {
        $form.find(options.trigger[i]).each(function () {
          valid = validate.apply(this) && valid;
        });
      }
      return valid;
    }

    for(var i = 0, l = options.trigger.length; i < l; i += 2) {
      // Bind events that trigger validation.
      this.find(options.trigger[i]).bind(options.trigger[i+1], validate);
    }

    // Bind form submit
    $form.submit(submit);

    return this;
  };

  $.fn.copsy.skip = function (element) {
    if (element.is(':hidden')) {
      return true;
    }
  };

  //### Default configuration
  $.fn.copsy.defaults = {
    // Different selectors and their corresponding trigger events.
    trigger: [
      ':radio', 'change',
      ':input:not(:radio):not(:submit)', 'blur change keyup'
    ]
  }

  // Array of available validator objects.
  $.fn.copsy.validators = {};
  // Array of validation handlers.
  $.fn.copsy.handlers = [];

  // Handy helper function to easily register new validators.
  // `id` is the unique id
  // `selector` is a CSS selector
  $.fn.copsy.addValidator = function (id, selector, fn) {
    var v = $.fn.copsy.validators[id];
    if (!v) {
      $.fn.copsy.validators[id] = v = {};
    }
    v[selector] = fn;
  };

  // Handy helper function to add new validation handlers.
  // `fn` argument is a handler function that should accept a Promise object as unique argument.
  $.fn.copsy.addHandler = function (fn) {
    if ($.isFunction(fn) && fn.length === 1) {
      $.fn.copsy.handlers.push(fn);
    }
  };

})(jQuery);

//
//## Configuration
//
(function ($) {
  //
  //### Define validators
  //
  $.fn.copsy.addValidator("mandatory", "input.mandatory", function (value) {
    return value && value.length > 0;
  });

  $.fn.copsy.addValidator("numeric", "input.numeric", function (value) {
    return value.length < 1 || /^\d+$/i.test(value);
  });

  $.fn.copsy.addValidator("email", "input.email", function (value) {
    return value.length < 1 || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test(value);
  });

  //
  //### Define validation messages
  //
  $.fn.copsy.message = {
    mandatory : "Please, specify",
    email : "Please, enter a valid email",
    numeric : "Please, enter only numeric values (0-9)"
  };

})(jQuery);<|endoftext|>


<commit_before>describe("Bootbox", function() {

  "use strict";

  it("is attached to the window object", function() {
    expect(window.bootbox).to.be.an("object");
  });

  it("exposes the correct public API", function() {
    expect(bootbox.alert).to.be.a("function");
    expect(bootbox.confirm).to.be.a("function");
    expect(bootbox.dialog).to.be.a("function");
    expect(bootbox.setDefaults).to.be.a("function");
    expect(bootbox.hideAll).to.be.a("function");
  });

  describe("hideAll", function() {
    beforeEach(function() {
      this.hidden = sinon.spy($.fn, "modal");
      bootbox.hideAll();
    });

    it("should hide all .bootbox modals", function() {
      expect(this.hidden).to.have.been.calledWithExactly("hide");
    });
  });

  describe("event listeners", function() {
    describe("hidden.bs.modal", function() {
      beforeEach(function() {
        this.dialog = bootbox.alert("hi");

        this.removed = sinon.stub(this.dialog, "remove");

        this.e = function(target) {

          $(this.dialog).trigger($.Event("hidden.bs.modal", {
            target: target
          }));
        };
      });

      afterEach(function() {
        this.removed.restore();
      });

      describe("when triggered with the wrong target", function() {
        beforeEach(function() {
          this.e({an: "object"});
        });

        it("does not remove the dialog", function() {
          expect(this.removed).not.to.have.been.called;
        });
      });

      describe("when triggered with the correct target", function() {
        beforeEach(function() {
          this.e(this.dialog.get(0));
        });

        it("removes the dialog", function() {
          expect(this.removed).to.have.been.called;
        });
      });
    });
  });

  describe("If $.fn.modal is undefined", function() {
    beforeEach(function() {
      this.oldModal = window.jQuery.fn.modal;
      window.jQuery.fn.modal = undefined;
    });

    afterEach(function() {
      window.jQuery.fn.modal = this.oldModal;
    });

    describe("When invoking a dialog", function() {
      beforeEach(function() {
        try {
          bootbox.alert("Hi", function() {});
        } catch (e) {
          this.e = e;
        }
      });

      it("throws the correct error", function() {
        expect(this.e.message).to.contain("$.fn.modal is not defined");
      });
    });
  });

  describe("adding and removing locales", function() {

    describe("bootbox.addLocale", function() {
      describe("with invalid values", function() {
        beforeEach(function() {
          try {
            bootbox.addLocale("xy", {
              OK: "BTN1"
            });
          } catch (e) {
            this.e = e;
          }
        });

        it("throws the expected error", function() {
          expect(this.e.message).to.equal("Please supply a translation for 'CANCEL'");
        });
      });

      describe("with invalid values", function() {
        beforeEach(function() {
          bootbox
          .addLocale("xy", {
            OK: "BTN1",
            CANCEL: "BTN2",
            CONFIRM: "BTN3"
          })
          .setLocale("xy");

          var d1 = bootbox.alert("foo");
          var d2 = bootbox.confirm("foo", function() { return true; });
          this.labels = {
            ok: d1.find(".btn:first").text(),
            cancel: d2.find(".btn:first").text(),
            confirm: d2.find(".btn:last").text()
          };
        });

        it("shows the expected OK translation", function() {
          expect(this.labels.ok).to.equal("BTN1");
        });
        it("shows the expected CANCEL translation", function() {
          expect(this.labels.cancel).to.equal("BTN2");
        });
        it("shows the expected PROMPT translation", function() {
          expect(this.labels.confirm).to.equal("BTN3");
        });
      });
    });

    describe("bootbox.removeLocale", function () {
      beforeEach(function () {
        bootbox.removeLocale("xy");

        var d1 = bootbox.alert("foo");
        var d2 = bootbox.confirm("foo", function () { return true; });
        this.labels = {
          ok: d1.find(".btn:first").text(),
          cancel: d2.find(".btn:first").text(),
          confirm: d2.find(".btn:last").text()
        };
      });

      it("falls back to the default OK translation", function () {
        expect(this.labels.ok).to.equal("OK");
      });
      it("falls back to the default CANCEL translation", function () {
        expect(this.labels.cancel).to.equal("Cancel");
      });
      it("falls back to the default PROMPT translation", function () {
        expect(this.labels.confirm).to.equal("OK");
      });
    });
  });

  describe("backdrop variations", function() {
    beforeEach(function() {
      this.e = function(target) {
        $(this.dialog).trigger($.Event("click.dismiss.bs.modal", {
          target: target
        }));
      };
    });

    describe("with the default value", function() {
      beforeEach(function() {
        this.callback = sinon.spy();
        this.dialog = bootbox.alert("hi", this.callback);
      });

      describe("When triggering the backdrop click dismiss event", function() {
        beforeEach(function() {
          this.e({an: "object"});
        });

        it("does not invoke the callback", function() {
          expect(this.callback).not.to.have.been.called;
        });
      });
    });

    describe("when set to false", function() {
      beforeEach(function() {
        this.callback = sinon.spy();
        this.dialog = bootbox.alert({
          message: "hi",
          callback: this.callback,
          backdrop: false
        });
      });

      describe("When triggering the backdrop click dismiss event", function() {
        describe("With the wrong target", function() {
          beforeEach(function() {
            this.e({an: "object"});
          });

          it("does not invoke the callback", function() {
            expect(this.callback).not.to.have.been.called;
          });
        });

        describe("With the correct target", function() {
          beforeEach(function() {
            this.e(this.dialog.get(0));
          });

          it("invokes the callback", function() {
            expect(this.callback).to.have.been.called;
          });

          it("should pass the dialog as `this`", function() {
            expect(this.callback.thisValues[0]).to.equal(this.dialog);
          });
        });
      });
    });

    describe("when set to true", function() {
      beforeEach(function() {
        this.callback = sinon.spy();
        this.dialog = bootbox.alert({
          message: "hi",
          callback: this.callback,
          backdrop: true
        });
      });

      describe("When triggering the backdrop click dismiss event", function() {
        describe("With the wrong target", function() {
          beforeEach(function() {
            this.e({an: "object"});
          });

          it("does not invoke the callback", function() {
            expect(this.callback).not.to.have.been.called;
          });
        });

        describe("With the correct target", function() {
          beforeEach(function() {
            this.e(this.dialog.children(".modal-backdrop").get(0));
          });

          it("invokes the callback", function() {
            expect(this.callback).to.have.been.called;
          });

          it("should pass the dialog as `this`", function() {
            expect(this.callback.thisValues[0]).to.equal(this.dialog);
          });
        });
      });
    });
  });
});
<commit_msg>stop spy hanging around after initial use<commit_after>describe("Bootbox", function() {

  "use strict";

  it("is attached to the window object", function() {
    expect(window.bootbox).to.be.an("object");
  });

  it("exposes the correct public API", function() {
    expect(bootbox.alert).to.be.a("function");
    expect(bootbox.confirm).to.be.a("function");
    expect(bootbox.dialog).to.be.a("function");
    expect(bootbox.setDefaults).to.be.a("function");
    expect(bootbox.hideAll).to.be.a("function");
  });

  describe("hideAll", function() {
    beforeEach(function() {
      this.hidden = sinon.spy($.fn, "modal");
      bootbox.hideAll();
    });

    afterEach(function() {
      this.hidden.restore();
    });

    it("should hide all .bootbox modals", function() {
      expect(this.hidden).to.have.been.calledWithExactly("hide");
    });
  });

  describe("event listeners", function() {
    describe("hidden.bs.modal", function() {
      beforeEach(function() {
        this.dialog = bootbox.alert("hi");

        this.removed = sinon.stub(this.dialog, "remove");

        this.e = function(target) {

          $(this.dialog).trigger($.Event("hidden.bs.modal", {
            target: target
          }));
        };
      });

      afterEach(function() {
        this.removed.restore();
      });

      describe("when triggered with the wrong target", function() {
        beforeEach(function() {
          this.e({an: "object"});
        });

        it("does not remove the dialog", function() {
          expect(this.removed).not.to.have.been.called;
        });
      });

      describe("when triggered with the correct target", function() {
        beforeEach(function() {
          this.e(this.dialog.get(0));
        });

        it("removes the dialog", function() {
          expect(this.removed).to.have.been.called;
        });
      });
    });
  });

  describe("If $.fn.modal is undefined", function() {
    beforeEach(function() {
      this.oldModal = window.jQuery.fn.modal;
      window.jQuery.fn.modal = undefined;
    });

    afterEach(function() {
      window.jQuery.fn.modal = this.oldModal;
    });

    describe("When invoking a dialog", function() {
      beforeEach(function() {
        try {
          bootbox.alert("Hi", function() {});
        } catch (e) {
          this.e = e;
        }
      });

      it("throws the correct error", function() {
        expect(this.e.message).to.contain("$.fn.modal is not defined");
      });
    });
  });

  describe("adding and removing locales", function() {

    describe("bootbox.addLocale", function() {
      describe("with invalid values", function() {
        beforeEach(function() {
          try {
            bootbox.addLocale("xy", {
              OK: "BTN1"
            });
          } catch (e) {
            this.e = e;
          }
        });

        it("throws the expected error", function() {
          expect(this.e.message).to.equal("Please supply a translation for 'CANCEL'");
        });
      });

      describe("with invalid values", function() {
        beforeEach(function() {
          bootbox
          .addLocale("xy", {
            OK: "BTN1",
            CANCEL: "BTN2",
            CONFIRM: "BTN3"
          })
          .setLocale("xy");

          var d1 = bootbox.alert("foo");
          var d2 = bootbox.confirm("foo", function() { return true; });
          this.labels = {
            ok: d1.find(".btn:first").text(),
            cancel: d2.find(".btn:first").text(),
            confirm: d2.find(".btn:last").text()
          };
        });

        it("shows the expected OK translation", function() {
          expect(this.labels.ok).to.equal("BTN1");
        });
        it("shows the expected CANCEL translation", function() {
          expect(this.labels.cancel).to.equal("BTN2");
        });
        it("shows the expected PROMPT translation", function() {
          expect(this.labels.confirm).to.equal("BTN3");
        });
      });
    });

    describe("bootbox.removeLocale", function () {
      beforeEach(function () {
        bootbox.removeLocale("xy");

        var d1 = bootbox.alert("foo");
        var d2 = bootbox.confirm("foo", function () { return true; });
        this.labels = {
          ok: d1.find(".btn:first").text(),
          cancel: d2.find(".btn:first").text(),
          confirm: d2.find(".btn:last").text()
        };
      });

      it("falls back to the default OK translation", function () {
        expect(this.labels.ok).to.equal("OK");
      });
      it("falls back to the default CANCEL translation", function () {
        expect(this.labels.cancel).to.equal("Cancel");
      });
      it("falls back to the default PROMPT translation", function () {
        expect(this.labels.confirm).to.equal("OK");
      });
    });
  });

  describe("backdrop variations", function() {
    beforeEach(function() {
      this.e = function(target) {
        $(this.dialog).trigger($.Event("click.dismiss.bs.modal", {
          target: target
        }));
      };
    });

    describe("with the default value", function() {
      beforeEach(function() {
        this.callback = sinon.spy();
        this.dialog = bootbox.alert("hi", this.callback);
      });

      describe("When triggering the backdrop click dismiss event", function() {
        beforeEach(function() {
          this.e({an: "object"});
        });

        it("does not invoke the callback", function() {
          expect(this.callback).not.to.have.been.called;
        });
      });
    });

    describe("when set to false", function() {
      beforeEach(function() {
        this.callback = sinon.spy();
        this.dialog = bootbox.alert({
          message: "hi",
          callback: this.callback,
          backdrop: false
        });
      });

      describe("When triggering the backdrop click dismiss event", function() {
        describe("With the wrong target", function() {
          beforeEach(function() {
            this.e({an: "object"});
          });

          it("does not invoke the callback", function() {
            expect(this.callback).not.to.have.been.called;
          });
        });

        describe("With the correct target", function() {
          beforeEach(function() {
            this.e(this.dialog.get(0));
          });

          it("invokes the callback", function() {
            expect(this.callback).to.have.been.called;
          });

          it("should pass the dialog as `this`", function() {
            expect(this.callback.thisValues[0]).to.equal(this.dialog);
          });
        });
      });
    });

    describe("when set to true", function() {
      beforeEach(function() {
        this.callback = sinon.spy();
        this.dialog = bootbox.alert({
          message: "hi",
          callback: this.callback,
          backdrop: true
        });
      });

      describe("When triggering the backdrop click dismiss event", function() {
        describe("With the wrong target", function() {
          beforeEach(function() {
            this.e({an: "object"});
          });

          it("does not invoke the callback", function() {
            expect(this.callback).not.to.have.been.called;
          });
        });

        describe("With the correct target", function() {
          beforeEach(function() {
            this.e(this.dialog.children(".modal-backdrop").get(0));
          });

          it("invokes the callback", function() {
            expect(this.callback).to.have.been.called;
          });

          it("should pass the dialog as `this`", function() {
            expect(this.callback.thisValues[0]).to.equal(this.dialog);
          });
        });
      });
    });
  });
});
<|endoftext|>


<commit_before>$(document).ready(function(){
	$.tablesorter.addParser({
		id: 'Level',
		is: function(s) {
			return false;
		},
		format: function(s) {
			return level_order.indexOf(s);
		},
		type: 'numeric'
	});
	$("#myTable").tablesorter({
		headers: {
			0: {sorter:'Level'}
		},
		textSorter: {
			1: $.tablesorter.sortText
		},
		sortAppend: [[0,0],[1,0]],
		sortList: [[0,0],[1,0]]
	});

	$("#myTable").tablesorter();
	$("#loading").hide();
	$("#loaded").show();
});

function resetFilterResult(){
	$(".song-tr").show();

	var min_lv = $('.min-lv').prop('selectedIndex');
	var max_lv = $('.max-lv').prop('selectedIndex');
	$(".song-tr").each(function() {
		var lv = parseInt($(this).attr('hidden-level'));
		if( lv < min_lv || lv > max_lv) {
			$(this).closest("tr").hide();
		}
	});

	$('.RANK:checkbox:not(:checked)').each(function() {
		var rank = $(this).attr('value');
		if(rank === "C-F"){
			$(".player.td-CF").closest("tr").hide();
		} else{
			$(".player.td-".concat(rank)).closest("tr").hide();
		}
	});

	$('.CLEAR:checkbox:not(:checked)').each(function() {
		var clear = $(this).attr('value');
		if(clear === "FULLCOMBO")$(".player.td-FC").closest("tr").hide();
		else if(clear === "HARD")$(".player.td-HC").closest("tr").hide();
		else if(clear === "NORMAL")$(".player.td-CL").closest("tr").hide();
		else if(clear === "EASY")$(".player.td-EC").closest("tr").hide();
		else if(clear === "FAILED")$(".player.td-FA").closest("tr").hide();
		else if(clear === "NOPLAY")$(".player.td-NO").closest("tr").hide();
	});

}

function setPopupPositionAndHeight(){
	$('.popup').height('auto');
	var h=$('.popup')[0].scrollHeight+2;
	var window_h=$(window).height();
	var min_h=Math.min(h,window_h);

	$('.popup').outerHeight(min_h);
	$('.popup').css('margin-top','-'+(min_h/2)+'px');
}

var toggled=false;
var toggledHash='';
$('.td-playedN').mouseenter(function(){
	if(!toggled){
		var hash = $(this).attr('hash');
		var level=$(this).siblings('.td-level').text();
		var title=$(this).siblings('.td-title').children('a').text();

		$('.popup-content').html('Loading...');
		setPopupPositionAndHeight();

		$('.popup').css('visibility', 'visible');
		$.ajax({
			url: '/~lavalse/LR2IR/search2.cgi',
			type: "get",
			data: {"difficultytablehash":hash,"level":level,"title":title},
			success: function(data){
				$('.popup-content').html(data);
				setPopupPositionAndHeight();
		}});
	}
});
$('.td-playedN').mouseleave(function(){
	if (!toggled)
		$('.popup').css('visibility', 'hidden');
});

$('.td-playedN').click(function(){
	var hash=$(this).attr('hash');
	if(!toggled){
		$(this).addClass('td-toggled');
		toggledHash=hash;
		toggled=true;
	}
	else{
		if(toggledHash===hash){
			$(this).removeClass('td-toggled');
			toggled=false;
		}
		else{
			$('.td-playedN[hash="'+toggledHash+'"]').removeClass('td-toggled');
			$(this).addClass('td-toggled');
			toggledHash=hash;

			var level=$(this).siblings('.td-level').text();
			var title=$(this).siblings('.td-title').children('a').text();

			$('.popup-content').html('Loading...');
			setPopupPositionAndHeight();

			$.ajax({
				url: '/~lavalse/LR2IR/search2.cgi',
				type: "get",
				data: {"difficultytablehash":hash,"level":level,"title":title},
				success: function(data){
					$('.popup-content').html(data);
					setPopupPositionAndHeight();
			}});
		}
	}
});
$(document).keyup(function(e) {
	if (toggled && e.keyCode === 27){
		$('.td-playedN[hash="'+toggledHash+'"]').removeClass('td-toggled');
		toggled=false;
		$('.popup').css('visibility', 'hidden');
	}
});

$('.ESC-button').click(function(){
	if (toggled){
		$('.td-playedN[hash="'+toggledHash+'"]').removeClass('td-toggled');
		toggled=false;
		$('.popup').css('visibility', 'hidden');
	}
});

var waitForFinalEvent = (function () {
	var timers = {};
	return function (callback, ms, uniqueId) {
		if (!uniqueId) {
			uniqueId = "Don't call this twice without a uniqueId";
		}
		if (timers[uniqueId]) {
			clearTimeout (timers[uniqueId]);
		}
		timers[uniqueId] = setTimeout(callback, ms);
	};
})();

$(window).resize(function () {
	waitForFinalEvent(function(){
		setPopupPositionAndHeight()
	}, 500, "unique-string");
});<commit_msg>Add webpage ajax failed handler<commit_after>$(document).ready(function(){
	$.tablesorter.addParser({
		id: 'Level',
		is: function(s) {
			return false;
		},
		format: function(s) {
			return level_order.indexOf(s);
		},
		type: 'numeric'
	});
	$("#myTable").tablesorter({
		headers: {
			0: {sorter:'Level'}
		},
		textSorter: {
			1: $.tablesorter.sortText
		},
		sortAppend: [[0,0],[1,0]],
		sortList: [[0,0],[1,0]]
	});

	$("#myTable").tablesorter();
	$("#loading").hide();
	$("#loaded").show();
});

function resetFilterResult(){
	$(".song-tr").show();

	var min_lv = $('.min-lv').prop('selectedIndex');
	var max_lv = $('.max-lv').prop('selectedIndex');
	$(".song-tr").each(function() {
		var lv = parseInt($(this).attr('hidden-level'));
		if( lv < min_lv || lv > max_lv) {
			$(this).closest("tr").hide();
		}
	});

	$('.RANK:checkbox:not(:checked)').each(function() {
		var rank = $(this).attr('value');
		if(rank === "C-F"){
			$(".player.td-CF").closest("tr").hide();
		} else{
			$(".player.td-".concat(rank)).closest("tr").hide();
		}
	});

	$('.CLEAR:checkbox:not(:checked)').each(function() {
		var clear = $(this).attr('value');
		if(clear === "FULLCOMBO")$(".player.td-FC").closest("tr").hide();
		else if(clear === "HARD")$(".player.td-HC").closest("tr").hide();
		else if(clear === "NORMAL")$(".player.td-CL").closest("tr").hide();
		else if(clear === "EASY")$(".player.td-EC").closest("tr").hide();
		else if(clear === "FAILED")$(".player.td-FA").closest("tr").hide();
		else if(clear === "NOPLAY")$(".player.td-NO").closest("tr").hide();
	});

}

function setPopupPositionAndHeight(){
	$('.popup').height('auto');
	var h=$('.popup')[0].scrollHeight+2;
	var window_h=$(window).height();
	var min_h=Math.min(h,window_h);

	$('.popup').outerHeight(min_h);
	$('.popup').css('margin-top','-'+(min_h/2)+'px');
}

var toggled=false;
var toggledHash='';
$('.td-playedN').mouseenter(function(){
	if(!toggled){
		var hash = $(this).attr('hash');
		var level=$(this).siblings('.td-level').text();
		var title=$(this).siblings('.td-title').children('a').text();

		$('.popup-content').html('Loading...');
		setPopupPositionAndHeight();

		$('.popup').css('visibility', 'visible');
		$.ajax({
				url: '/~lavalse/LR2IR/search2.cgi',
				type: "get",
				data: {"difficultytablehash":hash,"level":level,"title":title}
			})
			.done(function(data){
				$('.popup-content').html(data);
				setPopupPositionAndHeight();
			})
			.fail(function(){
					$('.popup-content').html('Failed to load data.');
			})
		;
	}
});
$('.td-playedN').mouseleave(function(){
	if (!toggled)
		$('.popup').css('visibility', 'hidden');
});

$('.td-playedN').click(function(){
	var hash=$(this).attr('hash');
	if(!toggled){
		$(this).addClass('td-toggled');
		toggledHash=hash;
		toggled=true;
	}
	else{
		if(toggledHash===hash){
			$(this).removeClass('td-toggled');
			toggled=false;
		}
		else{
			$('.td-playedN[hash="'+toggledHash+'"]').removeClass('td-toggled');
			$(this).addClass('td-toggled');
			toggledHash=hash;

			var level=$(this).siblings('.td-level').text();
			var title=$(this).siblings('.td-title').children('a').text();

			$('.popup-content').html('Loading...');
			setPopupPositionAndHeight();

			$.ajax({
					url: '/~lavalse/LR2IR/search2.cgi',
					type: "get",
					data: {"difficultytablehash":hash,"level":level,"title":title}
				})
				.done(function(data){
					$('.popup-content').html(data);
					setPopupPositionAndHeight();
				})
				.fail(function(){
						$('.popup-content').html('Failed to load data.');
				})
			;
		}
	}
});
$(document).keyup(function(e) {
	if (toggled && e.keyCode === 27){
		$('.td-playedN[hash="'+toggledHash+'"]').removeClass('td-toggled');
		toggled=false;
		$('.popup').css('visibility', 'hidden');
	}
});

$('.ESC-button').click(function(){
	if (toggled){
		$('.td-playedN[hash="'+toggledHash+'"]').removeClass('td-toggled');
		toggled=false;
		$('.popup').css('visibility', 'hidden');
	}
});

var waitForFinalEvent = (function () {
	var timers = {};
	return function (callback, ms, uniqueId) {
		if (!uniqueId) {
			uniqueId = "Don't call this twice without a uniqueId";
		}
		if (timers[uniqueId]) {
			clearTimeout (timers[uniqueId]);
		}
		timers[uniqueId] = setTimeout(callback, ms);
	};
})();

$(window).resize(function () {
	waitForFinalEvent(function(){
		setPopupPositionAndHeight()
	}, 500, "unique-string");
});<|endoftext|>


<commit_before>import _ from 'lodash';

const isRootLocaleComment =
  reply => (reply.depth === 1 && reply.body.length === 4 && reply.body.substring(0, 2) === '# ');

export const toObject = (body) => {
  const object = {};
  const lines = body.split(/\n/);
  lines.forEach((line) => {
    const message = line.split(':');
    if (message.length === 2) {
      object[message[0].trim()] = message[1].trim();
    }
  });
  return object;
};

export const getMessages = (replies) => {
  const localesMap = {};
  const messages = {};
  const sortedReplies = _.sortBy(replies, 'net_rshares');

  Object.keys(sortedReplies).forEach((key) => {
    const reply = sortedReplies[key];
    if (isRootLocaleComment(reply)) {
      localesMap[reply.permlink] = reply.body.replace('#', '').replace(' ', '').toLowerCase();
      messages[localesMap[reply.permlink]] = {};
    }
  });

  Object.keys(sortedReplies).forEach((key) => {
    const reply = sortedReplies[key];
    const locale = localesMap[reply.parent_permlink];
    if (locale) {
      const object = toObject(reply.body);
      messages[locale] = Object.assign(messages[locale], object);
    }
  });

  return messages;
};

export const getLocale = (appLocale, messages) => {
  const browserLocale = navigator.language || navigator.userLanguage; // eslint-disable-line
  let locale = appLocale || browserLocale;
  locale = locale.substr(0, 2);
  locale = messages[locale] ? locale : 'en';
  return locale;
};
<commit_msg>Allow translation that include ':' character<commit_after>import _ from 'lodash';

const isRootLocaleComment =
  reply => (reply.depth === 1 && reply.body.length === 4 && reply.body.substring(0, 2) === '# ');

export const toObject = (body) => {
  const object = {};
  const lines = body.split(/\n/);
  lines.forEach((line) => {
    const separatorPosition = line.indexOf(':');
    const key = separatorPosition > 0 ? line.slice(0, separatorPosition) : '';
    const value = separatorPosition > 0 ? line.slice(separatorPosition + 1) : '';
    if (key && value) {
      object[key.trim()] = value.trim();
    }
  });
  return object;
};

export const getMessages = (replies) => {
  const localesMap = {};
  const messages = {};
  const sortedReplies = _.sortBy(replies, 'net_rshares');

  Object.keys(sortedReplies).forEach((key) => {
    const reply = sortedReplies[key];
    if (isRootLocaleComment(reply)) {
      localesMap[reply.permlink] = reply.body.replace('#', '').replace(' ', '').toLowerCase();
      messages[localesMap[reply.permlink]] = {};
    }
  });

  Object.keys(sortedReplies).forEach((key) => {
    const reply = sortedReplies[key];
    const locale = localesMap[reply.parent_permlink];
    if (locale) {
      const object = toObject(reply.body);
      messages[locale] = Object.assign(messages[locale], object);
    }
  });

  return messages;
};

export const getLocale = (appLocale, messages) => {
  const browserLocale = navigator.language || navigator.userLanguage; // eslint-disable-line
  let locale = appLocale || browserLocale;
  locale = locale.substr(0, 2);
  locale = messages[locale] ? locale : 'en';
  return locale;
};
<|endoftext|>