<commit_before>var mainObject = {
    elm: null,
    elm1: null,
    myDetails: null,
    equalsBtn: null,
    resultDisplayer: null,
    lhs: null,
    rhs: null,
    result: true,
    x: null,
    y: null,
    obj: null,
    computedStyle: null,
    incX: 1,
    incY: 1,
    inter: 0,
    init: function(eventBinding) {
        eventBinding = eventBinding || false;
        if (eventBinding) {
            this.elm = $(".innerBox").get(0);
            this.elm1 = $(".headerWrapper").get(0);
            this.myDetails = $(".myDetails");
            this.resultDisplayer = $(".resultDisplayer");
            this.rhs = $(".rhs");
            this.lhs = $(".lhs");
            this.equalsBtn = $(".componentButton.equals");
            this.bindEvents();
            window.console.log = (str, cls) => {
                this.setItInParagraph(str, cls);
            }
        }
        clearInterval(this.inter);
        this.inter = setInterval(this.doBounce.bind(this), 20);
    },
    bindEvents: function() {
        var _this = this;
        $(_this.elm).hover(function() {
            clearInterval(_this.inter);
            $(this).removeClass("animate").addClass("stopped");
            _this.myDetails.finish().slideDown("fast");
        }, function() {
            _this.init();
            $(this).removeClass("stopped").addClass("animate");
            _this.myDetails.finish().slideUp("fast");
        }).click(function() {
            window.open("https://www.facebook.com/profile.php?id=100007985747854", "_blank");
        });
        _this.equalsBtn.click(function() {
            var x = _this.lhs.val().trim(),
                y = _this.rhs.val().trim(),evalX,evalY;
            try {
				_this.setResultsArea();
                _this.result = eval("(" + x + ") == (" + y + ")");
				evalX = eval("(" + x + ")");
				evalY = eval("(" + y + ")");
                _this.processAlgo(evalX, evalY, 1, (typeof evalX == "object" && evalX !== null) ? _this.getObjectRep(evalX) : x, (typeof evalY == "object" && evalY !== null) ? _this.getObjectRep(evalY) : y);
				console.log("RESULT : " + _this.result.toString().toUpperCase(), _this.result.toString())
            } catch (e) {
                console.log(e);
            }
        });
        $(window).resize(function() {
            _this.obj = _this.elm1.getBoundingClientRect();
        }).resize().load(function() {
            setTimeout(function() {
                $("#disqus_thread").addClass("discussPartialDisplay");
            }, 2000);
        });
    },
    doBounce: function() {
        this.computedStyle = window.getComputedStyle(this.elm);
        this.x = parseInt(this.computedStyle.left);
        this.y = parseInt(this.computedStyle.top);
        if (this.x < 0 || (this.x + 20) > this.obj.width) this.incX = -this.incX;
        if (this.y < 0 || (this.y + 20) > this.obj.height) this.incY = -this.incY;
        this.elm.style.left = this.x + this.incX + "px";
        this.elm.style.top = this.y + this.incY + "px";
    },
    setResultsArea : function(){
	this.resultDisplayer.empty().removeClass("center");
    },
    setItInParagraph: function(str, cls) {
        return $("
").html(((cls == "explanation") ? "⇨ " : "") + str).appendTo(this.resultDisplayer);
    },
    stringChecker: function(val) {
        return typeof val == "string" ? "\"" + val + "\"" : typeof val == "object" ? this.getObjectRep(val) : val;
    },
    getValForNSOBool: function(val, valType) {
        val = valType == "boolean" ? +val : val;
        return val;
    },
    getValForNSObject: function(val, helper, helperVal) {
        val = (helper == helperVal) ? this.toPrimitive(val) : val;
        return val;
    },
    toPrimitive: function(obj, helper) {
        helper = typeof obj.valueOf();
        return (helper === "object") ? obj.valueOf().toString() : (helper == "string") ? obj.valueOf() : obj.valueOf();
    },
    getObjectRep: function(val) {
        return Object.prototype.toString.call(val).includes("Array") ? "[...]" : "{Object...}";
    },
    isUndefinedOrNull: function(type, val) {
        return (type === "undefined" || (type === "object" && val === null));
    },
    isNumberStringObjectCombination: function(xType, yType) {
        return (xType == "number" && (yType == "object" && yType != null)) || ((xType == "object" && xType != null) && yType == "number") || (xType == "string" && (yType == "object" && yType != null)) || ((xType == "object" && xType != null) && yType == "string");
    },
    isNumberStringCombination: function(xType, yType) {
        return ((xType === "number" && yType === "string") || (xType === "string" && yType === "number"));
    },
    isNumberStringObject_WithBooleanCombination: function(xType, yType) {
        return xType === "boolean" || yType === "boolean";
    },
    renderReferenceLookup: function(id, additionalId) {
        switch (id) {
            case 1000:
                console.log("Refer line numbers 1.A and B in AECA.", "reference");
                break;
            case 1001:
                console.log("Refer line numbers 1.C.i and ii in AECA.", "reference");
                break;
            case 1002:
                switch (additionalId) {
                    case "number":
                        console.log("Refer line numbers 1.C.iii ,iv ,v and vi in AECA.", "reference");
                        break;
                    case "string":
                        console.log("Refer line number 1.D in AECA.", "reference");
                        break;
                    case "boolean":
                        console.log("Refer line number 1.E in AECA.", "reference");
                        break;
                    case "object":
                        console.log("Refer line number 1.F in AECA.", "reference");
                        break;
                }
                break;
            case 1003:
                console.log("Refer line number 2 and 3 in AECA.", "reference");
                break;
            case 1004:
                console.log("Refer line number 4 and 5 in AECA.", "reference");
                break;
            case 1005:
                console.log("Refer line number 6 and 7 in AECA.", "reference");
                break;
            case 1006:
                console.log("Refer line number 8 and 9 in AECA.", "reference");
                break;
            case 1007:
                console.log("Refer line number 10 in AECA.", "reference");
                break;
        }
    },
    processAlgo: function(x, y, stepNumber, stringX, stringY, helper) {
        var xType = typeof x,
            yType = typeof y;
        xType == (xType == "function") ? "object" : xType;
        yType == (yType == "function") ? "object" : yType;
        console.log("CALL #" + stepNumber + "Arguments - LHS : " + stringX + " RHS : " + stringY + "", "steps");
        if (xType === yType) {
            if (this.isUndefinedOrNull(xType, x)) {
                console.log("Both LHS and RHS are '" + (x + "") + "'. Hence the given expression will always be evaluated to 'true'.", "explanation");
                this.renderReferenceLookup(1000);
                return;
            } else if (xType === "number") {
                if (x !== x || y !== y) {
                    console.log("Though LHS and RHS are of type number, " + ((x !== x) ? "LHS" : "RHS") + " is 'NaN'. Basically 'NaN' will be evaluated to false even it is compared with itself. So the given expression will yield 'false' always.", "explanation");
                    this.renderReferenceLookup(1001);
                    return;
                }
            }
            console.log("LHS and RHS are of same type '" + xType + "'. Additionally, both are having " + ((x === y) ? "same" : "different") + ((xType === "object") ? " References" : " values") + ". So the given expression will be evaluated to '" + (x === y).toString() + "'.", "explanation");
            this.renderReferenceLookup(1002, xType);
            return;
        } else if (this.isUndefinedOrNull(xType, x) && this.isUndefinedOrNull(yType, y)) {
            console.log("When 'undefined' and 'null' are compared the result will always be 'true'. In our case LHS resolves to '" + (x + "") + "' and RHS resolves to '" + (y + "") + "'. So the given expression will evalautes to 'true'", "explanation");
            this.renderReferenceLookup(1003);
            return;
        } else if (this.isNumberStringCombination(xType, yType)) {
            console.log("LHS is a '" + xType + "' and RHS is a '" + yType + "', Hence " + ((xType === "string") ? "LHS" : "RHS") + " will be converted to 'number' first.", "explanation");
            console.log(((xType === "string") ? "LHS" : "RHS") + " will be converted as number to form the expression (" + (x = +x, x) + " == " + (y = +y, y) + "). After that, algorithm will be called recursively by supplying the gained expression.", "explanation");
            this.renderReferenceLookup(1004);
            return this.processAlgo(x, y, ++stepNumber, x , y);
        } else if (this.isNumberStringObject_WithBooleanCombination(xType, yType)) {
            console.log("If either RHS or LHS is a boolean, then it has to be converted to number first.", "explanation");
            console.log("Here, " + ((xType == "boolean") ? "LHS" : "RHS") + " is boolean. So after translating it into a number the whole expression becomes like below,", "explanation");
            x = this.getValForNSOBool(x, xType);
            y = this.getValForNSOBool(y, yType);
            console.log(this.stringChecker(x) + " == " + this.stringChecker(y) + ". And here we need a recursive call to the algorithm, to evaluate the newly generated expression.", "explanation");
            this.renderReferenceLookup(1005);
            return this.processAlgo(x, y, ++stepNumber, this.stringChecker(x), this.stringChecker(y));
        } else if (this.isNumberStringObjectCombination(xType, yType)) {
            helper = (xType === "object") ? "RHS" : "LHS";
            console.log(helper + " is a " + ((xType === "object") ? yType : xType) + ". And its opponent is an object. So object has to be converted to its primitive form first before further evaluations.", "explanation");
            console.log("ToPrimitve(" + (helper == "RHS" ? "LHS" : "RHS") + ") will be called and the following expression will be framed,", "explanation");
            x = this.getValForNSObject(x, helper, "RHS");
            y = this.getValForNSObject(y, helper, "LHS");
            console.log(this.stringChecker(x) + " == " + this.stringChecker(y) + ". Next, the framed expression will be passed to a recursive call of the algorithm.", "explanation");
            this.renderReferenceLookup(1006);
            return this.processAlgo(x, y, ++stepNumber, this.stringChecker(x), this.stringChecker(y));
        } else {
            console.log("No condition match found in AECA! Hence the given expression will be evaluated as 'false'", "explanation")
            this.renderReferenceLookup(1007);
        }
    }
};

$(mainObject.init.bind(mainObject, true));
<commit_msg>ux changes major<commit_after>var mainObject = {
    elm: null,
    elm1: null,
    myDetails: null,
    equalsBtn: null,
    resultDisplayer: null,
    lhs: null,
    rhs: null,
    result: true,
    x: null,
    y: null,
    obj: null,
    computedStyle: null,
    incX: 1,
    incY: 1,
    inter: 0,
    init: function(eventBinding) {
        eventBinding = eventBinding || false;
        if (eventBinding) {
            this.elm = $(".innerBox").get(0);
            this.elm1 = $(".headerWrapper").get(0);
            this.myDetails = $(".myDetails");
            this.resultDisplayer = $(".resultDisplayer");
            this.rhs = $(".rhs");
            this.lhs = $(".lhs");
            this.equalsBtn = $(".componentButton.equals");
            this.bindEvents();
            window.console.log = (str, cls) => {
                this.setItInParagraph(str, cls);
            }
        }
        clearInterval(this.inter);
        this.inter = setInterval(this.doBounce.bind(this), 20);
    },
    bindEvents: function() {
        var _this = this;
        $(_this.elm).hover(function() {
            clearInterval(_this.inter);
            $(this).removeClass("animate").addClass("stopped");
            _this.myDetails.finish().slideDown("fast");
        }, function() {
            _this.init();
            $(this).removeClass("stopped").addClass("animate");
            _this.myDetails.finish().slideUp("fast");
        }).click(function() {
            window.open("https://www.facebook.com/profile.php?id=100007985747854", "_blank");
        });
        _this.equalsBtn.click(function() {
            var x = _this.lhs.val().trim(),
                y = _this.rhs.val().trim(),evalX,evalY;
            try {
				_this.setResultsArea();
                _this.result = eval("(" + x + ") == (" + y + ")");
				evalX = eval("(" + x + ")");
				evalY = eval("(" + y + ")");
                _this.processAlgo(evalX, evalY, 1, (typeof evalX == "object" && evalX !== null) ? _this.getObjectRep(evalX) : x, (typeof evalY == "object" && evalY !== null) ? _this.getObjectRep(evalY) : y);
				console.log("RESULT : " + _this.result.toString().toUpperCase(), _this.result.toString())
            } catch (e) {
                console.log(e);
            }
        });
        $(window).resize(function() {
            _this.obj = _this.elm1.getBoundingClientRect();
        }).resize().load(function() {
            setTimeout(function() {
                $("#disqus_thread").addClass("discussPartialDisplay");
            }, 2000);
        });
    },
    doBounce: function() {
        this.computedStyle = window.getComputedStyle(this.elm);
        this.x = parseInt(this.computedStyle.left);
        this.y = parseInt(this.computedStyle.top);
        if (this.x < 0 || (this.x + 20) > this.obj.width) this.incX = -this.incX;
        if (this.y < 0 || (this.y + 20) > this.obj.height) this.incY = -this.incY;
        this.elm.style.left = this.x + this.incX + "px";
        this.elm.style.top = this.y + this.incY + "px";
    },
    setResultsArea : function(){
	this.resultDisplayer.empty().removeClass("center");
    },
    setItInParagraph: function(str, cls) {
        return $("
").html(((cls == "explanation") ? "⇨ " : "") + str).appendTo(this.resultDisplayer);
    },
    stringChecker: function(val) {
        return typeof val == "string" ? "\"" + val + "\"" : typeof val == "object" ? this.getObjectRep(val) : val;
    },
    getValForNSOBool: function(val, valType) {
        val = valType == "boolean" ? +val : val;
        return val;
    },
    getValForNSObject: function(val, helper, helperVal) {
        val = (helper == helperVal) ? this.toPrimitive(val) : val;
        return val;
    },
    toPrimitive: function(obj, helper) {
        helper = typeof obj.valueOf();
        return (helper === "object") ? obj.valueOf().toString() : (helper == "string") ? obj.valueOf() : obj.valueOf();
    },
    getObjectRep: function(val) {
        return Object.prototype.toString.call(val).includes("Array") ? "[...]" : "{Object...}";
    },
    isUndefinedOrNull: function(type, val) {
        return (type === "undefined" || (type === "object" && val === null));
    },
    isNumberStringObjectCombination: function(xType, yType) {
        return (xType == "number" && (yType == "object" && y != null)) || ((xType == "object" && x != null) && yType == "number") || (xType == "string" && (yType == "object" && y != null)) || ((xType == "object" && x != null) && yType == "string");
    },
    isNumberStringCombination: function(xType, yType) {
        return ((xType === "number" && yType === "string") || (xType === "string" && yType === "number"));
    },
    isNumberStringObject_WithBooleanCombination: function(xType, yType) {
        return xType === "boolean" || yType === "boolean";
    },
    renderReferenceLookup: function(id, additionalId) {
        switch (id) {
            case 1000:
                console.log("Refer line numbers 1.A and B in AECA.", "reference");
                break;
            case 1001:
                console.log("Refer line numbers 1.C.i and ii in AECA.", "reference");
                break;
            case 1002:
                switch (additionalId) {
                    case "number":
                        console.log("Refer line numbers 1.C.iii ,iv ,v and vi in AECA.", "reference");
                        break;
                    case "string":
                        console.log("Refer line number 1.D in AECA.", "reference");
                        break;
                    case "boolean":
                        console.log("Refer line number 1.E in AECA.", "reference");
                        break;
                    case "object":
                        console.log("Refer line number 1.F in AECA.", "reference");
                        break;
                }
                break;
            case 1003:
                console.log("Refer line number 2 and 3 in AECA.", "reference");
                break;
            case 1004:
                console.log("Refer line number 4 and 5 in AECA.", "reference");
                break;
            case 1005:
                console.log("Refer line number 6 and 7 in AECA.", "reference");
                break;
            case 1006:
                console.log("Refer line number 8 and 9 in AECA.", "reference");
                break;
            case 1007:
                console.log("Refer line number 10 in AECA.", "reference");
                break;
        }
    },
    processAlgo: function(x, y, stepNumber, stringX, stringY, helper) {
        var xType = typeof x,
            yType = typeof y;
        xType == (xType == "function") ? "object" : xType;
        yType == (yType == "function") ? "object" : yType;
        console.log("CALL #" + stepNumber + "Arguments - LHS : " + stringX + " RHS : " + stringY + "", "steps");
        if (xType === yType) {
            if (this.isUndefinedOrNull(xType, x)) {
                console.log("Both LHS and RHS are '" + (x + "") + "'. Hence the given expression will always be evaluated to 'true'.", "explanation");
                this.renderReferenceLookup(1000);
                return;
            } else if (xType === "number") {
                if (x !== x || y !== y) {
                    console.log("Though LHS and RHS are of type number, " + ((x !== x) ? "LHS" : "RHS") + " is 'NaN'. Basically 'NaN' will be evaluated to false even it is compared with itself. So the given expression will yield 'false' always.", "explanation");
                    this.renderReferenceLookup(1001);
                    return;
                }
            }
            console.log("LHS and RHS are of same type '" + xType + "'. Additionally, both are having " + ((x === y) ? "same" : "different") + ((xType === "object") ? " References" : " values") + ". So the given expression will be evaluated to '" + (x === y).toString() + "'.", "explanation");
            this.renderReferenceLookup(1002, xType);
            return;
        } else if (this.isUndefinedOrNull(xType, x) && this.isUndefinedOrNull(yType, y)) {
            console.log("When 'undefined' and 'null' are compared the result will always be 'true'. In our case LHS resolves to '" + (x + "") + "' and RHS resolves to '" + (y + "") + "'. So the given expression will evalautes to 'true'", "explanation");
            this.renderReferenceLookup(1003);
            return;
        } else if (this.isNumberStringCombination(xType, yType)) {
            console.log("LHS is a '" + xType + "' and RHS is a '" + yType + "', Hence " + ((xType === "string") ? "LHS" : "RHS") + " will be converted to 'number' first.", "explanation");
            console.log(((xType === "string") ? "LHS" : "RHS") + " will be converted as number to form the expression (" + (x = +x, x) + " == " + (y = +y, y) + "). After that, algorithm will be called recursively by supplying the gained expression.", "explanation");
            this.renderReferenceLookup(1004);
            return this.processAlgo(x, y, ++stepNumber, x , y);
        } else if (this.isNumberStringObject_WithBooleanCombination(xType, yType)) {
            console.log("If either RHS or LHS is a boolean, then it has to be converted to number first.", "explanation");
            console.log("Here, " + ((xType == "boolean") ? "LHS" : "RHS") + " is boolean. So after translating it into a number the whole expression becomes like below,", "explanation");
            x = this.getValForNSOBool(x, xType);
            y = this.getValForNSOBool(y, yType);
            console.log(this.stringChecker(x) + " == " + this.stringChecker(y) + ". And here we need a recursive call to the algorithm, to evaluate the newly generated expression.", "explanation");
            this.renderReferenceLookup(1005);
            return this.processAlgo(x, y, ++stepNumber, this.stringChecker(x), this.stringChecker(y));
        } else if (this.isNumberStringObjectCombination(xType, yType, x , y)) {
            helper = (xType === "object") ? "RHS" : "LHS";
            console.log(helper + " is a " + ((xType === "object") ? yType : xType) + ". And its opponent is an object. So object has to be converted to its primitive form first before further evaluations.", "explanation");
            console.log("ToPrimitve(" + (helper == "RHS" ? "LHS" : "RHS") + ") will be called and the following expression will be framed,", "explanation");
            x = this.getValForNSObject(x, helper, "RHS");
            y = this.getValForNSObject(y, helper, "LHS");
            console.log(this.stringChecker(x) + " == " + this.stringChecker(y) + ". Next, the framed expression will be passed to a recursive call of the algorithm.", "explanation");
            this.renderReferenceLookup(1006);
            return this.processAlgo(x, y, ++stepNumber, this.stringChecker(x), this.stringChecker(y));
        } else {
            console.log("No condition match found in AECA! Hence the given expression will be evaluated as 'false'", "explanation")
            this.renderReferenceLookup(1007);
        }
    }
};

$(mainObject.init.bind(mainObject, true));
<|endoftext|>


<commit_before>var x = cnp();

function cnp(){
var currentNumber = 0;
  currentNumber = currentNumber +1;
  console.log(currentNumber);
  document.write(currentNumber);
  }
<commit_msg>Factory and Singleton mashup<commit_after>//FACTORY SETUP

function Car(options) { //FACTORY OBJECT METHOD TO CREATE A CAR OBJECT
	this.doors = options.doors || 4;
	this.state = options.state || "brand new";
	this.color = options.color || "silver";
}

function Truck(options) { //FACTORY OBJECT METHOD TO CREATE A TRUCK OBJECT
	this.state = options.state || "used";
	this.wheelSize = options.wheelSize || "large";
	this.color = options.color || "blue";
}

function Boat(options) { //FACTORY OBJECT METHOD TO CREATE A BOAT OBJECT
	this.engine = options.engine || "honda";
	this.state = options.state || "brand new";
	this.color = options.color || "white";
}

function VehicleFactory() {} //CREATING THE EMPTY CLASS VEHICLEFACTORY
VehicleFactory.prototype.vehicleClass = Car; //PROTOTYPING THE VEHICLECLASS ATRIBUTE OF THE VEHICLEFACTORY CLASS
VehicleFactory.prototype.createVehicle = function(options) { //PROTOTYPING THE CREATEVEHICLE ATRIBUTE OF THE VEHICLEFACTORY CLASS TO A FUNCTION THAT RETURN A NEW OBJECT
	if(options.vehicleType === "car") {
		this.vehicleClass = Car;
	} else if(options.vehicleType === "truck") {
		this.vehicleClass = Truck;
	} else {
		this.vehicleClass = Boat;
	}

	return new this.vehicleClass(options);

};

//SINGLETON IMPLEMENTATION
var instance; //GLOBAL VARIABLE USED TO TRACK INSTANCE
var VehicleSingleton = function() {

		function init() { //FUNCTION USED TO INITIALIZE AN INSTANCE OF THE VEHICLE FACTORY
			return new VehicleFactory();

		}

		if(typeof instance === "undefined") { //CHECKING IF AN OBJECT OF TYPE VEHICLE FACTORY HAS BEEN INSTANTIATED
			instance = init(); //CALLING INIT() IF NO INSTANCE IS DETECTED
		}

		return instance; //RETURNING EITHER THE NEW OR EXISTING INSTANCE
	}
var outputFactory = VehicleSingleton(); //CREATING A NEW VEHICLEFACTORY OBJECT - USED FOR VALIDATION OF SINGLETON
var outputFactory2 = VehicleSingleton(); //USED FOR VALIDATION OF SINGLETON
var car = outputFactory.createVehicle({
	vehicleType: "car",
	color: "yellow",
	doors: 6
});

var boat = outputFactory.createVehicle({
	vehicleType: "boat",
	engine: "kawasaki",
	state: "used"
});

console.log(car instanceof Car);

console.log(boat instanceof Boat);

console.log(outputFactory === outputFactory2);

console.log(car);
console.log(boat);<|endoftext|>


<commit_before>var canvas = document.getElementById('background');
var ctx = canvas.getContext('2d');
ctx.canvas.width  = window.innerWidth;
ctx.canvas.height = window.innerHeight;

function DrawableObject(src) {
	this.image = new Image;
	this.image.src = src;
};
DrawableObject.prototype = new Image;
DrawableObject.prototype.draw = function(ctx, x, y, w, h){
	this.image.onload = function() {
		ctx.save();
		ctx.drawImage(this.image, x, y, w, h);
		ctx.restore();
	}.bind(this);
}
DrawableObject.prototype.paint = function(ctx, x, y, w, h){
	this.image.onload = function() {
		ctx.save();
		ctx.drawImage(this.image, x, y, w, h);
		var d = ctx.getImageData(x, y, w, h);
		for(var i=0; i<d.data.length; i+=4) {
			if (d.data[i] === 255 && d.data[i+1] === 255 && d.data[i+2] === 255) {
				d.data[i+3] = 0;
			}
		}
		ctx.putImageData(d, x, y, 0, 0, w, h);
		ctx.restore();
	}.bind(this);
}

var h = new DrawableObject('img/hunter.png');
var bg = new DrawableObject('img/bg.png');

bg.draw(ctx, 0, 0, ctx.canvas.width, ctx.canvas.height);
canvas = document.getElementById('player');
ctx = canvas.getContext('2d');
ctx.canvas.width  = window.innerWidth;
ctx.canvas.height = window.innerHeight;
h.paint(ctx, 200, window.innerHeight - 180, 48, 64);<commit_msg>loop background<commit_after>var canvas = document.getElementById('background');
var ctx = canvas.getContext('2d');
ctx.canvas.width  = window.innerWidth;
ctx.canvas.height = window.innerHeight;

function DrawableObject(src) {
	this.image = new Image;
	this.image.src = src;
};
DrawableObject.prototype = new Image;
DrawableObject.prototype.draw = function(ctx, x, y, w, h){
	this.image.onload = function() {
		ctx.save();
		ctx.drawImage(this.image, x, y, w, h);
		ctx.restore();
	}.bind(this);
}
DrawableObject.prototype.paint = function(ctx, x, y, w, h){
	this.image.onload = function() {
		ctx.save();
		ctx.drawImage(this.image, x, y, w, h);
		var d = ctx.getImageData(x, y, w, h);
		for(var i=0; i<d.data.length; i+=4) {
			if (d.data[i] === 255 && d.data[i+1] === 255 && d.data[i+2] === 255) {
				d.data[i+3] = 0;
			}
		}
		ctx.putImageData(d, x, y, 0, 0, w, h);
		ctx.restore();
	}.bind(this);
};
DrawableObject.prototype.loop = function(ctx, x, y, w, h, vx, vy){
	ctx.save();
	var i=0;
	var a = setInterval( function() {
		ctx.drawImage(this.image, x + vx*i, y + vy*i, w, h);
		if(Math.abs(vx*i) > w) {
			i = 0;
		} else {
			i += 2;
		}
	}.bind(this), 33);
	ctx.restore();
};

var h = new DrawableObject('img/hunter.png');
var bg = new DrawableObject('img/bg.png');

bg.loop(ctx, 0, 0, ctx.canvas.width, ctx.canvas.height, -1, 0);
bg.loop(ctx, ctx.canvas.width, 0, ctx.canvas.width, ctx.canvas.height, -1, 0);
canvas = document.getElementById('player');
ctx = canvas.getContext('2d');
ctx.canvas.width  = window.innerWidth;
ctx.canvas.height = window.innerHeight;
h.paint(ctx, 200, window.innerHeight - 180, 48, 64);<|endoftext|>


<commit_before>/*
* mvcArea
* author: ronglin
* create date: 2014.6.26
*/

'use strict';

var fs = require('fs'),
    path = require('path'),
    events = require('events'),
    utils = require('./utilities'),
    caching = require('./caching');

var CONST_Areas = 'areas',
    CONST_Ctrls = 'ctrls',
    CONST_Events = 'areaEvents.js';

var mvcArea = function(set) {
    utils.extend(this, set);
    this.controllers = {};
    this.extensions = {};
    this.routes = {};
};

mvcArea.isArea = true;
mvcArea.prototype = {

    name: null, path: null,

    controllers: null, routes: null, extensions:null,

    constructor: mvcArea,

    mapRoute: function(routeExp, defaultRoute) {
        var values = utils.isObject(defaultRoute) ? defaultRoute : {};
        this.routes[routeExp.toLowerCase()] = {
            expression: routeExp,
            defaultRoute: values
        };
    },

    removeRoute: function(routeExp) {
        return (delete this.routes[routeExp.toLowerCase()]);
    },

    clearRoutes: function() {
        this.routes = {};
    },

    loadController: function(filePath) {
        if (fs.statSync(filePath).isFile()) {
            var ctrl = require(filePath);
            if (ctrl && ctrl.__proto__.constructor.isController === true) {
                if (!ctrl.name()) {
                    var extName = path.extname(filePath);
                    ctrl.name(path.basename(filePath, extName));
                }
                ctrl.path(filePath);
                this.controllers[ctrl.name().toLowerCase()] = ctrl;
            }
        }
    },

    unloadController: function(filePath) {
        var extName = path.extname(filePath);
        var ctrlName = path.basename(filePath, extName);
        return (delete this.controllers[ctrlName.toLowerCase()]);
    },

    clearControllers: function() {
        this.controllers = {};
    },

    loadExtension: function(filePath) {
        if (fs.existsSync(filePath) && fs.statSync(filePath).isFile()) {
            this.extensions[filePath.toLowerCase()] = require(filePath);
        }
    },

    unloadExtension: function(filePath) {
        return (delete this.extensions[filePath.toLowerCase()]);
    },

    clearExtensions: function() {
        this.extensions = {};
    },

    fireExtension: function(funcName) {
        var self = this;
        utils.each(this.extensions, function(k, ext) {
            if (ext && utils.isFunction(ext[funcName])) {
                ext[funcName](self);
            }
        });
    }
};

module.exports = {

    _areasPath: utils.absPath(CONST_Areas),

    _areas: caching.region('mvc-areas-cache'),

    rootAreaName: utils.unique(8).toUpperCase(),

    events: new events.EventEmitter(),

    all: function() {
        return this._areas.all();
    },

    get: function(areaName) {
        return this._areas.get(areaName);
    },

    unload: function(areaName) {
        var area = this.get(areaName);
        if (area) {
            area.fireExtension('onUnload');
            this.events.emit('unload', area);
            return this._areas.remove(areaName);
        }
    },

    register: function(areaName, areaRoute, defaultRoute) {
        var areaDirectory = areaName;
        if (areaName === this.rootAreaName) { areaDirectory = path.sep + '..'; }
        var area, areaPath = path.normalize(path.join(this._areasPath, areaDirectory));
        if (fs.existsSync(areaPath) && fs.statSync(areaPath).isDirectory()) {
            // area obj
            area = new mvcArea({
                name: areaName,
                path: areaPath
            });
            // map route
            area.mapRoute(areaRoute, defaultRoute);
            // load default extension
            area.loadExtension(path.join(area.path, CONST_Events));
            // read 'areas/account/ctrls'
            var ctrlsPath = path.join(area.path, CONST_Ctrls);
            if (fs.existsSync(ctrlsPath) && fs.statSync(ctrlsPath).isDirectory()) {
                // read 'areas/account/ctrls/logon.js'
                var ctrlFiles = fs.readdirSync(ctrlsPath);
                utils.each(ctrlFiles, function(i, ctrlFileName) {
                    area.loadController(path.join(ctrlsPath, ctrlFileName));
                });
            }
        }
        //
        if (area) {
            area.fireExtension('onRegister');
            this.events.emit('register', area);
            this._areas.set(area.name, area);
        }
        // ret
        return area;
    },

    registerAll: function(app) {
        this.register(
            (this.rootAreaName),
            ('/:controller/:action'),
            ({ controller: 'home', action: 'index' })
        );
        var self = this, areasDirs = fs.readdirSync(this._areasPath);
        utils.each(areasDirs, function(i, areaName) {
            self.register(
                (areaName),
                ('/' + areaName + '/:controller/:action'),
                ({ controller: 'home', action: 'index' })
            );
        });
        return this.all();
    }
};
<commit_msg>support multi controllers in one controller file<commit_after>/*
* mvcArea
* author: ronglin
* create date: 2014.6.26
*/

'use strict';

var fs = require('fs'),
    path = require('path'),
    events = require('events'),
    utils = require('./utilities'),
    caching = require('./caching');

var CONST_Areas = 'areas',
    CONST_Ctrls = 'ctrls',
    CONST_Events = 'areaEvents.js';

var mvcArea = function(set) {
    utils.extend(this, set);
    this.controllers = {};
    this.extensions = {};
    this.routes = {};
};

mvcArea.isArea = true;
mvcArea.prototype = {

    name: null, path: null,

    controllers: null, routes: null, extensions:null,

    constructor: mvcArea,

    mapRoute: function(routeExp, defaultRoute) {
        var values = utils.isObject(defaultRoute) ? defaultRoute : {};
        this.routes[routeExp.toLowerCase()] = {
            expression: routeExp,
            defaultRoute: values
        };
    },

    removeRoute: function(routeExp) {
        return (delete this.routes[routeExp.toLowerCase()]);
    },

    clearRoutes: function() {
        this.routes = {};
    },

    loadController: function(filePath) {
        if (fs.statSync(filePath).isFile()) {
            var self = this, coreLoad = function(ctrl) {
                if (ctrl && ctrl.__proto__.constructor.isController === true) {
                    if (!ctrl.name()) {
                        var extName = path.extname(filePath);
                        ctrl.name(path.basename(filePath, extName));
                    }
                    ctrl.path(filePath);
                    self.controllers[ctrl.name().toLowerCase()] = ctrl;
                    return true;
                }
            };
            var module = require(filePath);
            if (module && coreLoad(module) !== true) {
                utils.each(module, function() {
                    coreLoad(this);
                });
            }
        }
    },

    unloadController: function(filePath) {
        var extName = path.extname(filePath);
        var ctrlName = path.basename(filePath, extName);
        return (delete this.controllers[ctrlName.toLowerCase()]);
    },

    clearControllers: function() {
        this.controllers = {};
    },

    loadExtension: function(filePath) {
        if (fs.existsSync(filePath) && fs.statSync(filePath).isFile()) {
            this.extensions[filePath.toLowerCase()] = require(filePath);
        }
    },

    unloadExtension: function(filePath) {
        return (delete this.extensions[filePath.toLowerCase()]);
    },

    clearExtensions: function() {
        this.extensions = {};
    },

    fireExtension: function(funcName) {
        var self = this;
        utils.each(this.extensions, function(k, ext) {
            if (ext && utils.isFunction(ext[funcName])) {
                ext[funcName](self);
            }
        });
    }
};

module.exports = {

    _areasPath: utils.absPath(CONST_Areas),

    _areas: caching.region('mvc-areas-cache'),

    rootAreaName: utils.unique(8).toUpperCase(),

    events: new events.EventEmitter(),

    all: function() {
        return this._areas.all();
    },

    get: function(areaName) {
        return this._areas.get(areaName);
    },

    unload: function(areaName) {
        var area = this.get(areaName);
        if (area) {
            area.fireExtension('onUnload');
            this.events.emit('unload', area);
            return this._areas.remove(areaName);
        }
    },

    register: function(areaName, areaRoute, defaultRoute) {
        var areaDirectory = areaName;
        if (areaName === this.rootAreaName) { areaDirectory = path.sep + '..'; }
        var area, areaPath = path.normalize(path.join(this._areasPath, areaDirectory));
        if (fs.existsSync(areaPath) && fs.statSync(areaPath).isDirectory()) {
            // area obj
            area = new mvcArea({
                name: areaName,
                path: areaPath
            });
            // map route
            area.mapRoute(areaRoute, defaultRoute);
            // load default extension
            area.loadExtension(path.join(area.path, CONST_Events));
            // read 'areas/account/ctrls'
            var ctrlsPath = path.join(area.path, CONST_Ctrls);
            if (fs.existsSync(ctrlsPath) && fs.statSync(ctrlsPath).isDirectory()) {
                // read 'areas/account/ctrls/logon.js'
                var ctrlFiles = fs.readdirSync(ctrlsPath);
                utils.each(ctrlFiles, function(i, ctrlFileName) {
                    area.loadController(path.join(ctrlsPath, ctrlFileName));
                });
            }
        }
        //
        if (area) {
            area.fireExtension('onRegister');
            this.events.emit('register', area);
            this._areas.set(area.name, area);
        }
        // ret
        return area;
    },

    registerAll: function(app) {
        this.register(
            (this.rootAreaName),
            ('/:controller/:action'),
            ({ controller: 'home', action: 'index' })
        );
        var self = this, areasDirs = fs.readdirSync(this._areasPath);
        utils.each(areasDirs, function(i, areaName) {
            self.register(
                (areaName),
                ('/' + areaName + '/:controller/:action'),
                ({ controller: 'home', action: 'index' })
            );
        });
        return this.all();
    }
};
<|endoftext|>


<commit_before>var News = {
  newsMinLimit: 1,
  newsMaxLimit: 15,
  backupImage: 'img/logo-sponsor-placeholder.png',
  msgNewsLimit: 'Nyhetsantall må være et tall mellom '+this.newsMinLimit+' og '+this.newsMaxLimit,
  msgConnectionError: 'Frakoblet fra feed: ',
  msgUnsupportedFeed: 'Feeden støttes ikke',
  msgCallbackRequired: 'Callback er påkrevd, legg resultatene inn i DOMen',

  debug: 1,

  feeds: {
    // Linjeforeninger
    'berg': 'http://bergstud.no/feed/',
    'delta': 'http://org.ntnu.no/delta/wp/?feed=rss2',
    'emil': 'http://emilweb.no/feed/',
    'online': 'https://online.ntnu.no/feeds/news/',
    'nabla': 'http://nabla.no/feed/',
    'spanskrøret': 'http://spanskroret.no/feed/',
    // Medier
    'dusken': 'http://dusken.no/feed/',
    'universitetsavisa': 'http://www.universitetsavisa.no/?service=rss',
    // Store studentorganisasjoner
    'samfundet': 'http://www.samfundet.no/arrangement/rss',
    // Studentdemokrati
    'studenttinget': 'http://www.studenttinget.no/feed/',
    'velferdstinget': 'http://www.velferdstinget.no/feed/rss/',
    // NTNU
    'ntnu': 'https://www.retriever-info.com/feed/2002900/generell_arkiv166/index.xml',
    'rektoratet': 'http://www.ntnu.no/blogger/rektoratet/feed/',
  },

  // Get is called by background.html periodically, with News.unreadCount as
  // callback. Fetchfeed is also called by popup.html when requested, but
  // without the callback as we already know the amount of unread posts.
  get: function(feedName, limit, callback) {
    if (this.feeds[feedName] === undefined) {
      if (this.debug) console.log('ERROR:', this.msgUnsupportedFeed);
      callback(this.msgUnsupportedFeed);
      return;
    }
    if (isNaN(limit) || (limit < 1 && 20 < limit)) {
      if (this.debug) console.log('ERROR:', this.msgNewsLimit);
      callback(this.msgNewsLimit);
      return;
    }
    if (callback == undefined) {
      console.log('ERROR:', this.msgCallbackRequired);
      callback(this.msgCallbackRequired);
      return;
    }

    feedName = feedName.toLowerCase();
    var rssUrl = this.feeds[feedName];

    var self = this;
    $.ajax({
      url: rssUrl, // permission to use url granted in manifest.json
      dataType: 'xml',
      success: function(xml) {
        // ls.lastResponseData = xmlstring;
        self.parseFeed(xml, feedName, callback);
      },
      error: function(jqXHR, text, err) {
        if (self.debug) console.log('ERROR:', self.msgConnectionError, feedName);
        callback(self.msgConnectionError);
      },
    });
  },

  parseFeed: function(xml, feedName, callback) {
    var items = [];
    var self = this;
    $(xml).find('item').each( function() {
      var item = self.parseItem(this, feedName);
      items.push(item);
    });
    callback(items);
  },

  // NOT DONE YET ///////////////////////////////////////////////////////////////////
  // todo: this function only handles the online-feed, make sure it handles all feeds
  parseItem: function(item, feedName) {
    var post = {};
    post.title = $(item).find("title").text();
    post.link = $(item).find("link").text();
    post.description = $(item).find("description").text();
    post.creator = $(item).find("dc:creator").text();

    post.altLink = null;

    post.date = $(item).find("pubDate").text().substr(5, 11); /////////////////////

    post.image = this.backupImage; ////////////////////////////////////////////////

    // Shorten 'bedriftspresentasjon' to 'bedpres'
    post.title = post.title.replace(/edrift(s)?presentasjon/gi, 'edpres');
    post.description = post.description.replace(/edrift(s)?presentasjon/gi, 'edpres');

    // Check for alternative links in description
    var altLink = this.checkForAltLink(post.description);

    // Remove excessive whitespace...
    if (post.description.match(/<\w+>|<\/\w+>/g) !== null) { // Check if string contains markup
      // ...and ludicrous formatting (HTML)
      post.description = $.trim($(post.description).text());
    }
    else {
      post.description = post.description.trim();
    }

    // In case browser does not grok tags with colons, stupid browser
    if (post.creator == '') {
      var tag = ("dc\\:creator").replace( /.*(\:)(.*)/, "$2" );
      $(item).find(tag).each(function(){
        post.creator = $(this).text().trim();
      });
    }
    // Didn't find a creator, set the feedname as creator
    if (post.creator.length == 0) {
      post.creator = feedName.capitalize();
    }
    // Abbreviate long creator names
    post.creator = this.abbreviateName(post.creator);

    // title + description must not exceed 5 lines
    var line = 50; // conservative estimation
    var desclength = line * 3;
    // double line titles will shorten the description by 1 line
    if (line <= post.title.length)
      desclength -= line;
    // shorten description according to desclength
    if (desclength < post.description.length)
      post.description = post.description.substr(0, desclength) + '...';

    return post;
  },

  // NOT DONE YET ///////////////////////////////////////////////////////////////////
  // todo: this function only handles the online-feed, make sure it handles all feeds
  unreadCount: function(xmlstring) {

    return; //

    var unread_count = 0;

    // Parse the feed
    var xmldoc = $.parseXML(xmlstring);
    $xml = $(xmldoc);
    var items = $xml.find("item");
    var idList = []; // New || Updated

    // Count feed items
    items.each( function(index, element) {

      var id = $(element).find("guid").text().split('/')[4];

      // Counting...
      if (id != localStorage.mostRecentRead) {
        unread_count++;
        idList.push(id); // New || Updated
        // Send a desktop notification about the first unread element
        if (unread_count == 1) {
          if (localStorage.lastNotified != id) {
            this.showNotification(element);
          }
          localStorage.mostRecentUnread = id;
        }
      }
      // All counted :)
      else {
        if (unread_count == 0) {
          if (this.debug) console.log('no new posts');
          Browser.setBadgeText('');
        }
        else if (unread_count >= this.maxNewsAmount) {
          if (this.debug) console.log(this.maxNewsAmount + '+ unread posts');
          Browser.setBadgeText(this.maxNewsAmount + '+');
        }
        else {
          if (this.debug) console.log('1-' + (this.maxNewsAmount - 1) + ' unread posts');
          Browser.setBadgeText(String(unread_count));
        }
        localStorage.unreadCount = unread_count;
        localStorage.mostRecentIdList = JSON.stringify(idList); // New || Updated
        return false;
      }

      // Stop counting if unread number is greater than 9
      if (index > (this.maxNewsAmount - 1)) { // Remember index is counting 0
        if (this.debug) console.log(this.maxNewsAmount + '+ unread posts (stopped counting)');
        Browser.setBadgeText(this.maxNewsAmount + '+');
        localStorage.unreadCount = this.maxNewsAmount;
        // New or updated?
        localStorage.mostRecentIdList = JSON.stringify(idList); // New || Updated
        return false;
      }
    });
  },

  showNotification: function(item) {
    if (localStorage.showNotifications == 'true') {
      var post = this.parseItem(item);
      // Remember this
      localStorage.lastNotified = post.link;
      // Get content
      localStorage.notificationTitle = post.title;
      localStorage.notificationLink = post.link;
      localStorage.notificationDescription = post.description;
      localStorage.notificationCreator = post.creator;
      // Show desktop notification
      Browser.createNotification('notification.html');
    }
  },

  checkForAltLink: function(description) {
    // For simplicity we'll use the first and best link we can find
    var altLink = description.match(/\(?\b(?:(http|https|ftp):\/\/)?((?:www.)?[a-zA-Z0-9\-\.]+[\.][a-zA-Z]{2,4})(?::(\d*))?(?=[\s\/,\.\)])([\/]{1}[^\s\?]*[\/]{1})*(?:\/?([^\s\n\?\[\]\{\}\#]*(?:(?=\.)){1}|[^\s\n\?\[\]\{\}\.\#]*)?([\.]{1}[^\s\?\#]*)?)?(?:\?{1}([^\s\n\#\[\]\(\)]*))?([\#][^\s\n]*)?\)?/);
    // Regex credz: http://someweblog.com/url-regular-expression-javascript-link-shortener/
    if (altLink != null) {
      if (typeof altLink[0] != 'undefined') {
        return altLink;
      }
    }
    return null;
  },

  abbreviateName: function(oldName) {
    if (oldName != undefined) {
      // Abbreviate middle names if name is long
      if (18 < oldName.length) {
        var pieces = oldName.split(' ');
        if (2 < pieces.length) {
          // Add first name
          var newName = pieces[0];
          // Add one letter per middle name
          for (var i = 1; i < pieces.length - 1; i++)
            newName += ' ' + pieces[i].charAt(0).toUpperCase() + '.';
          // Add last name
          newName += ' ' + pieces[pieces.length-1];
          return newName;
        }
      }
    }
    else {
      if (this.debug) console.log('ERROR: cannot abbreviate an undefined name');
    }
    return oldName;
  },

  // Organization specific functions

  online_getImage: function(link, callback) {
    var id = link.split('/')[4]; // id is stored in the link
    var image = 'undefined';
    var api = 'https://online.ntnu.no/api/f5be90e5ec1d2d454ae9/news_image_by_id/';
    $.getJSON(api + id, function(json) {
      if (json['online_news_image']) {
        image = json['online_news_image']['0']['image'];
        callback(link, image);
      }
      else {
        image = this.backupImage;
        if (this.debug) console.log('ERROR: no image exists for id: ' + id);
        callback(link, image);
      }
    })
    .error(function() {
      image = this.backupImage;
      if (this.debug) console.log('ERROR: couldn\'t connect API to get image links, returning default image');
      callback(link, image);
    });
  },

}

/*
felles:
    feeds
    get
    parseFeed
    parseItem
    showNotification
    unreadCount
    fletting

hver for seg:
    // last read
    keep list of recent posts
    get post image
*/

<commit_msg>news: respecting the news limit<commit_after>var News = {
  newsMinLimit: 1,
  newsMaxLimit: 15,
  backupImage: 'img/logo-sponsor-placeholder.png',
  msgNewsLimit: 'Nyhetsantall må være et tall mellom '+this.newsMinLimit+' og '+this.newsMaxLimit,
  msgConnectionError: 'Frakoblet fra feed: ',
  msgUnsupportedFeed: 'Feeden støttes ikke',
  msgCallbackRequired: 'Callback er påkrevd, legg resultatene inn i DOMen',

  debug: 1,

  feeds: {
    // Linjeforeninger
    'berg': 'http://bergstud.no/feed/',
    'delta': 'http://org.ntnu.no/delta/wp/?feed=rss2',
    'emil': 'http://emilweb.no/feed/',
    'online': 'https://online.ntnu.no/feeds/news/',
    'nabla': 'http://nabla.no/feed/',
    'spanskrøret': 'http://spanskroret.no/feed/',
    // Medier
    'dusken': 'http://dusken.no/feed/',
    'universitetsavisa': 'http://www.universitetsavisa.no/?service=rss',
    // Store studentorganisasjoner
    'samfundet': 'http://www.samfundet.no/arrangement/rss',
    // Studentdemokrati
    'studenttinget': 'http://www.studenttinget.no/feed/',
    'velferdstinget': 'http://www.velferdstinget.no/feed/rss/',
    // NTNU
    'ntnu': 'https://www.retriever-info.com/feed/2002900/generell_arkiv166/index.xml',
    'rektoratet': 'http://www.ntnu.no/blogger/rektoratet/feed/',
  },

  // Get is called by background.html periodically, with News.unreadCount as
  // callback. Fetchfeed is also called by popup.html when requested, but
  // without the callback as we already know the amount of unread posts.
  get: function(feedName, limit, callback) {
    if (this.feeds[feedName] === undefined) {
      if (this.debug) console.log('ERROR:', this.msgUnsupportedFeed);
      callback(this.msgUnsupportedFeed);
      return;
    }
    if (isNaN(limit) || (limit < 1 && 20 < limit)) {
      if (this.debug) console.log('ERROR:', this.msgNewsLimit);
      callback(this.msgNewsLimit);
      return;
    }
    if (callback == undefined) {
      console.log('ERROR:', this.msgCallbackRequired);
      callback(this.msgCallbackRequired);
      return;
    }

    feedName = feedName.toLowerCase();
    var rssUrl = this.feeds[feedName];

    var self = this;
    $.ajax({
      url: rssUrl, // permission to use url granted in manifest.json
      dataType: 'xml',
      success: function(xml) {
        // ls.lastResponseData = xmlstring;
        self.parseFeed(xml, feedName, limit, callback);
      },
      error: function(jqXHR, text, err) {
        if (self.debug) console.log('ERROR:', self.msgConnectionError, feedName);
        callback(self.msgConnectionError);
      },
    });
  },

  parseFeed: function(xml, feedName, limit, callback) {
    var items = [];
    var self = this;
    var count = 0;
    $(xml).find('item').each( function() {
      if (count++ < limit) {
        var item = self.parseItem(this, feedName);
        items.push(item);
      }
    });
    callback(items);
  },

  // NOT DONE YET ///////////////////////////////////////////////////////////////////
  // todo: this function only handles the online-feed, make sure it handles all feeds
  parseItem: function(item, feedName) {
    var post = {};
    post.title = $(item).find("title").text();
    post.link = $(item).find("link").text();
    post.description = $(item).find("description").text();
    post.creator = $(item).find("dc:creator").text();

    post.altLink = null;

    post.date = $(item).find("pubDate").text().substr(5, 11); /////////////////////

    post.image = this.backupImage; ////////////////////////////////////////////////

    // Shorten 'bedriftspresentasjon' to 'bedpres'
    post.title = post.title.replace(/edrift(s)?presentasjon/gi, 'edpres');
    post.description = post.description.replace(/edrift(s)?presentasjon/gi, 'edpres');

    // Check for alternative links in description
    var altLink = this.checkForAltLink(post.description);

    // Remove excessive whitespace...
    if (post.description.match(/<\w+>|<\/\w+>/g) !== null) { // Check if string contains markup
      // ...and ludicrous formatting (HTML)
      post.description = $.trim($(post.description).text());
    }
    else {
      post.description = post.description.trim();
    }

    // In case browser does not grok tags with colons, stupid browser
    if (post.creator == '') {
      var tag = ("dc\\:creator").replace( /.*(\:)(.*)/, "$2" );
      $(item).find(tag).each(function(){
        post.creator = $(this).text().trim();
      });
    }
    // Didn't find a creator, set the feedname as creator
    if (post.creator.length == 0) {
      post.creator = feedName.capitalize();
    }
    // Abbreviate long creator names
    post.creator = this.abbreviateName(post.creator);

    // title + description must not exceed 5 lines
    var line = 50; // conservative estimation
    var desclength = line * 3;
    // double line titles will shorten the description by 1 line
    if (line <= post.title.length)
      desclength -= line;
    // shorten description according to desclength
    if (desclength < post.description.length)
      post.description = post.description.substr(0, desclength) + '...';

    return post;
  },

  // NOT DONE YET ///////////////////////////////////////////////////////////////////
  // todo: this function only handles the online-feed, make sure it handles all feeds
  unreadCount: function(xmlstring) {

    return; //

    var unread_count = 0;

    // Parse the feed
    var xmldoc = $.parseXML(xmlstring);
    $xml = $(xmldoc);
    var items = $xml.find("item");
    var idList = []; // New || Updated

    // Count feed items
    items.each( function(index, element) {

      var id = $(element).find("guid").text().split('/')[4];

      // Counting...
      if (id != localStorage.mostRecentRead) {
        unread_count++;
        idList.push(id); // New || Updated
        // Send a desktop notification about the first unread element
        if (unread_count == 1) {
          if (localStorage.lastNotified != id) {
            this.showNotification(element);
          }
          localStorage.mostRecentUnread = id;
        }
      }
      // All counted :)
      else {
        if (unread_count == 0) {
          if (this.debug) console.log('no new posts');
          Browser.setBadgeText('');
        }
        else if (unread_count >= this.maxNewsAmount) {
          if (this.debug) console.log(this.maxNewsAmount + '+ unread posts');
          Browser.setBadgeText(this.maxNewsAmount + '+');
        }
        else {
          if (this.debug) console.log('1-' + (this.maxNewsAmount - 1) + ' unread posts');
          Browser.setBadgeText(String(unread_count));
        }
        localStorage.unreadCount = unread_count;
        localStorage.mostRecentIdList = JSON.stringify(idList); // New || Updated
        return false;
      }

      // Stop counting if unread number is greater than 9
      if (index > (this.maxNewsAmount - 1)) { // Remember index is counting 0
        if (this.debug) console.log(this.maxNewsAmount + '+ unread posts (stopped counting)');
        Browser.setBadgeText(this.maxNewsAmount + '+');
        localStorage.unreadCount = this.maxNewsAmount;
        // New or updated?
        localStorage.mostRecentIdList = JSON.stringify(idList); // New || Updated
        return false;
      }
    });
  },

  showNotification: function(item) {
    if (localStorage.showNotifications == 'true') {
      var post = this.parseItem(item);
      // Remember this
      localStorage.lastNotified = post.link;
      // Get content
      localStorage.notificationTitle = post.title;
      localStorage.notificationLink = post.link;
      localStorage.notificationDescription = post.description;
      localStorage.notificationCreator = post.creator;
      // Show desktop notification
      Browser.createNotification('notification.html');
    }
  },

  checkForAltLink: function(description) {
    // For simplicity we'll use the first and best link we can find
    var altLink = description.match(/\(?\b(?:(http|https|ftp):\/\/)?((?:www.)?[a-zA-Z0-9\-\.]+[\.][a-zA-Z]{2,4})(?::(\d*))?(?=[\s\/,\.\)])([\/]{1}[^\s\?]*[\/]{1})*(?:\/?([^\s\n\?\[\]\{\}\#]*(?:(?=\.)){1}|[^\s\n\?\[\]\{\}\.\#]*)?([\.]{1}[^\s\?\#]*)?)?(?:\?{1}([^\s\n\#\[\]\(\)]*))?([\#][^\s\n]*)?\)?/);
    console.log('alt link found:::::', altLink)
    // Regex credz: http://someweblog.com/url-regular-expression-javascript-link-shortener/
    if (altLink != null) {
      if (typeof altLink[0] != 'undefined') {
        return altLink;
      }
    }
    return null;
  },

  abbreviateName: function(oldName) {
    if (oldName != undefined) {
      // Abbreviate middle names if name is long
      if (18 < oldName.length) {
        var pieces = oldName.split(' ');
        if (2 < pieces.length) {
          // Add first name
          var newName = pieces[0];
          // Add one letter per middle name
          for (var i = 1; i < pieces.length - 1; i++)
            newName += ' ' + pieces[i].charAt(0).toUpperCase() + '.';
          // Add last name
          newName += ' ' + pieces[pieces.length-1];
          return newName;
        }
      }
    }
    else {
      if (this.debug) console.log('ERROR: cannot abbreviate an undefined name');
    }
    return oldName;
  },

  // Organization specific functions

  online_getImage: function(link, callback) {
    var id = link.split('/')[4]; // id is stored in the link
    var image = 'undefined';
    var api = 'https://online.ntnu.no/api/f5be90e5ec1d2d454ae9/news_image_by_id/';
    $.getJSON(api + id, function(json) {
      if (json['online_news_image']) {
        image = json['online_news_image']['0']['image'];
        callback(link, image);
      }
      else {
        image = this.backupImage;
        if (this.debug) console.log('ERROR: no image exists for id: ' + id);
        callback(link, image);
      }
    })
    .error(function() {
      image = this.backupImage;
      if (this.debug) console.log('ERROR: couldn\'t connect API to get image links, returning default image');
      callback(link, image);
    });
  },

}

/*
felles:
    feeds
    get
    parseFeed
    parseItem
    showNotification
    unreadCount
    fletting

hver for seg:
    // last read
    keep list of recent posts
    get post image
*/

<|endoftext|>


<commit_before>var fs            = require('fs'),
    url           = require('url'),
    merge         = require('utils-merge'),
    _             = require('underscore'),
    compiledTmpls = {};

exports = module.exports = function(options) {

	// Copy options object
	options = merge({
		'pubFilePath':  './public',
		'tmplDir':      'tmpl',
		'customRoutes': [],
		'debug':        false
	}, options);

	if ( ! (options.customRoutes instanceof Array))
		options.customRoutes = [];

	var returnObj = {};

	returnObj.resolve = function resolve(request, callback) {
		request.urlParsed = url.parse(request.url, true);
		var pathname      = request.urlParsed.pathname;

		// Remove .json path ending
		if (pathname.substring(pathname.length - 5) == '.json')
			pathname = pathname.substring(0, pathname.length - 5);

		var i = 0;
		while (options.customRoutes[i] !== undefined) {
			if (RegExp(options.customRoutes[i].regex).test(pathname)) {
				request.controllerName = options.customRoutes[i].controllerName;
				callCallback();
			}
			i++;
		}

		if (request.controllerName === undefined) {

			// Try to match a static file and if that fails, try to match a controller from URL
			var thisPubFilePath = options.pubFilePath + pathname;
			fs.stat(thisPubFilePath, function(err, stat) {
				if ( ! err && stat.isFile()) {
					// File found! Set the staticFilename and call the callback
					request.staticFilename = thisPubFilePath;
					callCallback();
				} else {
					// No static file was found, see if we have a matching controller when resolved from URL
					var controllerName = pathname.substring(1);

					fs.stat('./controllers/' + controllerName + '.js', function(err, stat) {
						if ( ! err && stat.isFile())
							request.controllerName = controllerName;
						callCallback();
					});
				}
			});
		}

		// Call callback if callable
		function callCallback() {
			if (typeof callback === 'function') {
				if (request.controllerName === undefined && request.staticFilename === undefined) {
					var errorMsg = 'larvitRouter.js - resolve() - Route "' + request.urlParsed.pathname + '" could not be resolved';
					console.error(errorMsg);
					callback(new Error(errorMsg));
				} else {
					callback(null);
				}
			}
		}
	};

	returnObj.sendToClient = function sendToClient(err, request, response, data) {
		if ( ! err) {
			var splittedPath = request.urlParsed.pathname.split('.');

			// We need to set the request type. Can be either json or html
			if (splittedPath[splittedPath.length - 1] == 'json') {
				request.type = 'json';
				request.controllerName = request.controllerName.substring(0, request.controllerName.length - 5);
				if (request.controllerName == '')
					request.controllerName = 'default';
			} else {
				request.type = 'html';
			}

			if (request.type == 'html') {
				var tmplName = '/' + options.tmplDir + '/' + request.controllerName + '.tmpl',
				    tmplRequest = {'url': tmplName};

				// Make an internal resolve for the template
				// We do this to imitade what it would be to fetch the
				// template from the clients perspective
				returnObj.resolve(tmplRequest, function(err) {
					if ( ! err && tmplRequest.staticFilename !== undefined) {

						compileTmpl(tmplRequest.staticFilename, function(err, compiledTmpl) {
							if ( ! err) {

								// The controller might have set a custom status code, do not override it
								if ( ! response.statusCode)
									response.statusCode = 200;

								response.writeHead(response.statusCode, {'Content-Type': 'text/html'});
								response.end(compiledTmpl(data));
							} else {
								internalError(err);
							}
						});

					} else {
						internalError(new Error('template "' + tmplName + '" not found'));
					}
				});
			} else if (request.type == 'json') {
				response.writeHead(200, {'Content-Type': 'application/json'});
				response.end(JSON.stringify(data));
			}
		} else {
			internalError(err);
		}

		function internalError(err) {
			console.error('larvitRouter.js - sendToClient() exited due to error:');
			console.error(err);

			response.writeHead(500, {'Content-Type': 'text/plain'});
			response.end('Internal server error');
		}
	};

	return returnObj;
}

/**
 * Compile templates and cache the compiled ones
 */
function compileTmpl(staticFilename, callback) {
	if (compiledTmpls[staticFilename] === undefined) {
		fs.readFile(staticFilename, 'utf8', function(err, tmplFileContent){
			if ( ! err) {
				compiledTmpls[staticFilename] = _.template(tmplFileContent);

				callback(null, compiledTmpls[staticFilename]);
			} else {
				callback(err);
			}
		})
	} else {
		callback(null, compiledTmpls[staticFilename]);
	}
}<commit_msg>Added use strict and some more error handling<commit_after>'use strict';

var fs            = require('fs'),
    url           = require('url'),
    merge         = require('utils-merge'),
    _             = require('underscore'),
    compiledTmpls = {};

exports = module.exports = function(options) {

	// Copy options object
	options = merge({
		'pubFilePath':  './public',
		'tmplDir':      'tmpl',
		'customRoutes': [],
		'debug':        false
	}, options);

	if ( ! (options.customRoutes instanceof Array))
		options.customRoutes = [];

	var returnObj = {};

	returnObj.resolve = function resolve(request, callback) {
		request.urlParsed = url.parse(request.url, true);
		var pathname      = request.urlParsed.pathname;

		// Remove .json path ending
		if (pathname.substring(pathname.length - 5) == '.json')
			pathname = pathname.substring(0, pathname.length - 5);

		var i = 0;
		while (options.customRoutes[i] !== undefined) {
			if (RegExp(options.customRoutes[i].regex).test(pathname)) {
				request.controllerName = options.customRoutes[i].controllerName;
				callCallback();
			}
			i++;
		}

		if (request.controllerName === undefined) {

			// Try to match a static file and if that fails, try to match a controller from URL
			var thisPubFilePath = options.pubFilePath + pathname;
			fs.stat(thisPubFilePath, function(err, stat) {
				if ( ! err && stat.isFile()) {
					// File found! Set the staticFilename and call the callback
					request.staticFilename = thisPubFilePath;
					callCallback();
				} else {
					// No static file was found, see if we have a matching controller when resolved from URL
					var controllerName = pathname.substring(1);

					fs.stat('./controllers/' + controllerName + '.js', function(err, stat) {
						if ( ! err && stat.isFile())
							request.controllerName = controllerName;
						callCallback();
					});
				}
			});
		}

		// Call callback if callable
		function callCallback() {
			if (typeof callback === 'function') {
				if (request.controllerName === undefined && request.staticFilename === undefined) {
					var errorMsg = 'larvitRouter.js - resolve() - Route "' + request.urlParsed.pathname + '" could not be resolved';
					console.error(errorMsg);
					callback(new Error(errorMsg));
				} else {
					callback(null);
				}
			}
		}
	};

	returnObj.sendToClient = function sendToClient(err, request, response, data) {
		if ( ! request.urlParsed) {
			internalError(new Error('request.urlParsed is not set in larvitRouter'));
		} else if ( ! err) {
			var splittedPath = request.urlParsed.pathname.split('.');

			// We need to set the request type. Can be either json or html
			if (splittedPath[splittedPath.length - 1] == 'json') {
				request.type = 'json';
				request.controllerName = request.controllerName.substring(0, request.controllerName.length - 5);
				if (request.controllerName == '')
					request.controllerName = 'default';
			} else {
				request.type = 'html';
			}

			if (request.type == 'html') {
				var tmplName = '/' + options.tmplDir + '/' + request.controllerName + '.tmpl',
				    tmplRequest = {'url': tmplName};

				// Make an internal resolve for the template
				// We do this to imitade what it would be to fetch the
				// template from the clients perspective
				returnObj.resolve(tmplRequest, function(err) {
					if ( ! err && tmplRequest.staticFilename !== undefined) {

						compileTmpl(tmplRequest.staticFilename, function(err, compiledTmpl) {
							if ( ! err) {

								// The controller might have set a custom status code, do not override it
								if ( ! response.statusCode)
									response.statusCode = 200;

								response.writeHead(response.statusCode, {'Content-Type': 'text/html'});
								response.end(compiledTmpl(data));
							} else {
								internalError(err);
							}
						});

					} else {
						internalError(new Error('template "' + tmplName + '" not found'));
					}
				});
			} else if (request.type == 'json') {
				response.writeHead(200, {'Content-Type': 'application/json'});
				response.end(JSON.stringify(data));
			}
		} else {
			internalError(err);
		}

		function internalError(err) {
			console.error('larvitRouter.js - sendToClient() exited due to error:');
			console.error(err);

			response.writeHead(500, {'Content-Type': 'text/plain'});
			response.end('Internal server error');
		}
	};

	return returnObj;
}

/**
 * Compile templates and cache the compiled ones
 */
function compileTmpl(staticFilename, callback) {
	if (compiledTmpls[staticFilename] === undefined) {
		fs.readFile(staticFilename, 'utf8', function(err, tmplFileContent){
			if ( ! err) {
				compiledTmpls[staticFilename] = _.template(tmplFileContent);

				callback(null, compiledTmpls[staticFilename]);
			} else {
				callback(err);
			}
		})
	} else {
		callback(null, compiledTmpls[staticFilename]);
	}
}<|endoftext|>


<commit_before>var express = require('express');
var _ = require('lodash');
var httpProxy = require('http-proxy');
var getAWSIPs = require('./getAWSIPs.js');
var Agent = require('agentkeepalive');
var raven = require('raven');

var serverPort = process.env.HTTP_PORT || 8081;
var proxyTimeout = parseInt(process.env.PROXY_TIMEOUT) || 180000;
var keepAliveTimeout = parseInt(process.env.KEEP_ALIVE_TIMEOUT) || 30000;
var maxSockets = parseInt(process.env.MAX_SOCKETS) || 100;
var maxFreeSockets = parseInt(process.env.MAX_FREE_SOCKETS) || 10;
var updateTargetsInterval = parseInt(process.env.UPDATE_TARGETS_INTERVAL) || 60000;
var latencyAverageWindow = parseInt(process.env.LATENCY_AVERAGE_WINDOW) || 30000;
var latencyGroupBySize = parseInt(process.env.LATENCY_GROUPBY_SIZE) || 100;

var log = new raven.Client(process.env.SENTRY);

var graftwerkTargets = [];

var updateGraftwerkTargets = _.throttle(function() {
  console.log('Fetching graftwerk nodes');
  getAWSIPs(function(ips) {
    graftwerkTargets = ips;
  });
}, 5000);

updateGraftwerkTargets();

setInterval(updateGraftwerkTargets, updateTargetsInterval);

var proxy = httpProxy.createProxyServer({
  agent: new Agent({
    maxSockets: maxSockets,
    maxFreeSockets: maxFreeSockets,
    timeout: proxyTimeout,
    keepAliveTimeout: keepAliveTimeout
  })
});

var printLatency = function(req) {
  var now = Date.now();
  var latency = now - req.loadBalancerStartTime;
  console.log('Latency ' + req.loadBalancerTarget + ': ' + latency);
};

proxy.on('error', function(err, req, res) {
  console.log('The ' + req.loadBalancerTarget + ' graftwerk node returned an error');
  printLatency(req);
  req.nbDispatchRetry = ++req.nbDispatchRetry || 1;

  if (req.nbDispatchRetry > 6) {
    console.log('6 tentatives later, no one works. We give up');
    res.status(503).json({
      error: 'Unable to contact a Grafter server'
    });
    log.captureMessage('6 tentatives later, no ones work. We give up.');
    return;
  }

  processRequest(req, res);
});

proxy.on('proxyRes', function(lol, req) {
  printLatency(req);
});

var currentTargetIndex = 0;
var selectTarget = function() {
  if (currentTargetIndex >= graftwerkTargets.length) {
    currentTargetIndex = 0;
  }

  return graftwerkTargets[currentTargetIndex];

  ++currentTargetIndex;
};

var processRequest = function(req, res) {
  // var target = _.sample(graftwerkTargets);
  var target = selectTarget();

  if (!target) {
    res.status(503).json({
      error: 'No Graftwerk server is available'
    });
    log.captureMessage('No Graftwerk server is available');
    return;
  }

  req.loadBalancerTarget = target;
  req.loadBalancerStartTime = Date.now();

  proxy.web(req, res, {
    target: {
      host: target,
      port: 8080
    }
  });
};

var app = express();
app.use(processRequest);

app.listen(serverPort, function() {
  console.log('LoadBalancer started on http://localhost:' + serverPort + '/');
});
<commit_msg>I should not tell anyone about this<commit_after>var express = require('express');
var _ = require('lodash');
var httpProxy = require('http-proxy');
var getAWSIPs = require('./getAWSIPs.js');
var Agent = require('agentkeepalive');
var raven = require('raven');

var serverPort = process.env.HTTP_PORT || 8081;
var proxyTimeout = parseInt(process.env.PROXY_TIMEOUT) || 180000;
var keepAliveTimeout = parseInt(process.env.KEEP_ALIVE_TIMEOUT) || 30000;
var maxSockets = parseInt(process.env.MAX_SOCKETS) || 100;
var maxFreeSockets = parseInt(process.env.MAX_FREE_SOCKETS) || 10;
var updateTargetsInterval = parseInt(process.env.UPDATE_TARGETS_INTERVAL) || 60000;
var latencyAverageWindow = parseInt(process.env.LATENCY_AVERAGE_WINDOW) || 30000;
var latencyGroupBySize = parseInt(process.env.LATENCY_GROUPBY_SIZE) || 100;

var log = new raven.Client(process.env.SENTRY);

var graftwerkTargets = [];

var updateGraftwerkTargets = _.throttle(function() {
  console.log('Fetching graftwerk nodes');
  getAWSIPs(function(ips) {
    graftwerkTargets = ips;
  });
}, 5000);

updateGraftwerkTargets();

setInterval(updateGraftwerkTargets, updateTargetsInterval);

var proxy = httpProxy.createProxyServer({
  agent: new Agent({
    maxSockets: maxSockets,
    maxFreeSockets: maxFreeSockets,
    timeout: proxyTimeout,
    keepAliveTimeout: keepAliveTimeout
  })
});

var printLatency = function(req) {
  var now = Date.now();
  var latency = now - req.loadBalancerStartTime;
  console.log('Latency ' + req.loadBalancerTarget + ': ' + latency);
};

proxy.on('error', function(err, req, res) {
  console.log('The ' + req.loadBalancerTarget + ' graftwerk node returned an error');
  printLatency(req);
  req.nbDispatchRetry = ++req.nbDispatchRetry || 1;

  if (req.nbDispatchRetry > 6) {
    console.log('6 tentatives later, no one works. We give up');
    res.status(503).json({
      error: 'Unable to contact a Grafter server'
    });
    log.captureMessage('6 tentatives later, no ones work. We give up.');
    return;
  }

  processRequest(req, res);
});

proxy.on('proxyRes', function(lol, req) {
  printLatency(req);
});

var currentTargetIndex = 0;
var selectTarget = function() {
  if (currentTargetIndex >= graftwerkTargets.length) {
    currentTargetIndex = 0;
  }

  return graftwerkTargets[currentTargetIndex++];
};

var processRequest = function(req, res) {
  // var target = _.sample(graftwerkTargets);
  var target = selectTarget();

  if (!target) {
    res.status(503).json({
      error: 'No Graftwerk server is available'
    });
    log.captureMessage('No Graftwerk server is available');
    return;
  }

  req.loadBalancerTarget = target;
  req.loadBalancerStartTime = Date.now();

  proxy.web(req, res, {
    target: {
      host: target,
      port: 8080
    }
  });
};

var app = express();
app.use(processRequest);

app.listen(serverPort, function() {
  console.log('LoadBalancer started on http://localhost:' + serverPort + '/');
});
<|endoftext|>


<commit_before>//Sudoku

//CodEval version

var fs  = require("fs");
fs.readFileSync(process.argv[2]).toString().split('\n').forEach(function (line) {
    if (line !== "") {
       var gridSize = 0,
           allValues = 0,
           i = 0,
           totalSum = 0;

        line = line.split(";");
        gridSize = line[0];
        allValues = line[1];
        allValues = allValues.split(",");

        for (i = 0; i <= allValues.length -1; i++) {
            totalSum = totalSum + Number(allValues[i]);
        }

        if (gridSize == 4 && totalSum == 40 || gridSize == 9 && totalSum == 405) {
            console.log("True") ;
        } else {
            console.log("False");
        }
    }
});
<commit_msg>minor edit<commit_after>//Sudoku
//CodEval version

var fs  = require("fs");
fs.readFileSync(process.argv[2]).toString().split('\n').forEach(function (line) {
    if (line !== "") {
       var gridSize = 0,
           allValues = 0,
           i = 0,
           totalSum = 0;

        line = line.split(";");
        gridSize = line[0];
        allValues = line[1];
        allValues = allValues.split(",");

        for (i = 0; i <= allValues.length -1; i++) {
            totalSum = totalSum + Number(allValues[i]);
        }

        if (gridSize == 4 && totalSum == 40 || gridSize == 9 && totalSum == 405) {
            console.log("True") ;
        } else {
            console.log("False");
        }
    }
});
<|endoftext|>


<commit_before>var contextMenuClick = function(info, tab, callbackID) {
	chrome.tabs.sendMessage(tab.id, {
		requestType: "contextMenu.click",
		callbackID: callbackID
	});
};

chrome.runtime.onMessage.addListener(
	function(request, sender, sendResponse) {
		// all requests expect a JSON object with requestType and then the relevant
		// companion information...
		switch(request.requestType) {
			case 'xmlhttpRequest':
				var xhr = new XMLHttpRequest();
				xhr.open(request.method, request.url, true);
				if (request.method === "POST") {
					xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
					// xhr.setRequestHeader("Content-length", request.data.length);
					// xhr.setRequestHeader("Connection", "close");
				}
				xhr.onreadystatechange = function() {
					if (xhr.readyState === 4) {
						sendResponse(xhr);
					}
				};
				xhr.send(request.data);
				break;
			case 'createTab':
				var newIndex,
					focus = (request.background !== true);

				if (typeof(request.index) !== 'undefined') {
					newIndex = request.index;
				} else {
					// If index wasn't specified, get the selected tab so we can get the index of it.
					// This allows us to open our new tab as the "next" tab in order rather than at the end.
					newIndex = sender.tab.index+1;
				}
				chrome.tabs.create({url: request.url, selected: focus, index: newIndex});
				sendResponse({status: "success"});
				break;
			case 'createNotification':
				if (!request.icon) {
					// if no icon specified, make a single pixel empty gif so we don't get a broken image link.
					request.icon = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==';
				}
				var notification = window.webkitNotifications.createNotification(
					request.icon,  // icon url - can be relative
					request.title,  // notification title
					request.text  // notification body text
				);
				notification.show();
				break;
			case 'localStorage':
				switch (request.operation) {
					case 'getItem':
						sendResponse({status: true, key: request.itemName, value: localStorage.getItem(request.itemName)});
						break;
					case 'removeItem':
						localStorage.removeItem(request.itemName);
						sendResponse({status: true, key: request.itemName, value: null});
						break;
					case 'setItem':
						localStorage.setItem(request.itemName, request.itemValue);
						sendResponse({status: true, key: request.itemName, value: request.itemValue});
						break;
				}
				break;
			case 'addURLToHistory':
				chrome.history.addUrl({url: request.url});
				break;
			case 'contextMenus.create':
				if (typeof request.obj.onclick === 'number') {
					var callbackID = request.obj.onclick;
					request.obj.onclick = function(info, tab) {
						contextMenuClick(info, tab, callbackID);
					};
				}
				chrome.contextMenus.create(request.obj);
				break;
			default:
				sendResponse({status: "unrecognized request type"});
				break;
		}
	}
);
<commit_msg>fixed an xhr bug in chrome<commit_after>var contextMenuClick = function(info, tab, callbackID) {
	chrome.tabs.sendMessage(tab.id, {
		requestType: "contextMenu.click",
		callbackID: callbackID
	});
};

chrome.runtime.onMessage.addListener(
	function(request, sender, sendResponse) {
		// all requests expect a JSON object with requestType and then the relevant
		// companion information...
		switch(request.requestType) {
			case 'xmlhttpRequest':
				var xhr = new XMLHttpRequest();
				xhr.open(request.method, request.url, true);
				if (request.method === "POST") {
					xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
					// xhr.setRequestHeader("Content-length", request.data.length);
					// xhr.setRequestHeader("Connection", "close");
				}
				xhr.onreadystatechange = function() {
					if (xhr.readyState === 4) {
						// Only store 'status' and 'responseText' fields and send them back.
						var response = {status: xhr.status, responseText: xhr.responseText};
						sendResponse(response);
					}
				};
				xhr.send(request.data);
				return true; // true must be returned here to indicate successful XHR
				break;
			case 'createTab':
				var newIndex,
					focus = (request.background !== true);

				if (typeof(request.index) !== 'undefined') {
					newIndex = request.index;
				} else {
					// If index wasn't specified, get the selected tab so we can get the index of it.
					// This allows us to open our new tab as the "next" tab in order rather than at the end.
					newIndex = sender.tab.index+1;
				}
				chrome.tabs.create({url: request.url, selected: focus, index: newIndex});
				sendResponse({status: "success"});
				break;
			case 'createNotification':
				if (!request.icon) {
					// if no icon specified, make a single pixel empty gif so we don't get a broken image link.
					request.icon = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==';
				}
				var notification = window.webkitNotifications.createNotification(
					request.icon,  // icon url - can be relative
					request.title,  // notification title
					request.text  // notification body text
				);
				notification.show();
				break;
			case 'localStorage':
				switch (request.operation) {
					case 'getItem':
						sendResponse({status: true, key: request.itemName, value: localStorage.getItem(request.itemName)});
						break;
					case 'removeItem':
						localStorage.removeItem(request.itemName);
						sendResponse({status: true, key: request.itemName, value: null});
						break;
					case 'setItem':
						localStorage.setItem(request.itemName, request.itemValue);
						sendResponse({status: true, key: request.itemName, value: request.itemValue});
						break;
				}
				break;
			case 'addURLToHistory':
				chrome.history.addUrl({url: request.url});
				break;
			case 'contextMenus.create':
				if (typeof request.obj.onclick === 'number') {
					var callbackID = request.obj.onclick;
					request.obj.onclick = function(info, tab) {
						contextMenuClick(info, tab, callbackID);
					};
				}
				chrome.contextMenus.create(request.obj);
				break;
			default:
				sendResponse({status: "unrecognized request type"});
				break;
		}
	}
);
<|endoftext|>