<commit_before>function pageViewModel(gvm) {
    // Page specific i18n bindings
    gvm.title = ko.computed(function(){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n.__("AdminPage");}, gvm);
    gvm.pageHeaderEditUser = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("UserEditTitle");}, gvm);

    gvm.edituserid = $("#usereditHeader").data('value');

    gvm.userName = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("UserName");}, gvm);
    gvm.firstName = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("Firstname");}, gvm);
    gvm.lastName = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("Lastname");}, gvm);
    gvm.userStatus = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("UserStatus");}, gvm);

    gvm.permissionRole = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("PermissionRole");}, gvm);
    gvm.permissionDescription = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("PermissionDescription");}, gvm);

    gvm.rights = ko.observableArray([]);
    gvm.allRights = ko.observableArray([]);
    gvm.checkedRights = ko.observableArray([]);
    gvm.user = ko.observableArray([]);

    gvm.updateUser = function(user)
    {
        gvm.user.push(user);
    },

    gvm.updatePermissions = function(permission)
    {
        gvm.rights.push(permission);
    },

    gvm.updateAllPermissions = function(permission)
    {
        gvm.allRights.push(permission);
    },

    gvm.removeUser = function(user) {
        gvm.user.remove(user);
        removeUser(user);
    },

    gvm.clearStructure = function() {
        gvm.rights.destroyAll();
        gvm.user.destroyAll();
    }

    gvm.updateCheckedRights = function(item){
        gvm.checkedRights.push(item);
    }
}

function initPage() {
    getAllUserDataById(viewModel.edituserid);
    setRights();

    $('#userEditForm').on('submit', function(e)
    {
        e.preventDefault();

        saveChanges();
        saveUserPermissions();

        window.location.href = "/admin/permissions/edit/" + viewModel.edituserid;
    });
}

function saveChanges(){
    console.log("Save changes");
    console.log("userid: " + viewModel.edituserid);

    saveUserEdits(viewModel.edituserid);
    saveUserPermissions();
}

function saveUserEdits(id){
    $.ajax({
        type: "POST",
        url: "/api/saveedit/" + id,
        data: $('#userEditForm').serialize(),
        success: function() {
            console.log('Success saved user changes');
        },
        error: function() {
            console.log("Error saving user changes");
        }
    });
}

function saveUserPermissions(){
    console.log("Save user permissions for user: " + viewModel.edituserid);
    //FIRST DELETE ALL PERMISSIONS
    $.getJSON("/api/removeroles/" + viewModel.edituserid, function(){
        console.log("User permissions were removed");
    });

    $.each(viewModel.allRights(), function(i, currentRights){

        var checkedValue = document.getElementsByName(currentRights);

        console.log(checkedValue[0].checked + " - " + currentRights);

        //SAVE NEW PERMISSIONS
        if(checkedValue[0].checked == true) {
            $.ajax({
                type: "POST",
                url: "/api/addrole/" + viewModel.edituserid,
                data: { 'currentRight': currentRights },
                success: function() {
                    console.log('Success saved user permission: ' + currentRights);
                },
                error: function() {
                    console.log('Error saving user permission: ' + currentRights);
                }
            });
        }
    });

}

function setRights(){
    viewModel.updateAllPermissions("GUEST");
    viewModel.updateAllPermissions("STUDENT");
    viewModel.updateAllPermissions("USER");
    viewModel.updateAllPermissions("SUPERUSER");
}

function getAllUserDataById(edituserid){
    console.log("Get data from user with id " + edituserid);
    $.getJSON("/api/edituser/" + edituserid, function(data)
    {
        var addedUsername = "";
        $.each(data, function(i, item){
            var current = item.username;

            $.each(data, function(i, item)
            {
                if(item.username == current && addedUsername != current){
                    console.log(current + " " + item.role);
                    viewModel.updatePermissions(item.role)
                }
            });

            if (addedUsername != current) {
                addedUsername = current;
                console.log("Added: " + addedUsername);
                viewModel.updateUser(new User(item.userid, item.username, item.firstname, item.lastname, item.status, viewModel.rights()));
            }
        });

        checkPermissions();
    });
}

function checkPermissions(){
    var checked = false;
    $.each(viewModel.allRights(), function(i, itemAllRights){
        checked = false;
        var data = [];
        $.each(viewModel.rights(), function(i, itemRights){
            if(itemAllRights == itemRights && checked == false){
                if(itemRights == "SUPERUSER"){
                    data["disabled"] = true;
                } else {

                    data["disabled"] = false;
                }
                checked = true;
                data["item"] = itemAllRights;
                data["isChecked"] = true;
                viewModel.updateCheckedRights(data);
            }
        });
        if (checked == false){
            data["item"] = itemAllRights;
            data["isChecked"] = false;
            data["disabled"] = false;
            viewModel.updateCheckedRights(data);
        }
    });

    $.each(viewModel.checkedRights(), function(i, item){
        console.log(" - " + item["item"] + " - " + item["checked"]);
    });
}

function User(id, username, firstname, lastname, status, permissions) {
    return {
        id: ko.observable(id),
        username: ko.observable(username),
        firstname: ko.observable(firstname),
        lastname: ko.observable(lastname),
        status: ko.observable(status),
        permissions: ko.observableArray(permissions),

        removeThisUser: function() {
            if(confirm('Are you sure you want to remove this user?'))
            {
                viewModel.removeUser(this);
            }
        },

        changeStatus: function() {
            if (this.status() == "ACTIVE"){
                this.status("DISABLED");
            } else if (this.status() == "DISABLED") {
                this.status("ACTIVE");
            } else {
                this.status("WAIT_ACTIVATION");
            }
            updateUserStatus(this);
        }
    };
}<commit_msg>edit user panel: Save changes<commit_after>function pageViewModel(gvm) {
    // Page specific i18n bindings
    gvm.title = ko.computed(function(){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n.__("AdminPage");}, gvm);
    gvm.pageHeaderEditUser = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("UserEditTitle");}, gvm);

    gvm.edituserid = $("#usereditHeader").data('value');

    gvm.userName = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("UserName");}, gvm);
    gvm.firstName = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("Firstname");}, gvm);
    gvm.lastName = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("Lastname");}, gvm);
    gvm.userStatus = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("UserStatus");}, gvm);

    gvm.permissionRole = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("PermissionRole");}, gvm);
    gvm.permissionDescription = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("PermissionDescription");}, gvm);

    gvm.rights = ko.observableArray([]);
    gvm.allRights = ko.observableArray([]);
    gvm.checkedRights = ko.observableArray([]);
    gvm.user = ko.observableArray([]);

    gvm.updateUser = function(user)
    {
        gvm.user.push(user);
    },

    gvm.updatePermissions = function(permission)
    {
        gvm.rights.push(permission);
    },

    gvm.updateAllPermissions = function(permission)
    {
        gvm.allRights.push(permission);
    },

    gvm.removeUser = function(user) {
        gvm.user.remove(user);
        removeUser(user);
    },

    gvm.clearStructure = function() {
        gvm.rights.destroyAll();
        gvm.user.destroyAll();
    }

    gvm.updateCheckedRights = function(item){
        gvm.checkedRights.push(item);
    }
}

function initPage() {
    getAllUserDataById(viewModel.edituserid);
    setRights();

    $('#userEditForm').on('submit', function(e)
    {
        e.preventDefault();

        saveChanges();
        saveUserPermissions();
    });
}

function saveChanges(){
    console.log("Save changes");
    console.log("userid: " + viewModel.edituserid);

    saveUserEdits(viewModel.edituserid);
    saveUserPermissions();
}

function saveUserEdits(id){
    $.ajax({
        type: "POST",
        url: "/api/saveedit/" + id,
        data: $('#userEditForm').serialize(),
        success: function() {
            console.log('Success saved user changes');
        },
        error: function() {
            console.log("Error saving user changes");
        }
    });
}

function saveUserPermissions(){
    console.log("Save user permissions for user: " + viewModel.edituserid);
    //FIRST DELETE ALL PERMISSIONS
    $.getJSON("/api/removeroles/" + viewModel.edituserid, function(){
        console.log("User permissions were removed");
    });

    $.each(viewModel.allRights(), function(i, currentRights){

        var checkedValue = document.getElementsByName(currentRights);

        console.log(checkedValue[0].checked + " - " + currentRights);

        //SAVE NEW PERMISSIONS
        if(checkedValue[0].checked == true) {
            $.ajax({
                type: "POST",
                url: "/api/addrole/" + viewModel.edituserid,
                data: { 'currentRight': currentRights },
                success: function() {
                    console.log('Success saved user permission: ' + currentRights);
                },
                error: function() {
                    console.log('Error saving user permission: ' + currentRights);
                }
            });
        }
    });

}

function setRights(){
    viewModel.updateAllPermissions("GUEST");
    viewModel.updateAllPermissions("STUDENT");
    viewModel.updateAllPermissions("USER");
    viewModel.updateAllPermissions("SUPERUSER");
}

function getAllUserDataById(edituserid){
    console.log("Get data from user with id " + edituserid);
    $.getJSON("/api/edituser/" + edituserid, function(data)
    {
        var addedUsername = "";
        $.each(data, function(i, item){
            var current = item.username;

            $.each(data, function(i, item)
            {
                if(item.username == current && addedUsername != current){
                    console.log(current + " " + item.role);
                    viewModel.updatePermissions(item.role)
                }
            });

            if (addedUsername != current) {
                addedUsername = current;
                console.log("Added: " + addedUsername);
                viewModel.updateUser(new User(item.userid, item.username, item.firstname, item.lastname, item.status, viewModel.rights()));
            }
        });

        checkPermissions();
    });
}

function checkPermissions(){
    var checked = false;
    $.each(viewModel.allRights(), function(i, itemAllRights){
        checked = false;
        var data = [];
        $.each(viewModel.rights(), function(i, itemRights){
            if(itemAllRights == itemRights && checked == false){
                if(itemRights == "SUPERUSER"){
                    data["disabled"] = true;
                } else {

                    data["disabled"] = false;
                }
                checked = true;
                data["item"] = itemAllRights;
                data["isChecked"] = true;
                viewModel.updateCheckedRights(data);
            }
        });
        if (checked == false){
            data["item"] = itemAllRights;
            data["isChecked"] = false;
            data["disabled"] = false;
            viewModel.updateCheckedRights(data);
        }
    });

    $.each(viewModel.checkedRights(), function(i, item){
        console.log(" - " + item["item"] + " - " + item["checked"]);
    });
}

function User(id, username, firstname, lastname, status, permissions) {
    return {
        id: ko.observable(id),
        username: ko.observable(username),
        firstname: ko.observable(firstname),
        lastname: ko.observable(lastname),
        status: ko.observable(status),
        permissions: ko.observableArray(permissions),

        removeThisUser: function() {
            if(confirm('Are you sure you want to remove this user?'))
            {
                viewModel.removeUser(this);
            }
        },

        changeStatus: function() {
            if (this.status() == "ACTIVE"){
                this.status("DISABLED");
            } else if (this.status() == "DISABLED") {
                this.status("ACTIVE");
            } else {
                this.status("WAIT_ACTIVATION");
            }
            updateUserStatus(this);
        }
    };
}<|endoftext|>


<commit_before>define([
	"goo/math/Quaternion",
	"goo/math/Matrix3x3",
	"goo/math/Vector3"
], function(
	Quaternion,
	Matrix3x3,
	Vector3
) {

	"use strict";

	describe('Quaternion', function() {

		it('can be instantiated with or without arguments',function(){
			var p = new Quaternion();
			var q = new Quaternion(1,2,3,4);
			expect(p).toEqual(Quaternion.IDENTITY);
			expect(q.x).toEqual(1);
			expect(q.y).toEqual(2);
			expect(q.z).toEqual(3);
			expect(q.w).toEqual(4);
		});

		it('can add two quaternions',function(){
			var p = new Quaternion(1,1,1,1);
			var q = new Quaternion(2,2,2,2);
			var result = new Quaternion();
			Quaternion.add(p,q,result);
			expect(result).toEqual(new Quaternion(3,3,3,3));
		});

		it('can subtract two quaternions',function(){
			var p = new Quaternion(1,1,1,1);
			var q = new Quaternion(2,2,2,2);
			var result = new Quaternion();
			Quaternion.sub(p,q,result);
			expect(result).toEqual(new Quaternion(-1,-1,-1,-1));
		});

		it('can multiply two quaternions component-wise',function(){
			var p = new Quaternion(2,2,2,2);
			var q = new Quaternion(2,2,2,2);
			var result = new Quaternion();
			Quaternion.mul(p,q,result);
			expect(result).toEqual(new Quaternion(4,4,4,4));
		});

		it('can multiply two quaternions',function(){
			var p = new Quaternion();
			var q = new Quaternion();
			var result = new Quaternion();
			Quaternion.mul2(p,q,result);

			//! schteppe:  How to check result?
			expect(result).toEqual(new Quaternion());
		});

		it('can divide component-wise',function(){
			var p = new Quaternion(2,2,2,2);
			var q = new Quaternion(2,2,2,2);
			var result = new Quaternion();
			Quaternion.div(p,q,result);
			expect(result).toEqual(new Quaternion(1,1,1,1));
		});

		it('can add a scalar to a quaternion',function(){
			var p = new Quaternion(1,1,1,1);
			var result = new Quaternion();
			Quaternion.scalarAdd(p,1,result);
			expect(result).toEqual(new Quaternion(2,2,2,2));
		});

		it('can subtract a scalar from a quaternion',function(){
			var p = new Quaternion(1,1,1,1);
			var result = new Quaternion();
			Quaternion.scalarSub(p,1,result);
			expect(result).toEqual(new Quaternion(0,0,0,0));
		});

		it('can multiply a scalar with a quaternion',function(){
			var p = new Quaternion(1,1,1,1);
			var result = new Quaternion();
			Quaternion.scalarMul(p,2,result);
			expect(result).toEqual(new Quaternion(2,2,2,2));
		});

		it('can divide a quaternion with a scalar',function(){
			var p = new Quaternion(2,2,2,2);
			var result = new Quaternion();
			Quaternion.scalarDiv(p,2,result);
			expect(result).toEqual(new Quaternion(1,1,1,1));
		});

		it('can slerp',function(){
			var angle1 = Math.PI/2;
			var angle2 = 3*Math.PI/2;
			var startQuat = new Quaternion(Math.sin(angle1),0,0,Math.cos(angle1));
			var endQuat = new Quaternion(Math.sin(angle2),0,0,Math.cos(angle2));
			var result = new Quaternion();

			//! schteppe:  How to check ok?
			Quaternion.slerp(startQuat,endQuat,0.5,result);
		});

		it('can slerp via prototype method',function(){
			var startQuat = new Quaternion();
			var endQuat = new Quaternion();
			var result = new Quaternion();
			startQuat.slerp(endQuat,0.5,result);
			expect(result).toEqual(new Quaternion());
		});

		it('can negate',function(){
			var q = new Quaternion(1,1,1,1);
			q.negate();
			expect(q).toEqual(new Quaternion(-1,-1,-1,-1));
		});

		it('can dot',function(){
			var q = new Quaternion(1,1,1,1);
			expect(q.dot(q)).toEqual(4);
		});

		it('can be set from rotation matrix', function(){
			var q = new Quaternion();
			var m = new Matrix3x3();
			q.fromRotationMatrix(m);
			//! schteppe:  How to check ok?
		});

		it('can convert to rotation matrix', function(){
			var q = new Quaternion();
			var m = new Matrix3x3();
			q.toRotationMatrix(m);
			expect(q.toRotationMatrix() instanceof Matrix3x3).toBeTruthy();

			//! schteppe:  How to check ok?
		});

		it('can be set from vector to vector', function(){
			var q = new Quaternion();
			var u = new Vector3();
			var v = new Vector3();
			q.fromVectorToVector(u,v);
			//! schteppe:  How to check ok?
		});

		it('can be normalized', function(){
			var q = new Quaternion(0,0,0,2);
			q.normalize();
			expect(q.magnitude()).toEqual(1);
		});

		it('can get magnitude', function(){
			var q = new Quaternion(0,0,0,2);
			expect(q.magnitude()).toEqual(2);
		});

		it('can get squared magnitude', function(){
			var q = new Quaternion(0,0,0,2);
			expect(q.magnitudeSquared()).toEqual(4);
		});

		it('can be set from axis angle', function(){
			var q = new Quaternion();
			var axis = new Vector3(1,0,0);
			var angle = 0;
			q.fromAngleAxis(angle,axis);
			expect(q).toEqual(new Quaternion());
		});

		it('can be set from a normal axis and angle', function(){
			var q = new Quaternion();
			var axis = new Vector3(1,0,0);
			var angle = 0;
			q.fromAngleNormalAxis(angle,axis);
			expect(q).toEqual(new Quaternion());
		});

		it('can be set from a zero axis and angle', function(){
			var q = new Quaternion();
			var axis = new Vector3(0,0,0);
			var angle = 0;
			q.fromAngleNormalAxis(angle,axis);
			expect(q).toEqual(new Quaternion());
		});

		it('can generate axis and angle 1', function(){
			var q = new Quaternion();
			var axis = new Vector3(0,0,0);
			var angle = q.toAngleAxis(axis);
			expect(typeof angle).toEqual('number');
		});

		it('can generate axis and angle 2', function(){
			var q = new Quaternion();
			var axis = new Vector3(1,0,0);
			var axisResult = new Vector3();
			var angle = Math.PI/2;
			q.fromAngleNormalAxis(angle,axis);
			var angleResult = q.toAngleAxis(axisResult);
			expect(Math.abs(angleResult - angle)<=0.001).toBeTruthy();
			expect(axisResult).toEqual(axis);
		});

		it('can check for equality', function(){
			var q = new Quaternion();
			expect(q.equals(q)).toBeTruthy();
		});

		it('can check for equality with foreign object', function(){
			var q = new Quaternion();
			expect(q.equals(1)).toBeFalsy();
		});

		it('can set all components', function(){
			var q = new Quaternion();
			q.setd(1,2,3,4);
			expect(q).toEqual(new Quaternion(1,2,3,4));
		});

		it('can set all components via array', function(){
			var q = new Quaternion();
			q.seta([1,2,3,4]);
			expect(q).toEqual(new Quaternion(1,2,3,4));
		});

		it('can set all components via other quaternion', function(){
			var q = new Quaternion();
			var p = new Quaternion(1,2,3,4);
			q.setv(p);
			expect(q).toEqual(p);
		});

	});
});
<commit_msg>comments fix<commit_after>define([
	"goo/math/Quaternion",
	"goo/math/Matrix3x3",
	"goo/math/Vector3"
], function(
	Quaternion,
	Matrix3x3,
	Vector3
) {

	"use strict";

	describe('Quaternion', function() {

		it('can be instantiated with or without arguments',function(){
			var p = new Quaternion();
			var q = new Quaternion(1,2,3,4);
			expect(p).toEqual(Quaternion.IDENTITY);
			expect(q.x).toEqual(1);
			expect(q.y).toEqual(2);
			expect(q.z).toEqual(3);
			expect(q.w).toEqual(4);
		});

		it('can add two quaternions',function(){
			var p = new Quaternion(1,1,1,1);
			var q = new Quaternion(2,2,2,2);
			var result = new Quaternion();
			Quaternion.add(p,q,result);
			expect(result).toEqual(new Quaternion(3,3,3,3));
		});

		it('can subtract two quaternions',function(){
			var p = new Quaternion(1,1,1,1);
			var q = new Quaternion(2,2,2,2);
			var result = new Quaternion();
			Quaternion.sub(p,q,result);
			expect(result).toEqual(new Quaternion(-1,-1,-1,-1));
		});

		it('can multiply two quaternions component-wise',function(){
			var p = new Quaternion(2,2,2,2);
			var q = new Quaternion(2,2,2,2);
			var result = new Quaternion();
			Quaternion.mul(p,q,result);
			expect(result).toEqual(new Quaternion(4,4,4,4));
		});

		it('can multiply two quaternions',function(){
			var p = new Quaternion();
			var q = new Quaternion();
			var result = new Quaternion();
			Quaternion.mul2(p,q,result);

			//! schteppe: TODO: How to check result?
			expect(result).toEqual(new Quaternion());
		});

		it('can divide component-wise',function(){
			var p = new Quaternion(2,2,2,2);
			var q = new Quaternion(2,2,2,2);
			var result = new Quaternion();
			Quaternion.div(p,q,result);
			expect(result).toEqual(new Quaternion(1,1,1,1));
		});

		it('can add a scalar to a quaternion',function(){
			var p = new Quaternion(1,1,1,1);
			var result = new Quaternion();
			Quaternion.scalarAdd(p,1,result);
			expect(result).toEqual(new Quaternion(2,2,2,2));
		});

		it('can subtract a scalar from a quaternion',function(){
			var p = new Quaternion(1,1,1,1);
			var result = new Quaternion();
			Quaternion.scalarSub(p,1,result);
			expect(result).toEqual(new Quaternion(0,0,0,0));
		});

		it('can multiply a scalar with a quaternion',function(){
			var p = new Quaternion(1,1,1,1);
			var result = new Quaternion();
			Quaternion.scalarMul(p,2,result);
			expect(result).toEqual(new Quaternion(2,2,2,2));
		});

		it('can divide a quaternion with a scalar',function(){
			var p = new Quaternion(2,2,2,2);
			var result = new Quaternion();
			Quaternion.scalarDiv(p,2,result);
			expect(result).toEqual(new Quaternion(1,1,1,1));
		});

		it('can slerp',function(){
			var angle1 = Math.PI/2;
			var angle2 = 3*Math.PI/2;
			var startQuat = new Quaternion(Math.sin(angle1),0,0,Math.cos(angle1));
			var endQuat = new Quaternion(Math.sin(angle2),0,0,Math.cos(angle2));
			var result = new Quaternion();

			//! schteppe: TODO: How to check ok?
			Quaternion.slerp(startQuat,endQuat,0.5,result);
		});

		it('can slerp via prototype method',function(){
			var startQuat = new Quaternion();
			var endQuat = new Quaternion();
			var result = new Quaternion();
			startQuat.slerp(endQuat,0.5,result);
			expect(result).toEqual(new Quaternion());
		});

		it('can negate',function(){
			var q = new Quaternion(1,1,1,1);
			q.negate();
			expect(q).toEqual(new Quaternion(-1,-1,-1,-1));
		});

		it('can dot',function(){
			var q = new Quaternion(1,1,1,1);
			expect(q.dot(q)).toEqual(4);
		});

		it('can be set from rotation matrix', function(){
			var q = new Quaternion();
			var m = new Matrix3x3();
			q.fromRotationMatrix(m);
			//! schteppe: TODO: How to check ok?
		});

		it('can convert to rotation matrix', function(){
			var q = new Quaternion();
			var m = new Matrix3x3();
			q.toRotationMatrix(m);
			expect(q.toRotationMatrix() instanceof Matrix3x3).toBeTruthy();

			//! schteppe: TODO: How to check ok?
		});

		it('can be set from vector to vector', function(){
			var q = new Quaternion();
			var u = new Vector3();
			var v = new Vector3();
			q.fromVectorToVector(u,v);
			//! schteppe: TODO: How to check ok?
		});

		it('can be normalized', function(){
			var q = new Quaternion(0,0,0,2);
			q.normalize();
			expect(q.magnitude()).toEqual(1);
		});

		it('can get magnitude', function(){
			var q = new Quaternion(0,0,0,2);
			expect(q.magnitude()).toEqual(2);
		});

		it('can get squared magnitude', function(){
			var q = new Quaternion(0,0,0,2);
			expect(q.magnitudeSquared()).toEqual(4);
		});

		it('can be set from axis angle', function(){
			var q = new Quaternion();
			var axis = new Vector3(1,0,0);
			var angle = 0;
			q.fromAngleAxis(angle,axis);
			expect(q).toEqual(new Quaternion());
		});

		it('can be set from a normal axis and angle', function(){
			var q = new Quaternion();
			var axis = new Vector3(1,0,0);
			var angle = 0;
			q.fromAngleNormalAxis(angle,axis);
			expect(q).toEqual(new Quaternion());
		});

		it('can be set from a zero axis and angle', function(){
			var q = new Quaternion();
			var axis = new Vector3(0,0,0);
			var angle = 0;
			q.fromAngleNormalAxis(angle,axis);
			expect(q).toEqual(new Quaternion());
		});

		it('can generate axis and angle 1', function(){
			var q = new Quaternion();
			var axis = new Vector3(0,0,0);
			var angle = q.toAngleAxis(axis);
			expect(typeof angle).toEqual('number');
		});

		it('can generate axis and angle 2', function(){
			var q = new Quaternion();
			var axis = new Vector3(1,0,0);
			var axisResult = new Vector3();
			var angle = Math.PI/2;
			q.fromAngleNormalAxis(angle,axis);
			var angleResult = q.toAngleAxis(axisResult);
			expect(Math.abs(angleResult - angle)<=0.001).toBeTruthy();
			expect(axisResult).toEqual(axis);
		});

		it('can check for equality', function(){
			var q = new Quaternion();
			expect(q.equals(q)).toBeTruthy();
		});

		it('can check for equality with foreign object', function(){
			var q = new Quaternion();
			expect(q.equals(1)).toBeFalsy();
		});

		it('can set all components', function(){
			var q = new Quaternion();
			q.setd(1,2,3,4);
			expect(q).toEqual(new Quaternion(1,2,3,4));
		});

		it('can set all components via array', function(){
			var q = new Quaternion();
			q.seta([1,2,3,4]);
			expect(q).toEqual(new Quaternion(1,2,3,4));
		});

		it('can set all components via other quaternion', function(){
			var q = new Quaternion();
			var p = new Quaternion(1,2,3,4);
			q.setv(p);
			expect(q).toEqual(p);
		});

	});
});
<|endoftext|>


<commit_before>function pageViewModel(gvm) {
    // Page specific i18n bindings
    gvm.title = ko.computed(function(){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n.__("AdminEditPage");}, gvm);
    gvm.pageHeaderEditUser = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("UserEditTitle");}, gvm);
    gvm.projectname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectName");}, gvm);
    gvm.menuLanguage = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("MenuLanguage");}, gvm);

    gvm.firstname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("Firstname");}, gvm);
    gvm.lastname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("Lastname");}, gvm);
    gvm.email = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("Email");}, gvm);
    gvm.status = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AssessProjectStatus");}, gvm);

    gvm.adminEditUserPermissions = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AdminEditUserPermissions");}, gvm);
    gvm.adminRights = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AdminRights");}, gvm);

    gvm.adminGuest = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AdminGuest");}, gvm);
    gvm.adminStudent = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AdminStudent");}, gvm);
    gvm.adminUser = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AdminUser");}, gvm);
    gvm.adminSuperuser = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AdminSuperuser");}, gvm);

    gvm.saveBtn = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("SaveBtn");}, gvm);
    gvm.cancelBtn = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("CancelBtn");}, gvm);

    gvm.edituserid = $("#usereditHeader").data('value');

    gvm.loggedinuser = ko.observable();

    getLoggedInUser();

    gvm.userName = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("UserName");}, gvm);
    gvm.firstName = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("Firstname");}, gvm);
    gvm.lastName = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("Lastname");}, gvm);
    gvm.userStatus = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("UserStatus");}, gvm);

    gvm.permissionRole = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("PermissionRole");}, gvm);
    gvm.permissionDescription = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("PermissionDescription");}, gvm);

    gvm.currentUserRole = ko.observable();
    gvm.availablePermissions = ko.observableArray(['GUEST', 'STUDENT', 'USER', 'SUPERUSER']);

    gvm.rights = ko.observableArray([]);
    gvm.allRights = ko.observableArray([]);
    gvm.userRights = ko.observableArray([]);
    gvm.user = ko.observableArray([]);

    gvm.updateUser = function(user)
    {
        gvm.user.push(user);
    },

    gvm.updatePermissions = function(permission)
    {
        gvm.rights.push(permission);
    },

    gvm.updateAllPermissions = function(permission)
    {
        gvm.allRights.push(permission);
    },

    gvm.removeUser = function(user) {
        gvm.user.remove(user);
        removeUser(user);
    },

    gvm.clearStructure = function() {
        gvm.rights.destroyAll();
        gvm.user.destroyAll();
    }
}

function initPage() {
    getAllUserDataById(viewModel.edituserid);

    $('#userEditForm').on('submit', function(e)
    {
        e.preventDefault();

        if(viewModel.loggedinuser != viewModel.edituserid)
        {
            saveChanges();
            saveUserPermissions();
        } else {
            saveChanges();
        }
    });

    $(".cancelPageBtn").click(function()
    {
        window.location.href = "/admin/home";
    });
}

function getLoggedInUser(){
    $.getJSON("/api/loggedinuser", function(data){
        viewModel.loggedinuser = data;
    });
}

function saveChanges(){
    saveUserEdits(viewModel.edituserid);
}

function saveUserEdits(id){
    $.ajax({
        type: "POST",
        url: "/api/saveedit/" + id,
        data: $('#userEditForm').serialize(),
        success: function() {
        },
        error: function() {
            console.log("Error saving user changes");
        }
    });
}

function saveUserPermissions(){
    var role = viewModel.currentUserRole();
    var permissions = "GUEST ";

    if(role == 'STUDENT' || role == 'USER' || role == 'SUPERUSER'){
        permissions += "STUDENT ";
        if(role == 'USER' || role == 'SUPERUSER'){
            permissions += "USER ";
            if(role == 'SUPERUSER'){
                permissions += "SUPERUSER";
            }
        }
    }

    //SAVE NEW PERMISSIONS
    $.ajax({
        type: "POST",
        url: "/api/addrole/" + viewModel.edituserid,
        data: { 'permissions': permissions },
        success: function() {
            alert('Changes saved correctly');
            window.location.href = "/admin/home";
        },
        error: function() {
            alert('Error saving user. Please contact the Administrator');
        }
    });
}

function getAllUserDataById(edituserid){
    $.getJSON("/api/edituser/" + edituserid, function(data)
    {
        var addedUsername = "";
        $.each(data, function(i, item){
            var current = item.username;

            $.each(data, function(i, item)
            {
                if(item.username == current && addedUsername != current){
                    viewModel.updatePermissions(item.role)
                }
            });

            if (addedUsername != current) {
                addedUsername = current;
                console.log(viewModel.rights());
                viewModel.updateUser(new User(item.userid, item.username, item.firstname, item.lastname, item.status, viewModel.rights()));
            }
        });
    });
}

function User(id, username, firstname, lastname, status, permissions) {
    console.log(permissions);
    return {
        id: ko.observable(id),
        username: ko.observable(username),
        firstname: ko.observable(firstname),
        lastname: ko.observable(lastname),
        status: ko.observable(status),
        permissions: ko.observableArray(permissions),
        userStatuses: ko.observableArray(['ACTIVE', 'DISABLED']),

        removeThisUser: function() {
            if(confirm('Are you sure you want to remove this user?'))
            {
                viewModel.removeUser(this);
            }
        },

        changeStatus: function() {
            if (this.status() == "ACTIVE"){
                this.status("DISABLED");
            } else if (this.status() == "DISABLED") {
                this.status("ACTIVE");
            } else if (this.status() == "WAIT_ACTIVATION") {
                this.status("ACTIVE");
            }
            updateUserStatus(this);
        }
    };
}<commit_msg>small fixes<commit_after>function pageViewModel(gvm) {
    // Page specific i18n bindings
    gvm.title = ko.computed(function(){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n.__("AdminEditPage");}, gvm);
    gvm.pageHeaderEditUser = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("UserEditTitle");}, gvm);
    gvm.projectname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectName");}, gvm);
    gvm.menuLanguage = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("MenuLanguage");}, gvm);

    gvm.firstname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("Firstname");}, gvm);
    gvm.lastname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("Lastname");}, gvm);
    gvm.email = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("Email");}, gvm);
    gvm.status = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AssessProjectStatus");}, gvm);

    gvm.adminEditUserPermissions = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AdminEditUserPermissions");}, gvm);
    gvm.adminRights = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AdminRights");}, gvm);

    gvm.adminGuest = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AdminGuest");}, gvm);
    gvm.adminStudent = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AdminStudent");}, gvm);
    gvm.adminUser = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AdminUser");}, gvm);
    gvm.adminSuperuser = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AdminSuperuser");}, gvm);

    gvm.saveBtn = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("SaveBtn");}, gvm);
    gvm.cancelBtn = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("CancelBtn");}, gvm);

    gvm.edituserid = $("#usereditHeader").data('value');

    gvm.loggedinuser = ko.observable();

    getLoggedInUser();

    gvm.userName = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("UserName");}, gvm);
    gvm.firstName = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("Firstname");}, gvm);
    gvm.lastName = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("Lastname");}, gvm);
    gvm.userStatus = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("UserStatus");}, gvm);

    gvm.permissionRole = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("PermissionRole");}, gvm);
    gvm.permissionDescription = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("PermissionDescription");}, gvm);

    gvm.currentUserRole = ko.observable();
    gvm.availablePermissions = ko.observableArray(['GUEST', 'STUDENT', 'USER', 'SUPERUSER']);

    gvm.rights = ko.observableArray([]);
    gvm.allRights = ko.observableArray([]);
    gvm.userRights = ko.observableArray([]);
    gvm.user = ko.observableArray([]);

    gvm.updateUser = function(user)
    {
        gvm.user.push(user);
    },

    gvm.updatePermissions = function(permission)
    {
        gvm.rights.push(permission);
    },

    gvm.updateAllPermissions = function(permission)
    {
        gvm.allRights.push(permission);
    },

    gvm.removeUser = function(user) {
        gvm.user.remove(user);
        removeUser(user);
    },

    gvm.clearStructure = function() {
        gvm.rights.destroyAll();
        gvm.user.destroyAll();
    }
}

function initPage() {
    getAllUserDataById(viewModel.edituserid);

    $('#userEditForm').on('submit', function(e)
    {
        e.preventDefault();

        if(viewModel.loggedinuser != viewModel.edituserid)
        {
            saveChanges();
            saveUserPermissions();
        } else {
            saveChanges();
        }
    });

    $(".cancelPageBtn").click(function()
    {
        window.location.href = "/admin/home";
    });
}

function getLoggedInUser(){
    $.getJSON("/api/loggedinuser", function(data){
        viewModel.loggedinuser = data;
    });
}

function saveChanges(){
    saveUserEdits(viewModel.edituserid);
}

function saveUserEdits(id){
    $.ajax({
        type: "POST",
        url: "/api/saveedit/" + id,
        data: $('#userEditForm').serialize(),
        success: function() {
        },
        error: function() {
            console.log("Error saving user changes");
        }
    });
}

function saveUserPermissions(){
    var role = viewModel.currentUserRole();
    var permissions = "GUEST ";

    if(role == 'STUDENT' || role == 'USER' || role == 'SUPERUSER'){
        permissions += "STUDENT ";
        if(role == 'USER' || role == 'SUPERUSER'){
            permissions += "USER ";
            if(role == 'SUPERUSER'){
                permissions += "SUPERUSER";
            }
        }
    }

    //SAVE NEW PERMISSIONS
    $.ajax({
        type: "POST",
        url: "/api/addrole/" + viewModel.edituserid,
        data: { 'permissions': permissions },
        success: function() {
            alert('Changes saved correctly');
            window.location.href = "/admin/home";
        },
        error: function() {
            alert('Error saving user. Please contact the Administrator');
        }
    });
}

function getAllUserDataById(edituserid){
    $.getJSON("/api/edituser/" + edituserid, function(data)
    {
        var addedUsername = "";
        $.each(data, function(i, item){
            var current = item.username;

            $.each(data, function(i, item)
            {
                if(item.username == current && addedUsername != current){
                    viewModel.updatePermissions(item.role)
                }
            });

            if (addedUsername != current) {
                addedUsername = current;
                console.log(viewModel.rights());
                viewModel.updateUser(new User(item.userid, item.username, item.firstname, item.lastname, item.status, viewModel.rights()));
            }
        });
    });
}

function contains(a, obj) {
    var i = a.length;
    while (i--) {
        if (a[i] === obj) {
            return true;
        }
    }
    return false;
}

function User(id, username, firstname, lastname, status, permissions) {
    console.log(permissions);
    var hoogste = "GUEST";

    if (contains(permissions, "SUPERUSER")){
        hoogste = "SUPERUSER";
    } else if (contains(permissions, "USER")){
        hoogste = "USER";
    } else if (contains(permissions, "STUDENT")){
        hoogste = "STUDENT";
    } else if (contains(permissions, "GUEST")){
        hoogste = "GUEST";
    }
    console.log(hoogste);
    return {
        id: ko.observable(id),
        username: ko.observable(username),
        firstname: ko.observable(firstname),
        lastname: ko.observable(lastname),
        status: ko.observable(status),
        permissions: ko.observableArray(hoogste),
        userStatuses: ko.observableArray(['ACTIVE', 'DISABLED']),

        removeThisUser: function() {
            if(confirm('Are you sure you want to remove this user?'))
            {
                viewModel.removeUser(this);
            }
        },

        changeStatus: function() {
            if (this.status() == "ACTIVE"){
                this.status("DISABLED");
            } else if (this.status() == "DISABLED") {
                this.status("ACTIVE");
            } else if (this.status() == "WAIT_ACTIVATION") {
                this.status("ACTIVE");
            }
            updateUserStatus(this);
        }
    };
}<|endoftext|>


<commit_before>function runTest()
{
    FBTest.openNewTab(basePath + "commandLine/4217/issue4217.html", function(win)
    {
        FBTest.openFirebug(function()
        {
            FBTest.enableConsolePanel(function(win)
            {
                var config = {tagName: "div", classes: "logRow", counter: 2};

                FBTest.waitForDisplayedElement("console", config, function(row)
                {
                    var panelNode = FBTest.getPanel("console").panelNode;
                    var rows = panelNode.querySelectorAll(".logRow");

                    if (FBTest.compare(2, rows.length, "There must be two logs"))
                    {
                        FBTest.compare(/console.log\('hello'\)/,
                            rows[0].getElementsByClassName("objectBox-text").item(0).textContent,
                            "'console.log('hello')' must be shown inside the Console");
                        FBTest.compare("hello",
                            rows[1].getElementsByClassName("objectBox-text").item(0).textContent,
                            "'hello' must be shown inside the Console");
                    }

                    var isMac = panelNode.ownerDocument.defaultView.navigator.platform.contains("Mac");
                    var eventModifierKeys = (isMac ?
                                            {metaKey: true, shiftKey: true} :
                                            {ctrlKey: true, shiftKey: true});

                    FBTest.sendShortcut("e", eventModifierKeys);

                    rows = panelNode.querySelectorAll(".logRow");

                    if (FBTest.compare(4, rows.length, "There must be four logs"))
                    {
                        FBTest.compare(/console.log\('hello'\)/,
                            rows[2].getElementsByClassName("objectBox-text").item(0).textContent,
                            "'console.log('hello')' must be shown inside the Console");
                        FBTest.compare("hello",
                            rows[3].getElementsByClassName("objectBox-text").item(0).textContent,
                            "'hello' must be shown inside the Console");
                    }

                    FBTest.testDone();
                });

                FBTest.executeCommand("console.log('hello')");
            });
        });
    });
}<commit_msg>Used FBTest.isMac()<commit_after>function runTest()
{
    FBTest.openNewTab(basePath + "commandLine/4217/issue4217.html", function(win)
    {
        FBTest.openFirebug(function()
        {
            FBTest.enableConsolePanel(function(win)
            {
                var config = {tagName: "div", classes: "logRow", counter: 2};

                FBTest.waitForDisplayedElement("console", config, function(row)
                {
                    var panelNode = FBTest.getPanel("console").panelNode;
                    var rows = panelNode.getElementsByClassName("logRow");

                    if (FBTest.compare(2, rows.length, "There must be two logs"))
                    {
                        FBTest.compare(/console.log\('hello'\)/,
                            rows[0].getElementsByClassName("objectBox-text").item(0).textContent,
                            "'console.log('hello')' must be shown inside the Console");
                        FBTest.compare("hello",
                            rows[1].getElementsByClassName("objectBox-text").item(0).textContent,
                            "'hello' must be shown inside the Console");
                    }

                    var eventModifierKeys = FBTest.isMac() ?
                        {metaKey: true, shiftKey: true} :
                        {ctrlKey: true, shiftKey: true};

                    FBTest.sendShortcut("e", eventModifierKeys);

                    rows = panelNode.getElementsByClassName("logRow");

                    if (FBTest.compare(4, rows.length, "There must be four logs"))
                    {
                        FBTest.compare(/console.log\('hello'\)/,
                            rows[2].getElementsByClassName("objectBox-text").item(0).textContent,
                            "'console.log('hello')' must be shown inside the Console");
                        FBTest.compare("hello",
                            rows[3].getElementsByClassName("objectBox-text").item(0).textContent,
                            "'hello' must be shown inside the Console");
                    }

                    FBTest.testDone();
                });

                FBTest.executeCommand("console.log('hello')");
            });
        });
    });
}<|endoftext|>


<commit_before>var chai = require('chai')
  , expect = require('chai').expect
  , sinon = require('sinon')
  , loadState = require('../../lib/middleware/load')
  , Dispatcher = require('../../lib/manager');

describe('load', function() {

  it('should be named loadState', function() {
    var store = new Object();
    expect(loadState(store).name).to.equal('loadState');
  });

  describe('loading state without handle', function() {
    var store = {
      load: function(){}
    };

    before(function() {
      sinon.stub(store, 'load').yields(null, undefined);
    });

    after(function() {
      store.load.restore();
    });

    var request, err;
    before(function(done) {
      chai.connect.use(loadState(store))
        .req(function(req) {
          request = req;
        })
        .next(function(e) {
          err = e;
          done();
        })
        .dispatch();
    });

    it('should not error', function() {
      expect(err).to.be.undefined;
    });

    it('should not set state', function() {
      expect(request.state).to.be.undefined;
    });

    it('should not call store#load', function() {
      expect(store.load).to.not.have.been.called;
    });
  });

});
<commit_msg>Add tests.<commit_after>var chai = require('chai')
  , expect = require('chai').expect
  , sinon = require('sinon')
  , loadState = require('../../lib/middleware/load')
  , Dispatcher = require('../../lib/manager');

describe('load', function() {

  it('should be named loadState', function() {
    var store = new Object();
    expect(loadState(store).name).to.equal('loadState');
  });

  describe('loading state without state query parameter', function() {
    var store = {
      load: function(){}
    };

    before(function() {
      sinon.stub(store, 'load').yields(null, { name: 'test', x: 1 });
    });

    after(function() {
      store.load.restore();
    });

    var request, err;
    before(function(done) {
      chai.connect.use(loadState(store))
        .req(function(req) {
          request = req;
          req.query = { state: '12345678' };
        })
        .next(function(e) {
          err = e;
          done();
        })
        .dispatch();
    });

    it('should not error', function() {
      expect(err).to.be.undefined;
    });

    it('should set state', function() {
      expect(request.state).to.be.an('object');
      expect(request.state).to.deep.equal({
        name: 'test',
        x: 1
      });
    });

    it('should not call store#load', function() {
      expect(store.load).to.have.been.calledOnce;
      var call = store.load.getCall(0);
      expect(call.args[0]).to.equal(request);
      expect(call.args[1]).to.equal('12345678');
    });
  });

  describe('loading state without handle', function() {
    var store = {
      load: function(){}
    };

    before(function() {
      sinon.stub(store, 'load').yields(null, undefined);
    });

    after(function() {
      store.load.restore();
    });

    var request, err;
    before(function(done) {
      chai.connect.use(loadState(store))
        .req(function(req) {
          request = req;
        })
        .next(function(e) {
          err = e;
          done();
        })
        .dispatch();
    });

    it('should not error', function() {
      expect(err).to.be.undefined;
    });

    it('should not set state', function() {
      expect(request.state).to.be.undefined;
    });

    it('should not call store#load', function() {
      expect(store.load).to.not.have.been.called;
    });
  });

});
<|endoftext|>


<commit_before>"use strict";

//
// this class contains flow-relative data field
//
cssRegions.Flow = function NamedFlow(name) {

    // TODO: force immediate relayout if someone ask the overset properties
    // and the layout has been deemed wrong (still isn't a proof of correctness but okay)

    // define the flow name
    this.name = name; Object.defineProperty(this, "name", {get: function() { return name; }});

    // define the overset status
    this.overset = false;

    // define the first empty region
    this.firstEmptyRegionIndex = -1;

    // elements poured into the flow
    this.content = this.lastContent = [];

    // elements that consume this flow
    this.regions = this.lastRegions = [];

    // event handlers
    this.eventListeners = {
        "regionfragmentchange": [],
        "regionoversetchange": [],
    };

    // this function is used to work with dom event streams
    var This=this; This.update = function(stream) {
        stream.schedule(This.update); This.relayout();
    };

    // register to style changes already
    This.lastStylesheetAdded = 0;
    cssCascade.addEventListener('stylesheetadded', function() {
        if(This.lastStylesheetAdded - Date() > 100) {
            This.lastStylesheetAdded = +Date();
            This.relayout();
        }
    });
}

cssRegions.Flow.prototype.removeFromContent = function(element) {

    // TODO: clean up stuff
    this.removeEventListenersOf(element);

    // remove reference
    var index = this.content.indexOf(element);
    if(index>=0) { this.content.splice(index,1); }

};

cssRegions.Flow.prototype.removeFromRegions = function(element) {

    // TODO: clean up stuff
    this.removeEventListenersOf(element);

    // remove reference
    var index = this.regions.indexOf(element);
    if(index>=0) { this.regions.splice(index,1); }

};

cssRegions.Flow.prototype.addToContent = function(element) {

    // walk the tree to find an element inside the content chain
    var content = this.content;
    var treeWalker = document.createTreeWalker(
        document.documentElement,
        NodeFilter.SHOW_ELEMENT,
        function(node) {
            return content.indexOf(node) >= 0 ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
        },
        false
    );

    // which by the way has to be after the considered element
    treeWalker.currentNode = element;

    // if we find such node
    if(treeWalker.nextNode()) {

        // insert the element at his current location
        content.splice(content.indexOf(treeWalker.currentNode),0,element);

    } else {

        // add the new element to the end of the array
        content.push(element);

    }

};

cssRegions.Flow.prototype.addToRegions = function(element) {

    // walk the tree to find an element inside the region chain
    var regions = this.regions;
    var treeWalker = document.createTreeWalker(
        document.documentElement,
        NodeFilter.SHOW_ELEMENT,
        function(node) {
            return regions.indexOf(node) >= 0 ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
        },
        false
    );

    // which by the way has to be after the considered element
    treeWalker.currentNode = element;

    // if we find such node
    if(treeWalker.nextNode()) {

        // insert the element at his current location
        regions.splice(this.regions.indexOf(treeWalker.currentNode),0,element);

    } else {

        // add the new element to the end of the array
        regions.push(element);
    }

};

cssRegions.Flow.prototype.generateContentFragment = function() {
    var fragment = document.createDocumentFragment(); var This=this;

    // add copies of all due content
    for(var i=0; i<this.content.length; i++) {
        var element = this.content[i];

        //
        // STEP 1: IDENTIFY FRAGMENT SOURCES AS SUCH
        //
        cssRegionsHelpers.markNodesAsFragmentSource([element], element.cssRegionsLastFlowIntoType=="content");

        //
        // STEP 2: CLONE THE FRAGMENT SOURCES
        //

        // depending on the requested behavior
        if(element.cssRegionsLastFlowIntoType=="element") {

            // add the element
            fragment.appendChild(element.cloneNode(true));

            // clone the style
            cssRegionsHelpers.copyStyle(element, fragment.lastChild);

        } else {

            // add current children
            var el = element.firstChild; while(el) {

                // add the element
                fragment.appendChild(el.cloneNode(true));

                // clone the style
                cssRegionsHelpers.copyStyle(el, fragment.lastChild);

                el = el.nextSibling;
            }

        }

    }

    //
    // STEP 3: HIDE TEXT NODES IN FRAGMENT SOURCES
    //
    cssRegionsHelpers.hideTextNodesFromFragmentSource(this.content);

    //
    // STEP 4: CONVERT CLONED FRAGMENT SOURCES INTO TRUE FRAGMENTS
    //
    cssRegionsHelpers.transformFragmentSourceToFragments(
        Array.prototype.slice.call(fragment.childNodes,0)
    )

    //
    // CLONED CONTENT IS READY!
    //
    return fragment;
}

cssRegions.Flow.prototype.relayout = function() {
    var This = this;

    // batch relayout queries
    if(This.relayoutScheduled) { return; }
    This.relayoutScheduled = true;
    requestAnimationFrame(function() { This._relayout() });

}

cssRegions.Flow.prototype._relayout = function(){
    var This=this;

    try {

        //
        // note: it is recommended to look at the beautiful
        // drawings I made before attempting to understand
        // this stuff. If you don't have them, ask me.
        //
        console.log("starting a new relayout for "+This.name);
        //debugger;

        // NOTE: we recover the scroll position in case the browser mess it up
        var docElmScrollTop = document.documentElement.scrollTop;
        var docBdyScrollTop = document.body.scrollTop;

        //
        // STEP 1: REMOVE PREVIOUS EVENT LISTENERS
        //

        // remove the listeners from everything
        This.removeEventListenersOf(This.lastRegions);
        This.removeEventListenersOf(This.lastContent);

        //
        // STEP 2: RESTORE CONTENT/REGIONS TO A CLEAN STATE
        //

        // cleanup previous layout
        cssRegionsHelpers.unmarkNodesAsRegion(This.lastRegions); This.lastRegions = This.regions.slice(0);
        cssRegionsHelpers.unmarkNodesAsFragmentSource(This.lastContent); This.lastContent = This.content.slice(0);

        //
        // STEP 3: EMPTY ALL REGIONS
        // ADD WRAPPER FOR FLOW CONTENT
        // PREPARE FOR CONTENT CLONING
        //

        // TODO: compute the style of all source elements
        // TODO: generate stylesheets for those rules

        // empty all the regions
        cssRegionsHelpers.markNodesAsRegion(This.regions);

        // create a fresh list of the regions
        var regionStack = This.regions.slice(0).reverse();

        //
        // STEP 4: CLONE THE CONTENT
        // ADD METADATA TO CLONED CONTENT
        // HIDE FLOW CONTENT AT INITIAL POSITION
        //

        // create a fresh list of the content
        var contentFragment = This.generateContentFragment();

        //
        // STEP 5: POUR CONTENT INTO THE REGIONS
        //

        // layout this stuff
        This.overset = cssRegions.layoutContent(regionStack, contentFragment);
        This.firstEmptyRegionIndex = This.regions.length-1; while(This.regions[This.firstEmptyRegionIndex]) {
            if(This.regions[This.firstEmptyRegionIndex].cssRegionsWrapper.firstChild) {
                if((++This.firstEmptyRegionIndex)==This.regions.length) {
                    This.firstEmptyRegionIndex = -1;
                }
                break;
            } else {
                This.firstEmptyRegionIndex--;
            }
        }

        //
        // STEP 6: REGISTER TO UPDATE EVENTS
        //

        // make sure regions update are taken in consideration
        if(window.MutationObserver) {
            This.addEventListenersTo(This.content);
            This.addEventListenersTo(This.regions);
        } else {
            // the other browsers don't get this as acurately
            // but that shouldn't be that of an issue for 99% of the cases
            setImmediate(function() {
                This.addEventListenersTo(This.content);
            });
        }

        //
        // STEP 7: FIRE SOME EVENTS
        //
        requestAnimationFrame(function() {

            // TODO: only fire when necessary but...
            This.dispatchEvent('regionfragmentchange');
            This.dispatchEvent('regionoversetchange');

        });

        // NOTE: we recover the scroll position in case the browser mess it up
        document.documentElement.scrollTop = docElmScrollTop;
        document.body.scrollTop = docBdyScrollTop;

        // mark layout has being done
        This.relayoutScheduled = false;

    } catch(ex) {

        // sometimes IE fails for no valid reason
        // (other than the page is still loading)
        setImmediate(function() { throw ex; });

        // but we cannot accept to fail, so we need to try again
        // until we finish a complete layout pass...
        requestAnimationFrame(function() { This._relayout() });

    }
}

cssRegions.Flow.prototype.relayoutIfSizeChanged = function() {

    // go through all regions
    // and see if any did change of size
    var rs = this.regions;
    for(var i=rs.length; i--; ) {
        if(
            rs[i].offsetHeight !== rs[i].cssRegionsLastOffsetHeight
            || rs[i].offsetWidth !== rs[i].cssRegionsLastOffsetWidth
        ) {
            this.relayout(); return;
        }
    }

}

cssRegions.Flow.prototype.addEventListenersTo = function(nodes) {
    var This=this; if(nodes instanceof Element) { nodes=[nodes] }

    nodes.forEach(function(element) {
        if(!element.cssRegionsEventStream) {
            element.cssRegionsEventStream = new myDOMUpdateEventStream({target: element});
            element.cssRegionsEventStream.schedule(This.update);
        }
    });

}

cssRegions.Flow.prototype.removeEventListenersOf = function(nodes) {
    var This=this; if(nodes instanceof Element) { nodes=[nodes] }

    nodes.forEach(function(element) {
        if(element.cssRegionsEventStream) {
            element.cssRegionsEventStream.dispose();
            delete element.cssRegionsEventStream;
        }
    });

}

// alias
cssRegions.NamedFlow = cssRegions.Flow;

// return a disconnected array of the content of a NamedFlow
cssRegions.NamedFlow.prototype.getContent = function getContent() {
    return this.content.slice(0)
}

// return a disconnected array of the content of a NamedFlow
cssRegions.NamedFlow.prototype.getContent = function getContent() {
    return this.content.slice(0)
}

cssRegions.NamedFlow.prototype.getRegionsByContent = function getRegionsByContent(node) {
    var regions = [];
    var fragments = document.querySelectorAll('[data-css-regions-fragment-of="'+node.getAttribute('data-css-regions-fragment-source')+'"]');
    for (var i=0; i<fragments.length; i++) {

        var current=fragments[i]; do {

            if(current.getAttribute('data-css-region')) {
                regions.push(current); break;
            }

        } while(current=current.parentNode);

    }

    return regions;
}

basicObjectModel.EventTarget.implementsIn(cssRegions.Flow);

//
// this class is a collection of named flows (not an array, sadly)
//
cssRegions.NamedFlowCollection = function NamedFlowCollection() {

    this.length = 0;

}

cssRegions.NamedFlowCollection.prototype.namedItem = function(k) {
    return cssRegions.flows[k] || (cssRegions.flows[k]=new cssRegions.Flow(k));
}

//
// this helper creates the required methods on top of the DOM {ie: public exports}
//
cssRegions.enablePolyfillObjectModel = function() {

    //
    // DOCUMENT INTERFACE
    //

    //
    // returns a static list of active named flows
    //
    document.getNamedFlows = function() {

        var c = new cssRegions.NamedFlowCollection(); var flows = cssRegions.flows;
        for(var flowName in cssRegions.flows) {

            if(Object.prototype.hasOwnProperty.call(flows, flowName)) {

                // only active flows can be included
                if(flows[flowName].content.length!=0 || flows[flowName].regions.length!=0) {
                    c[c.length++] = c[flowName] = flows[flowName];
                }

            }

        }
        return c;

    }

    //
    // returns a live object for any named flow
    //
    document.getNamedFlow = function(flowName) {

        var flows = cssRegions.flows;
        return (flows[flowName] || (flows[flowName]=new cssRegions.NamedFlow(flowName)));

    }

    //
    // ELEMENT INTERFACE
    //
    Object.defineProperties(
        Element.prototype,
        {
            "regionOverset": {
                get: function() {
                    return this._regionOverset || 'fit';
                },
                set: function(value) {
                    this._regionOverset = value;
                }
            },
            "getRegionFlowRanges": {
                value: function getRegionFlowRanges() {
                    return null; // TODO: can we implement that? I think we can't (properly).
                }
            },
            "getComputedRegionStyle": {
                value: function getComputedRegionStyle(element,pseudo) {
                    // TODO: only works while we don't relayout
                    // TODO: only works properly for elements actually in the region
                    var fragment = document.querySelector('[data-css-regions-fragment-of="'+element.getAttribute('data-css-regions-fragment-source')+'"]');
                    if(pseudo) {
                        return getComputedStyle(fragment||element);
                    } else {
                        return getComputedStyle(fragment||element, pseudo);
                    }
                }
            }
        }
    )

    //
    // CSSDeclaration interface
    //
    cssCascade.polyfillStyleInterface('flow-into');
    cssCascade.polyfillStyleInterface('flow-from');
    cssCascade.polyfillStyleInterface('region-fragment');

}

cssRegions.enablePolyfill();<commit_msg>Fixed a bug where an event would fire multiple times<commit_after>"use strict";

//
// this class contains flow-relative data field
//
cssRegions.Flow = function NamedFlow(name) {

    // TODO: force immediate relayout if someone ask the overset properties
    // and the layout has been deemed wrong (still isn't a proof of correctness but okay)

    // define the flow name
    this.name = name; Object.defineProperty(this, "name", {get: function() { return name; }});

    // define the overset status
    this.overset = false;

    // define the first empty region
    this.firstEmptyRegionIndex = -1;

    // elements poured into the flow
    this.content = this.lastContent = [];

    // elements that consume this flow
    this.regions = this.lastRegions = [];

    // event handlers
    this.eventListeners = {
        "regionfragmentchange": [],
        "regionoversetchange": [],
    };

    // this function is used to work with dom event streams
    var This=this; This.update = function(stream) {
        stream.schedule(This.update); This.relayout();
    };

    // register to style changes already
    This.lastStylesheetAdded = 0;
    cssCascade.addEventListener('stylesheetadded', function() {
        if(This.lastStylesheetAdded - Date() > 100) {
            This.lastStylesheetAdded = +Date();
            This.relayout();
        }
    });
}

cssRegions.Flow.prototype.removeFromContent = function(element) {

    // TODO: clean up stuff
    this.removeEventListenersOf(element);

    // remove reference
    var index = this.content.indexOf(element);
    if(index>=0) { this.content.splice(index,1); }

};

cssRegions.Flow.prototype.removeFromRegions = function(element) {

    // TODO: clean up stuff
    this.removeEventListenersOf(element);

    // remove reference
    var index = this.regions.indexOf(element);
    if(index>=0) { this.regions.splice(index,1); }

};

cssRegions.Flow.prototype.addToContent = function(element) {

    // walk the tree to find an element inside the content chain
    var content = this.content;
    var treeWalker = document.createTreeWalker(
        document.documentElement,
        NodeFilter.SHOW_ELEMENT,
        function(node) {
            return content.indexOf(node) >= 0 ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
        },
        false
    );

    // which by the way has to be after the considered element
    treeWalker.currentNode = element;

    // if we find such node
    if(treeWalker.nextNode()) {

        // insert the element at his current location
        content.splice(content.indexOf(treeWalker.currentNode),0,element);

    } else {

        // add the new element to the end of the array
        content.push(element);

    }

};

cssRegions.Flow.prototype.addToRegions = function(element) {

    // walk the tree to find an element inside the region chain
    var regions = this.regions;
    var treeWalker = document.createTreeWalker(
        document.documentElement,
        NodeFilter.SHOW_ELEMENT,
        function(node) {
            return regions.indexOf(node) >= 0 ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
        },
        false
    );

    // which by the way has to be after the considered element
    treeWalker.currentNode = element;

    // if we find such node
    if(treeWalker.nextNode()) {

        // insert the element at his current location
        regions.splice(this.regions.indexOf(treeWalker.currentNode),0,element);

    } else {

        // add the new element to the end of the array
        regions.push(element);
    }

};

cssRegions.Flow.prototype.generateContentFragment = function() {
    var fragment = document.createDocumentFragment(); var This=this;

    // add copies of all due content
    for(var i=0; i<this.content.length; i++) {
        var element = this.content[i];

        //
        // STEP 1: IDENTIFY FRAGMENT SOURCES AS SUCH
        //
        cssRegionsHelpers.markNodesAsFragmentSource([element], element.cssRegionsLastFlowIntoType=="content");

        //
        // STEP 2: CLONE THE FRAGMENT SOURCES
        //

        // depending on the requested behavior
        if(element.cssRegionsLastFlowIntoType=="element") {

            // add the element
            fragment.appendChild(element.cloneNode(true));

            // clone the style
            cssRegionsHelpers.copyStyle(element, fragment.lastChild);

        } else {

            // add current children
            var el = element.firstChild; while(el) {

                // add the element
                fragment.appendChild(el.cloneNode(true));

                // clone the style
                cssRegionsHelpers.copyStyle(el, fragment.lastChild);

                el = el.nextSibling;
            }

        }

    }

    //
    // STEP 3: HIDE TEXT NODES IN FRAGMENT SOURCES
    //
    cssRegionsHelpers.hideTextNodesFromFragmentSource(this.content);

    //
    // STEP 4: CONVERT CLONED FRAGMENT SOURCES INTO TRUE FRAGMENTS
    //
    cssRegionsHelpers.transformFragmentSourceToFragments(
        Array.prototype.slice.call(fragment.childNodes,0)
    )

    //
    // CLONED CONTENT IS READY!
    //
    return fragment;
}

cssRegions.Flow.prototype.relayout = function() {
    var This = this;

    // batch relayout queries
    if(This.relayoutScheduled) { return; }
    This.relayoutScheduled = true;
    requestAnimationFrame(function() { This._relayout() });

}

cssRegions.Flow.prototype._relayout = function(){
    var This=this;

    try {

        //
        // note: it is recommended to look at the beautiful
        // drawings I made before attempting to understand
        // this stuff. If you don't have them, ask me.
        //
        console.log("starting a new relayout for "+This.name);
        //debugger;

        // NOTE: we recover the scroll position in case the browser mess it up
        var docElmScrollTop = document.documentElement.scrollTop;
        var docBdyScrollTop = document.body.scrollTop;

        //
        // STEP 1: REMOVE PREVIOUS EVENT LISTENERS
        //

        // remove the listeners from everything
        This.removeEventListenersOf(This.lastRegions);
        This.removeEventListenersOf(This.lastContent);
        cancelAnimationFrame(This.lastEventRAF);

        //
        // STEP 2: RESTORE CONTENT/REGIONS TO A CLEAN STATE
        //

        // cleanup previous layout
        cssRegionsHelpers.unmarkNodesAsRegion(This.lastRegions); This.lastRegions = This.regions.slice(0);
        cssRegionsHelpers.unmarkNodesAsFragmentSource(This.lastContent); This.lastContent = This.content.slice(0);

        //
        // STEP 3: EMPTY ALL REGIONS
        // ADD WRAPPER FOR FLOW CONTENT
        // PREPARE FOR CONTENT CLONING
        //

        // TODO: compute the style of all source elements
        // TODO: generate stylesheets for those rules

        // empty all the regions
        cssRegionsHelpers.markNodesAsRegion(This.regions);

        // create a fresh list of the regions
        var regionStack = This.regions.slice(0).reverse();

        //
        // STEP 4: CLONE THE CONTENT
        // ADD METADATA TO CLONED CONTENT
        // HIDE FLOW CONTENT AT INITIAL POSITION
        //

        // create a fresh list of the content
        var contentFragment = This.generateContentFragment();

        //
        // STEP 5: POUR CONTENT INTO THE REGIONS
        //

        // layout this stuff
        This.overset = cssRegions.layoutContent(regionStack, contentFragment);
        This.firstEmptyRegionIndex = This.regions.length-1; while(This.regions[This.firstEmptyRegionIndex]) {
            if(This.regions[This.firstEmptyRegionIndex].cssRegionsWrapper.firstChild) {
                if((++This.firstEmptyRegionIndex)==This.regions.length) {
                    This.firstEmptyRegionIndex = -1;
                }
                break;
            } else {
                This.firstEmptyRegionIndex--;
            }
        }

        //
        // STEP 6: REGISTER TO UPDATE EVENTS
        //

        // make sure regions update are taken in consideration
        if(window.MutationObserver) {
            This.addEventListenersTo(This.content);
            This.addEventListenersTo(This.regions);
        } else {
            // the other browsers don't get this as acurately
            // but that shouldn't be that of an issue for 99% of the cases
            setImmediate(function() {
                This.addEventListenersTo(This.content);
            });
        }

        //
        // STEP 7: FIRE SOME EVENTS
        //
        if(This.regions.length > 0) {
            This.lastEventRAF = requestAnimationFrame(function() {

                // TODO: only fire when necessary but...
                This.dispatchEvent('regionfragmentchange');
                This.dispatchEvent('regionoversetchange');

            });
        }

        // NOTE: we recover the scroll position in case the browser mess it up
        document.documentElement.scrollTop = docElmScrollTop;
        document.body.scrollTop = docBdyScrollTop;

        // mark layout has being done
        This.relayoutScheduled = false;

    } catch(ex) {

        // sometimes IE fails for no valid reason
        // (other than the page is still loading)
        setImmediate(function() { throw ex; });

        // but we cannot accept to fail, so we need to try again
        // until we finish a complete layout pass...
        requestAnimationFrame(function() { This._relayout() });

    }
}

cssRegions.Flow.prototype.relayoutIfSizeChanged = function() {

    // go through all regions
    // and see if any did change of size
    var rs = this.regions;
    for(var i=rs.length; i--; ) {
        if(
            rs[i].offsetHeight !== rs[i].cssRegionsLastOffsetHeight
            || rs[i].offsetWidth !== rs[i].cssRegionsLastOffsetWidth
        ) {
            this.relayout(); return;
        }
    }

}

cssRegions.Flow.prototype.addEventListenersTo = function(nodes) {
    var This=this; if(nodes instanceof Element) { nodes=[nodes] }

    nodes.forEach(function(element) {
        if(!element.cssRegionsEventStream) {
            element.cssRegionsEventStream = new myDOMUpdateEventStream({target: element});
            element.cssRegionsEventStream.schedule(This.update);
        }
    });

}

cssRegions.Flow.prototype.removeEventListenersOf = function(nodes) {
    var This=this; if(nodes instanceof Element) { nodes=[nodes] }

    nodes.forEach(function(element) {
        if(element.cssRegionsEventStream) {
            element.cssRegionsEventStream.dispose();
            delete element.cssRegionsEventStream;
        }
    });

}

// alias
cssRegions.NamedFlow = cssRegions.Flow;

// return a disconnected array of the content of a NamedFlow
cssRegions.NamedFlow.prototype.getContent = function getContent() {
    return this.content.slice(0)
}

// return a disconnected array of the content of a NamedFlow
cssRegions.NamedFlow.prototype.getContent = function getContent() {
    return this.content.slice(0)
}

cssRegions.NamedFlow.prototype.getRegionsByContent = function getRegionsByContent(node) {
    var regions = [];
    var fragments = document.querySelectorAll('[data-css-regions-fragment-of="'+node.getAttribute('data-css-regions-fragment-source')+'"]');
    for (var i=0; i<fragments.length; i++) {

        var current=fragments[i]; do {

            if(current.getAttribute('data-css-region')) {
                regions.push(current); break;
            }

        } while(current=current.parentNode);

    }

    return regions;
}

basicObjectModel.EventTarget.implementsIn(cssRegions.Flow);

//
// this class is a collection of named flows (not an array, sadly)
//
cssRegions.NamedFlowCollection = function NamedFlowCollection() {

    this.length = 0;

}

cssRegions.NamedFlowCollection.prototype.namedItem = function(k) {
    return cssRegions.flows[k] || (cssRegions.flows[k]=new cssRegions.Flow(k));
}

//
// this helper creates the required methods on top of the DOM {ie: public exports}
//
cssRegions.enablePolyfillObjectModel = function() {

    //
    // DOCUMENT INTERFACE
    //

    //
    // returns a static list of active named flows
    //
    document.getNamedFlows = function() {

        var c = new cssRegions.NamedFlowCollection(); var flows = cssRegions.flows;
        for(var flowName in cssRegions.flows) {

            if(Object.prototype.hasOwnProperty.call(flows, flowName)) {

                // only active flows can be included
                if(flows[flowName].content.length!=0 || flows[flowName].regions.length!=0) {
                    c[c.length++] = c[flowName] = flows[flowName];
                }

            }

        }
        return c;

    }

    //
    // returns a live object for any named flow
    //
    document.getNamedFlow = function(flowName) {

        var flows = cssRegions.flows;
        return (flows[flowName] || (flows[flowName]=new cssRegions.NamedFlow(flowName)));

    }

    //
    // ELEMENT INTERFACE
    //
    Object.defineProperties(
        Element.prototype,
        {
            "regionOverset": {
                get: function() {
                    return this._regionOverset || 'fit';
                },
                set: function(value) {
                    this._regionOverset = value;
                }
            },
            "getRegionFlowRanges": {
                value: function getRegionFlowRanges() {
                    return null; // TODO: can we implement that? I think we can't (properly).
                }
            },
            "getComputedRegionStyle": {
                value: function getComputedRegionStyle(element,pseudo) {
                    // TODO: only works while we don't relayout
                    // TODO: only works properly for elements actually in the region
                    var fragment = document.querySelector('[data-css-regions-fragment-of="'+element.getAttribute('data-css-regions-fragment-source')+'"]');
                    if(pseudo) {
                        return getComputedStyle(fragment||element);
                    } else {
                        return getComputedStyle(fragment||element, pseudo);
                    }
                }
            }
        }
    )

    //
    // CSSDeclaration interface
    //
    cssCascade.polyfillStyleInterface('flow-into');
    cssCascade.polyfillStyleInterface('flow-from');
    cssCascade.polyfillStyleInterface('region-fragment');

}

cssRegions.enablePolyfill();<|endoftext|>


<commit_before>const { async } = require('./../../../../app.js');
const config = require('./../../../../config/config');
const { Router } = require('supertest');
const { expect } = require('chai');

describe('homeController tests', () => {
    let app = null;

    beforeEach(() => {
        return Promise.resolve()
            .then(() => () => require('./../../../../db')
                .init(config.db))
            .then((db) => require('./../../../../data')
                .init(db))
            .then((data) => require('./../../../../config/express')
                .init(data, config))
            .then((_app) => {
                app = _app;
            });
    });

    describe('GET /', () => {
        it('expect to return 200', (done) => {
            Router.expect(app)
                .get('/')
                .expect(200)
                .end((err, res) => {
                    if (err) {
                        return done(err);
                    }

                    console.log(res.text);

                    return done();
                });
        });
    });
});
<commit_msg>Removing unnecessary things.<commit_after>const config = require('./../../../../config/config');
const request = require('supertest');
const { expect } = require('chai');

describe('homeController tests', () => {
    let app = null;

    beforeEach(() => {
        return Promise.resolve()
            .then(() => () => require('./../../../../db')
                .init(config.db))
            .then((db) => require('./../../../../data')
                .init(db))
            .then((data) => require('./../../../../config/express')
                .init(data, config))
            .then((_app) => {
                app = _app;
            });
    });

    describe('GET /', () => {
        it('expect to return 200', (done) => {
            request(app)
                .get('/')
                .expect(200)
                .end((err, res) => {
                    if (err) {
                        return done(err);
                    }

                    console.log(res.text);

                    return done();
                });
        });
    });
});
<|endoftext|>


<commit_before>!function(a){"use strict";var b=a.HTMLCanvasElement&&a.HTMLCanvasElement.prototype,c=a.Blob&&function(){try{return Boolean(new Blob)}catch(a){return!1}}(),d=c&&a.Uint8Array&&function(){try{return 100===new Blob([new Uint8Array(100)]).size}catch(a){return!1}}(),e=a.BlobBuilder||a.WebKitBlobBuilder||a.MozBlobBuilder||a.MSBlobBuilder,f=/^data:((.*?)(;charset=.*?)?)(;base64)?,/,g=(c||e)&&a.atob&&a.ArrayBuffer&&a.Uint8Array&&function(a){var b,g,h,i,j,k,l,m,n;if(b=a.match(f),!b)throw new Error("invalid data URI");for(g=b[2]?b[1]:"text/plain"+(b[3]||";charset=US-ASCII"),h=!!b[4],i=a.slice(b[0].length),j=h?atob(i):decodeURIComponent(i),k=new ArrayBuffer(j.length),l=new Uint8Array(k),m=0;m<j.length;m+=1)l[m]=j.charCodeAt(m);return c?new Blob([d?l:k],{type:g}):(n=new e,n.append(k),n.getBlob(g))};a.HTMLCanvasElement&&!b.toBlob&&(b.mozGetAsFile?b.toBlob=function(a,c,d){a(d&&b.toDataURL&&g?g(this.toDataURL(c,d)):this.mozGetAsFile("blob",c))}:b.toDataURL&&g&&(b.toBlob=function(a,b,c){a(g(this.toDataURL(b,c)))})),"function"==typeof define&&define.amd?define(function(){return g}):a.dataURLtoBlob=g}(window);<commit_msg>Production build.<commit_after>!function(t){"use strict";var e=t.HTMLCanvasElement&&t.HTMLCanvasElement.prototype,n=t.Blob&&function(){try{return Boolean(new Blob)}catch(t){return!1}}(),o=n&&t.Uint8Array&&function(){try{return 100===new Blob([new Uint8Array(100)]).size}catch(t){return!1}}(),r=t.BlobBuilder||t.WebKitBlobBuilder||t.MozBlobBuilder||t.MSBlobBuilder,a=/^data:((.*?)(;charset=.*?)?)(;base64)?,/,i=(n||r)&&t.atob&&t.ArrayBuffer&&t.Uint8Array&&function(t){var e,i,l,u,B,b,c,f,d;if(e=t.match(a),!e)throw new Error("invalid data URI");for(i=e[2]?e[1]:"text/plain"+(e[3]||";charset=US-ASCII"),l=!!e[4],u=t.slice(e[0].length),B=l?atob(u):decodeURIComponent(u),b=new ArrayBuffer(B.length),c=new Uint8Array(b),f=0;f<B.length;f+=1)c[f]=B.charCodeAt(f);return n?new Blob([o?c:b],{type:i}):(d=new r,d.append(b),d.getBlob(i))};t.HTMLCanvasElement&&!e.toBlob&&(e.mozGetAsFile?e.toBlob=function(t,n,o){t(o&&e.toDataURL&&i?i(this.toDataURL(n,o)):this.mozGetAsFile("blob",n))}:e.toDataURL&&i&&(e.toBlob=function(t,e,n){t(i(this.toDataURL(e,n)))})),"function"==typeof define&&define.amd?define(function(){return i}):t.dataURLtoBlob=i}(window);
<|endoftext|>


<commit_before>///////////////////////////////////////////////////////////////////////////////
//
//	files.js
//
//		data file loading and handling
//		supports async loading from assets/ and also manually
//		adding external content into the file registry
//
///////////////////////////////////////////////////////////////////////////////

var files = {};

//ensuring everything we've asked for is loaded
var _files_loaded = true;
function check_files_loaded()
{
	_files_loaded = true;
	for(path in files)
	{
		if(!files[path].loaded)
		{
			loaded = false;
			break;
		}
	}
	return _files_loaded;
}

function get_file_path(name)
{
	return "./assets/"+name;
}

function fetch_file(name)
{
	if(files.hasOwnProperty(name))
	{
		return files[name];
	}
	//else
	return null;
}

function add_external_file(name, contents)
{
	var file = {
		name: name,
		error: false,
		loaded: true,
		contents: contents
	};
	files[name] = file;
	return file;
}

function load_file(name)
{
	//possible early-out if we've already loaded it
	var fetched = fetch_file(name);
	if(fetched !== null)
	{
		return fetched;
	}

	//if we don't have it, better load it now
	_files_loaded = false;

	var file = {
		name: name,
		error: false,
		loaded: false,
		contents: null
	};
	try {
		var xhttp = new XMLHttpRequest();
		xhttp.open("GET", get_file_path(name), true);
		xhttp.onreadystatechange = function()
		{
			if (this.readyState == 4)
			{
				file.loaded = true;
				if(this.status == 200 || this.status == 0 || this.status == 304)
				{
					file.contents = this.responseText;
				}
				else
				{
					file.contents = "";
					file.error = true;
				}
			}
		};
		xhttp.overrideMimeType('text/plain');
		xhttp.send(null);
	}
	catch(e)
	{
		file.error = true;
		file.loaded = true;
		file.contents = "";
	}

	files[name] = file;

	return file;
}

//contents parsing helpers

//csv
//	handles converting a csv file into a 2d array
//	including removing blank lines
//args:
//	raw: true to not trim or process each line and element
//	parse_numbers; true to run everything through Number()
//	parse_ints; true to run everything through parseInt()
function csv_to_2d_array(contents, args) {
	if(args === undefined) {
		args = {};
	}
	var lines = contents.split("\n");
	for(var i = 0; i < lines.length; i++) {
		if(args.raw !== true) {
			lines[i] = lines[i].trim();
		}
		//blank line?
		if(lines[i] == "" || lines[i] == "\r") {
			//remove
			lines.splice(i, 1);
			i--;
			continue;
		}
		lines[i] = lines[i].split(",");
		if(args.raw !== true) {
			for(var j = 0; j < lines[i].length; j++) {
				if(args.parse_numbers === true) {
					lines[i][j] = Number(lines[i][j]);
				} else if(args.parse_ints === true) {
					lines[i][j] = parseInt(lines[i][j]);
				} else {
					lines[i][j] = lines[i][j].trim();
				}
			}
		}
	}
	return lines;
}

<commit_msg>[modified] a different way of detecting file loading (maybe more chrome/SimpleHTTPServer friendly?)<commit_after>///////////////////////////////////////////////////////////////////////////////
//
//	files.js
//
//		data file loading and handling
//		supports async loading from assets/ and also manually
//		adding external content into the file registry
//
///////////////////////////////////////////////////////////////////////////////

var files = {};

//ensuring everything we've asked for is loaded
var _files_loaded = true;
function check_files_loaded()
{
	_files_loaded = true;
	for(path in files)
	{
		if(!files[path].loaded)
		{
			loaded = false;
			break;
		}
	}
	return _files_loaded;
}

function get_file_path(name)
{
	return "./assets/"+name;
}

function fetch_file(name)
{
	if(files.hasOwnProperty(name))
	{
		return files[name];
	}
	//else
	return null;
}

function add_external_file(name, contents)
{
	var file = {
		name: name,
		error: false,
		loaded: true,
		contents: contents
	};
	files[name] = file;
	return file;
}

function load_file(name)
{
	//possible early-out if we've already loaded it
	var fetched = fetch_file(name);
	if(fetched !== null)
	{
		return fetched;
	}

	//if we don't have it, better load it now
	_files_loaded = false;

	var file = {
		name: name,
		error: false,
		loaded: false,
		contents: null
	};
	try {
		var xhttp = new XMLHttpRequest();
		xhttp.addEventListener("loadend", function(e) {
			file.loaded = true;
			file.contents = this.responseText;
			if(file.contents == null) //failure?
			{
				file.contents = "";
				file.error = true;
			}
		})
		xhttp.open("GET", get_file_path(name), true);
		xhttp.overrideMimeType('text/plain');
		xhttp.send(null);
	}
	catch(e)
	{
		file.error = true;
		file.loaded = true;
		file.contents = "";
	}

	files[name] = file;

	return file;
}

//contents parsing helpers

//csv
//	handles converting a csv file into a 2d array
//	including removing blank lines
//args:
//	raw: true to not trim or process each line and element
//	parse_numbers; true to run everything through Number()
//	parse_ints; true to run everything through parseInt()
function csv_to_2d_array(contents, args) {
	if(args === undefined) {
		args = {};
	}
	var lines = contents.split("\n");
	for(var i = 0; i < lines.length; i++) {
		if(args.raw !== true) {
			lines[i] = lines[i].trim();
		}
		//blank line?
		if(lines[i] == "" || lines[i] == "\r") {
			//remove
			lines.splice(i, 1);
			i--;
			continue;
		}
		lines[i] = lines[i].split(",");
		if(args.raw !== true) {
			for(var j = 0; j < lines[i].length; j++) {
				if(args.parse_numbers === true) {
					lines[i][j] = Number(lines[i][j]);
				} else if(args.parse_ints === true) {
					lines[i][j] = parseInt(lines[i][j]);
				} else {
					lines[i][j] = lines[i][j].trim();
				}
			}
		}
	}
	return lines;
}

<|endoftext|>


<commit_before>(function(app) {
  'use strict';

  var FileSaver = require('file-saver');
  var helper = app.helper || require('../helper.js');
  var dom = app.dom || require('../dom.js');
  var Component = app.Component || require('./component.js');
  var ContentHeader = app.ContentHeader || require('./content-header.js');
  var ModuleContainer = app.ModuleContainer || require('./module-container.js');

  var Content = helper.inherits(function(props) {
    Content.super_.call(this, props);

    this.header = new ContentHeader({
      element: this.headerElement(),
      sidebarCollapser: props.sidebarCollapser,
      sidebarExpander: props.sidebarExpander,
      fileLoader: Content.prototype.fileLoader.bind(this),
      fileSaver: Content.prototype.fileSaver.bind(this),
    });

    this.moduleContainer = new ModuleContainer({
      element: this.moduleContainerElement(),
      moduleDragStarter: props.moduleDragStarter,
      moduleDragEnder: props.moduleDragEnder,
    });
  }, Component);

  Content.prototype.headerElement = function() {
    return dom.child(this.element(), 0);
  };

  Content.prototype.moduleContainerElement = function() {
    return dom.child(this.element(), 1);
  };

  Content.prototype.disabled = function(value) {
    this.header.disabled(value);
    this.moduleContainer.disabled(value);
  };

  Content.prototype.loadModuleByClientPosition = function(props, visiblePortNames) {
    return this.moduleContainer.loadModuleByClientPosition(props, visiblePortNames).catch(function(e) {
      if (!(e instanceof RangeError)) {
        throw e;
      }
    });
  };

  Content.prototype.redraw = function() {
    this.header.redraw();
    this.moduleContainer.redraw();
  };

  Content.prototype.fileLoader = function(file) {
    this.disabled(true);
    dom.load(file).then(function(text) {
      var data = JSON.parse(text);
      this.moduleContainer.clear();
      return this.moduleContainer.load(data);
    }.bind(this)).catch(function(e) {
      alert(e);
    }).then(function() {
      this.disabled(false);
    }.bind(this));
  };

  Content.prototype.fileSaver = function() {
    var text = JSON.stringify(this.moduleContainer.toData());
    var blob = new Blob([text], { type: 'application/json' });
    FileSaver.saveAs(blob, 'download.json');
  };

  if (typeof module !== 'undefined' && module.exports) {
    module.exports = Content;
  } else {
    app.Content = Content;
  }
})(this.app || (this.app = {}));
<commit_msg>Add method to load modules from JSON text<commit_after>(function(app) {
  'use strict';

  var FileSaver = require('file-saver');
  var helper = app.helper || require('../helper.js');
  var dom = app.dom || require('../dom.js');
  var Component = app.Component || require('./component.js');
  var ContentHeader = app.ContentHeader || require('./content-header.js');
  var ModuleContainer = app.ModuleContainer || require('./module-container.js');

  var Content = helper.inherits(function(props) {
    Content.super_.call(this, props);

    this.header = new ContentHeader({
      element: this.headerElement(),
      sidebarCollapser: props.sidebarCollapser,
      sidebarExpander: props.sidebarExpander,
      fileLoader: Content.prototype.fileLoader.bind(this),
      fileSaver: Content.prototype.fileSaver.bind(this),
    });

    this.moduleContainer = new ModuleContainer({
      element: this.moduleContainerElement(),
      moduleDragStarter: props.moduleDragStarter,
      moduleDragEnder: props.moduleDragEnder,
    });
  }, Component);

  Content.prototype.headerElement = function() {
    return dom.child(this.element(), 0);
  };

  Content.prototype.moduleContainerElement = function() {
    return dom.child(this.element(), 1);
  };

  Content.prototype.disabled = function(value) {
    this.header.disabled(value);
    this.moduleContainer.disabled(value);
  };

  Content.prototype.loadJSON = function(text) {
    var data = JSON.parse(text);
    this.moduleContainer.clear();
    return this.moduleContainer.load(data);
  };

  Content.prototype.loadModuleByClientPosition = function(props, visiblePortNames) {
    return this.moduleContainer.loadModuleByClientPosition(props, visiblePortNames).catch(function(e) {
      if (!(e instanceof RangeError)) {
        throw e;
      }
    });
  };

  Content.prototype.redraw = function() {
    this.header.redraw();
    this.moduleContainer.redraw();
  };

  Content.prototype.fileLoader = function(file) {
    this.disabled(true);
    dom.load(file).then(function(text) {
      return this.loadJSON(text);
    }.bind(this)).catch(function(e) {
      alert(e);
    }).then(function() {
      this.disabled(false);
    }.bind(this));
  };

  Content.prototype.fileSaver = function() {
    var text = JSON.stringify(this.moduleContainer.toData());
    var blob = new Blob([text], { type: 'application/json' });
    FileSaver.saveAs(blob, 'download.json');
  };

  if (typeof module !== 'undefined' && module.exports) {
    module.exports = Content;
  } else {
    app.Content = Content;
  }
})(this.app || (this.app = {}));
<|endoftext|>


<commit_before>/** @jsx React.DOM */
define([
    'underscore', 'jquery', 'react', 'kendo',
    '../ImmutableOptimizations'
], function (_, $, React, kendo, ImmutableOptimizations) {
    'use strict';

    var KendoGrid = React.createClass({

        getDefaultProps: function () {
            return {
                className: '',
                height: 150, // TODO remove this
                dataSource: undefined,
                columns: undefined
            };
        },

        render: function () {
            console.assert(this.props.dataSource);
            console.assert(this.props.columns);
            return (
);
        },

        componentDidMount: function () {
            var $rootNode = $(this.getDOMNode());
            void kendo;
            $rootNode.kendoGrid({
                dataSource: this.props.dataSource,
                height: this.props.height,
                columns: this.props.columns
            });
        },

        componentDidUpdate: function (prevProps, prevState) {
            var $el = $(this.getDOMNode());
            var kendoWidget = $el.data('kendoGrid');

            if (this.props.dataSource instanceof Array) {
                // This better be a datasource that was originally built from inline data.
                // I don't know how to detect this to verify it.
                kendoWidget.dataSource.data(this.props.dataSource);
            }
            else if (prevProps.dataSource !== this.props.dataSource) {
                kendoWidget.setDataSource(this.props.dataSource);
            }
        }
    });

    return KendoGrid;
});<commit_msg>KendoGrid should support rowTemplate - fixes #42<commit_after>/** @jsx React.DOM */
define([
    'underscore', 'jquery', 'react', 'kendo',
    '../ImmutableOptimizations'
], function (_, $, React, kendo, ImmutableOptimizations) {
    'use strict';

    var KendoGrid = React.createClass({

        getDefaultProps: function () {
            return {
                className: '',
                height: 150, // TODO remove this
                dataSource: undefined,
                columns: undefined,
                rowTemplate: undefined
            };
        },

        render: function () {
            console.assert(this.props.dataSource);
            console.assert(this.props.columns);
            return (
);
        },

        componentDidMount: function () {
            var $rootNode = $(this.getDOMNode());
            void kendo;
            $rootNode.kendoGrid({
                dataSource: this.props.dataSource,
                height: this.props.height,
                columns: this.props.columns,
                rowTemplate: this.props.rowTemplate
            });
        },

        componentDidUpdate: function (prevProps, prevState) {
            var $el = $(this.getDOMNode());
            var kendoWidget = $el.data('kendoGrid');

            if (this.props.dataSource instanceof Array) {
                // This better be a datasource that was originally built from inline data.
                // I don't know how to detect this to verify it.
                kendoWidget.dataSource.data(this.props.dataSource);
            }
            else if (prevProps.dataSource !== this.props.dataSource) {
                kendoWidget.setDataSource(this.props.dataSource);
            }
        }
    });

    return KendoGrid;
});<|endoftext|>