<commit_before>/**
 * This provides the principal function to make a call to the API. Basically
 * a fancy wrapper around XHR/JSONP/etc.
 */
'use strict';

goog.provide('Server');
goog.require('utils');
goog.require('goog.json');
goog.require('storage'); // jshint unused:false
goog.require('safejson');

/**
 * @class Server
 * @constructor
 */
var Server = function() { };

Server.prototype._jsonp_callback_index = 0;

/**
 * @param {Object} obj
 * @param {string} prefix
 */
Server.prototype.serializeObject = function(obj, prefix) {
	if (typeof obj === 'undefined') {
		return '';
	}

	var pairs = [ ];
	if (obj instanceof Array) {
		for (var i = 0; i < obj.length; i++) {
			pairs.push(encodeURIComponent(prefix) + '=' + encodeURIComponent(obj[i]));
		}
		return pairs.join('&');
	}

	for (var prop in obj) {
		if (!obj.hasOwnProperty(prop)) {
			continue;
		}
		if (obj[prop] instanceof Array || typeof obj[prop] === 'object') {
			pairs.push(
				this.serializeObject(obj[prop], prefix ? prefix + '.' + prop : prop)
			);
		}
		else {
			pairs.push(encodeURIComponent(prefix ? prefix + '.' + prop : prop) +
				'=' +
				encodeURIComponent(obj[prop])
			);
		}
	}
	return pairs.join('&');
};

/**
 * @param {utils.resource} resource
 * @param {Object.<string, *>} data
 */
Server.prototype.getUrl = function(resource, data) {
	var k;
	var v;
	var err;
	var url = resource.destination + resource.endpoint;
	var branch_id = /^[0-9]{15,20}$/;
	var branch_key = /key_(live|test)_[A-Za-z0-9]{32}/;

	var appendKeyOrId = function(data, destinationObject) {
		if (typeof destinationObject === 'undefined') {
			destinationObject = { };
		}
		if (data['branch_key'] && branch_key.test(data['branch_key'])) {
			destinationObject['branch_key'] = data['branch_key'];
			return destinationObject;
		}
		else if (data['app_id'] && branch_id.test(data['app_id'])) {
			destinationObject['app_id'] = data['app_id'];
			return destinationObject;
		}
		else {
			throw Error(utils.message(
				utils.messages.missingParam,
				[
					resource.endpoint,
					'branch_key or app_id'
				]
			));
		}
	};

	if (resource.endpoint === '/v1/has-app') {
		try {
			resource.queryPart = appendKeyOrId(data, resource.queryPart);
		}
		catch (e) {
			return {
				error: e.message
			};
		}
	}

	if (typeof resource.queryPart !== 'undefined') {
		for (k in resource.queryPart) {
			if (!resource.queryPart.hasOwnProperty(k)) {
				continue;
			}
			err = (typeof resource.queryPart[k] === 'function') ?
				resource.queryPart[k](resource.endpoint, k, data[k]) :
				err;
			if (err) {
				return { error: err };
			}
			url += '/' + data[k];
		}
	}

	var d = { };
	if (typeof resource.params !== 'undefined') {
		for (k in resource.params) {
			if (resource.params.hasOwnProperty(k)) {
				err = resource.params[k](resource.endpoint, k, data[k]);
				if (err) {
					return {
						error: err
					};
				}

				v = data[k];
				if (!(typeof v === 'undefined' || v === '' || v === null)) {
					d[k] = v;
				}
			}
		}
	}

	if (resource.method === 'POST' || resource.endpoint === '/v1/credithistory') {
		try {
			data = appendKeyOrId(data, d);
		}
		catch (e) {
			return {
				error: e.message
			};
		}
	}

	if (resource.endpoint === '/v1/event') {
		d['metadata'] = safejson.stringify(d['metadata'] || {});
		if (d.hasOwnProperty('commerce_data')) {
			d['commerce_data'] = safejson.stringify(d['commerce_data'] || {});
		}
	}

	if (resource.endpoint === '/v1/open') {
		d['options'] = safejson.stringify(d['options'] || {});
	}

	return {
		data: this.serializeObject(d, ''),
		url: url.replace(/^\//, '')
	};
};

/**
 * This function is standalone for easy mocking.
 * @param {string} src
 */
Server.prototype.createScript = function(src, onError, onLoad) {
	var script = document.createElement('script');
	script.type = 'text/javascript';
	script.async = true;
	script.src = src;

	var heads = document.getElementsByTagName('head');
	if (!heads || heads.length < 1) {
		if (typeof onError === 'function') {
			onError();
		}
		return;
	}
	heads[0].appendChild(script);

	if (typeof onError === 'function') {
		utils.addEvent(script, 'error', onError);
	}
	if (typeof onLoad === 'function') {
		utils.addEvent(script, 'load', onLoad);
	}
};

/**
 * @param {string} requestURL
 * @param {Object} requestData
 * @param {utils._httpMethod} requestMethod
 * @param {function(?Error,*=,?=)=} callback
 */
Server.prototype.jsonpRequest = function(requestURL, requestData, requestMethod, callback) {

	// Ensures correct behavior for auto deep linking in iOS 11, Safari
	if (this._jsonp_callback_index === 0 && utils.isSafari11OrGreater()) {
		this._jsonp_callback_index++;
	}
	var callbackString = 'branch_callback__' + (this._jsonp_callback_index++);

	var postPrefix = (requestURL.indexOf('branch.io') >= 0) ? '&data=' : '&post_data=';
	var postData = (requestMethod === 'POST') ?
		encodeURIComponent(utils.base64encode(goog.json.serialize(requestData))) :
		'';

	var timeoutTrigger = window.setTimeout(
		function() {
			window[callbackString] = function() { };
			callback(new Error(utils.messages.timeout), null, 504);
		},
		utils.timeout
	);

	window[callbackString] = function(data) {
		window.clearTimeout(timeoutTrigger);
		callback(null, data);
	};

	this.createScript(
		requestURL + (requestURL.indexOf('?') < 0 ? '?' : '') +
			(postData ? postPrefix + postData : '') +
			(requestURL.indexOf('/c/') >= 0 ? '&click=1' : '') +
			'&callback=' + callbackString,
		function onError() {
			callback(new Error(utils.messages.blockedByClient), null);
		},
		function onLoad() {
			try {
				if (typeof this.remove === 'function') {
					this.remove();
				}
				else {
					// some browsers do not have a 'remove' method
					// for Element, so fall back
					this.parentNode.removeChild(this);
				}
			}
			catch (e) {
				// we're trying to remove the script tag during a
				// jsonp request, but if that fails, we shouldn't
				// break anything else...just continue
			}
			delete window[callbackString];
		});
};

/**
 * @param {string} url
 * @param {Object} data
 * @param {utils._httpMethod} method
 * @param {storage} storage
 * @param {function(?Error,*=,?=)=} callback
 * @param {?boolean=} noparse
 */
Server.prototype.XHRRequest = function(url, data, method, storage, callback, noparse) {
	var req = (window.XMLHttpRequest ?
			new XMLHttpRequest() :
			new ActiveXObject('Microsoft.XMLHTTP'));
	req.ontimeout = function() {
		callback(new Error(utils.messages.timeout), null, 504);
	};
	req.onerror = function(e) {
		callback(new Error(e.error || ('Error in API: ' + req.status)), null, req.status);
	};
	req.onreadystatechange = function() {
		var data;
		if (req.readyState === 4) {
			if (req.status === 200) {
				if (noparse) {
					data = req.responseText;
				}
				else {
					try {
						data = safejson.parse(req.responseText);
					}
					catch (e) {
						data = {};
					}
				}
				callback(null, data, req.status);
			}
			else if (req.status === 402) {
				callback(new Error('Not enough credits to redeem.'), null, req.status);
			}
			else if (req.status.toString().substring(0, 1) === '4' ||
					req.status.toString().substring(0, 1) === '5') {
				// Server returns helpful information when a partner sends up incorrect fields in logEvent().
				// This information appears in req.responseText.
				if (req['responseURL'] && req['responseURL'].includes("v2/event")) {
					callback(req['responseText'], null, req['status']);
				}
				else {
					callback(new Error('Error in API: ' + req.status), null, req.status);
				}
			}
		}
	};

	try {
		req.open(method, url, true);
		req.timeout = utils.timeout;
		req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		req.send(data);
	}
	catch (e) {
		storage.set('use_jsonp', true);
		this.jsonpRequest(url, data, method, callback);
	}
};

/**
 * @param {utils.resource} resource
 * @param {Object.<string, *>} data
 * @param {storage} storage
 * @param {function(?Error,*=)=} callback
 */
Server.prototype.request = function(resource, data, storage, callback) {
	var self = this;

	var u = this.getUrl(resource, data);
	if (u.error) {
		var errorObj = {
			message: u.error,
			endpoint: resource.endpoint,
			data: data
		};
		return callback(new Error(safejson.stringify(errorObj)));
	}

	var url;
	var postData = '';
	if (resource.method === 'GET') {
		url = u.url + '?' + u.data;
	}
	else {
		url = u.url;
		postData = u.data;
	}

	// How many times to retry the request if the initial attempt fails
	var retries = utils.retries;
	// If request fails, retry after X miliseconds
	/***
	 * @type {function(?Error,*=): ?undefined}
	 */
	var done = function(err, data, status) {
		if (err && retries > 0 && (status || "").toString().substring(0, 1) === '5') {
			retries--;
			window.setTimeout(function() {
				makeRequest();
			}, utils.retry_delay);
		}
		else {
			callback(err, data);
		}
	};
	var makeRequest = function() {
		if (storage.get('use_jsonp') || resource.jsonp) {
			self.jsonpRequest(url, data, resource.method, done);
		}
		else {
			self.XHRRequest(url, postData, resource.method, storage, done);
		}
	};
	makeRequest();
};
<commit_msg>adding a comment<commit_after>/**
 * This provides the principal function to make a call to the API. Basically
 * a fancy wrapper around XHR/JSONP/etc.
 */
'use strict';

goog.provide('Server');
goog.require('utils');
goog.require('goog.json');
goog.require('storage'); // jshint unused:false
goog.require('safejson');

/**
 * @class Server
 * @constructor
 */
var Server = function() { };

Server.prototype._jsonp_callback_index = 0;

/**
 * @param {Object} obj
 * @param {string} prefix
 */
Server.prototype.serializeObject = function(obj, prefix) {
	if (typeof obj === 'undefined') {
		return '';
	}

	var pairs = [ ];
	if (obj instanceof Array) {
		for (var i = 0; i < obj.length; i++) {
			pairs.push(encodeURIComponent(prefix) + '=' + encodeURIComponent(obj[i]));
		}
		return pairs.join('&');
	}

	for (var prop in obj) {
		if (!obj.hasOwnProperty(prop)) {
			continue;
		}
		if (obj[prop] instanceof Array || typeof obj[prop] === 'object') {
			pairs.push(
				this.serializeObject(obj[prop], prefix ? prefix + '.' + prop : prop)
			);
		}
		else {
			pairs.push(encodeURIComponent(prefix ? prefix + '.' + prop : prop) +
				'=' +
				encodeURIComponent(obj[prop])
			);
		}
	}
	return pairs.join('&');
};

/**
 * @param {utils.resource} resource
 * @param {Object.<string, *>} data
 */
Server.prototype.getUrl = function(resource, data) {
	var k;
	var v;
	var err;
	var url = resource.destination + resource.endpoint;
	var branch_id = /^[0-9]{15,20}$/;
	var branch_key = /key_(live|test)_[A-Za-z0-9]{32}/;

	var appendKeyOrId = function(data, destinationObject) {
		if (typeof destinationObject === 'undefined') {
			destinationObject = { };
		}
		if (data['branch_key'] && branch_key.test(data['branch_key'])) {
			destinationObject['branch_key'] = data['branch_key'];
			return destinationObject;
		}
		else if (data['app_id'] && branch_id.test(data['app_id'])) {
			destinationObject['app_id'] = data['app_id'];
			return destinationObject;
		}
		else {
			throw Error(utils.message(
				utils.messages.missingParam,
				[
					resource.endpoint,
					'branch_key or app_id'
				]
			));
		}
	};

	if (resource.endpoint === '/v1/has-app') {
		try {
			resource.queryPart = appendKeyOrId(data, resource.queryPart);
		}
		catch (e) {
			return {
				error: e.message
			};
		}
	}

	if (typeof resource.queryPart !== 'undefined') {
		for (k in resource.queryPart) {
			if (!resource.queryPart.hasOwnProperty(k)) {
				continue;
			}
			err = (typeof resource.queryPart[k] === 'function') ?
				resource.queryPart[k](resource.endpoint, k, data[k]) :
				err;
			if (err) {
				return { error: err };
			}
			url += '/' + data[k];
		}
	}

	var d = { };
	if (typeof resource.params !== 'undefined') {
		for (k in resource.params) {
			if (resource.params.hasOwnProperty(k)) {
				err = resource.params[k](resource.endpoint, k, data[k]);
				if (err) {
					return {
						error: err
					};
				}

				v = data[k];
				if (!(typeof v === 'undefined' || v === '' || v === null)) {
					d[k] = v;
				}
			}
		}
	}

	if (resource.method === 'POST' || resource.endpoint === '/v1/credithistory') {
		try {
			data = appendKeyOrId(data, d);
		}
		catch (e) {
			return {
				error: e.message
			};
		}
	}

	if (resource.endpoint === '/v1/event') {
		d['metadata'] = safejson.stringify(d['metadata'] || {});
		if (d.hasOwnProperty('commerce_data')) {
			d['commerce_data'] = safejson.stringify(d['commerce_data'] || {});
		}
	}

	if (resource.endpoint === '/v1/open') {
		d['options'] = safejson.stringify(d['options'] || {});
	}

	return {
		data: this.serializeObject(d, ''),
		url: url.replace(/^\//, '')
	};
};

/**
 * This function is standalone for easy mocking.
 * @param {string} src
 */
Server.prototype.createScript = function(src, onError, onLoad) {
	var script = document.createElement('script');
	script.type = 'text/javascript';
	script.async = true;
	script.src = src;

	var heads = document.getElementsByTagName('head');
	if (!heads || heads.length < 1) {
		if (typeof onError === 'function') {
			onError();
		}
		return;
	}
	heads[0].appendChild(script);

	if (typeof onError === 'function') {
		utils.addEvent(script, 'error', onError);
	}
	if (typeof onLoad === 'function') {
		utils.addEvent(script, 'load', onLoad);
	}
};

/**
 * @param {string} requestURL
 * @param {Object} requestData
 * @param {utils._httpMethod} requestMethod
 * @param {function(?Error,*=,?=)=} callback
 */
Server.prototype.jsonpRequest = function(requestURL, requestData, requestMethod, callback) {

	/* On iOS 11-Safari when a partner calls .deepview() and uses $uri_redirect_mode: 2,
	   they will not get transported into the app (if installed) on pageload because
	   callbackString will evaluate to branch_callback_0. The backend expects branch_callback_1
	   for auto-open to work. This is why we have the fix below.
	*/
	if (this._jsonp_callback_index === 0 && utils.isSafari11OrGreater()) {
		this._jsonp_callback_index++;
	}
	var callbackString = 'branch_callback__' + (this._jsonp_callback_index++);

	var postPrefix = (requestURL.indexOf('branch.io') >= 0) ? '&data=' : '&post_data=';
	var postData = (requestMethod === 'POST') ?
		encodeURIComponent(utils.base64encode(goog.json.serialize(requestData))) :
		'';

	var timeoutTrigger = window.setTimeout(
		function() {
			window[callbackString] = function() { };
			callback(new Error(utils.messages.timeout), null, 504);
		},
		utils.timeout
	);

	window[callbackString] = function(data) {
		window.clearTimeout(timeoutTrigger);
		callback(null, data);
	};

	this.createScript(
		requestURL + (requestURL.indexOf('?') < 0 ? '?' : '') +
			(postData ? postPrefix + postData : '') +
			(requestURL.indexOf('/c/') >= 0 ? '&click=1' : '') +
			'&callback=' + callbackString,
		function onError() {
			callback(new Error(utils.messages.blockedByClient), null);
		},
		function onLoad() {
			try {
				if (typeof this.remove === 'function') {
					this.remove();
				}
				else {
					// some browsers do not have a 'remove' method
					// for Element, so fall back
					this.parentNode.removeChild(this);
				}
			}
			catch (e) {
				// we're trying to remove the script tag during a
				// jsonp request, but if that fails, we shouldn't
				// break anything else...just continue
			}
			delete window[callbackString];
		});
};

/**
 * @param {string} url
 * @param {Object} data
 * @param {utils._httpMethod} method
 * @param {storage} storage
 * @param {function(?Error,*=,?=)=} callback
 * @param {?boolean=} noparse
 */
Server.prototype.XHRRequest = function(url, data, method, storage, callback, noparse) {
	var req = (window.XMLHttpRequest ?
			new XMLHttpRequest() :
			new ActiveXObject('Microsoft.XMLHTTP'));
	req.ontimeout = function() {
		callback(new Error(utils.messages.timeout), null, 504);
	};
	req.onerror = function(e) {
		callback(new Error(e.error || ('Error in API: ' + req.status)), null, req.status);
	};
	req.onreadystatechange = function() {
		var data;
		if (req.readyState === 4) {
			if (req.status === 200) {
				if (noparse) {
					data = req.responseText;
				}
				else {
					try {
						data = safejson.parse(req.responseText);
					}
					catch (e) {
						data = {};
					}
				}
				callback(null, data, req.status);
			}
			else if (req.status === 402) {
				callback(new Error('Not enough credits to redeem.'), null, req.status);
			}
			else if (req.status.toString().substring(0, 1) === '4' ||
					req.status.toString().substring(0, 1) === '5') {
				// Server returns helpful information when a partner sends up incorrect fields in logEvent().
				// This information appears in req.responseText.
				if (req['responseURL'] && req['responseURL'].includes("v2/event")) {
					callback(req['responseText'], null, req['status']);
				}
				else {
					callback(new Error('Error in API: ' + req.status), null, req.status);
				}
			}
		}
	};

	try {
		req.open(method, url, true);
		req.timeout = utils.timeout;
		req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		req.send(data);
	}
	catch (e) {
		storage.set('use_jsonp', true);
		this.jsonpRequest(url, data, method, callback);
	}
};

/**
 * @param {utils.resource} resource
 * @param {Object.<string, *>} data
 * @param {storage} storage
 * @param {function(?Error,*=)=} callback
 */
Server.prototype.request = function(resource, data, storage, callback) {
	var self = this;

	var u = this.getUrl(resource, data);
	if (u.error) {
		var errorObj = {
			message: u.error,
			endpoint: resource.endpoint,
			data: data
		};
		return callback(new Error(safejson.stringify(errorObj)));
	}

	var url;
	var postData = '';
	if (resource.method === 'GET') {
		url = u.url + '?' + u.data;
	}
	else {
		url = u.url;
		postData = u.data;
	}

	// How many times to retry the request if the initial attempt fails
	var retries = utils.retries;
	// If request fails, retry after X miliseconds
	/***
	 * @type {function(?Error,*=): ?undefined}
	 */
	var done = function(err, data, status) {
		if (err && retries > 0 && (status || "").toString().substring(0, 1) === '5') {
			retries--;
			window.setTimeout(function() {
				makeRequest();
			}, utils.retry_delay);
		}
		else {
			callback(err, data);
		}
	};
	var makeRequest = function() {
		if (storage.get('use_jsonp') || resource.jsonp) {
			self.jsonpRequest(url, data, resource.method, done);
		}
		else {
			self.XHRRequest(url, postData, resource.method, storage, done);
		}
	};
	makeRequest();
};
<|endoftext|>


<commit_before>/*jslint node:true */
'use strict';

var lodash = require('lodash'),
    jjv = require('jjv'),
    REQ = require('request'),
    when = require('when'),
    fs = require('fs'),

AValidator = {
    normalizeError: function (V, I) {
        return {
            type: 'validation',
            target: I,
            rule: V
        };
    },
    findSchemaFiles: function (base, match) {
        var F = [],
            D = base || process.cwd();

        try {
            fs.readdirSync(D).forEach(function (N) {
                var FN = D + '/' + N,
                    S = fs.statSync(FN);

                if (S.isDirectory()) {
                    lodash.map(AValidator.findSchemaFiles(FN), function (O) {
                        F.push(O);
                    });
                    return;
                }

                if (N.match(match || /(schema)?\.json$/)) {
                    F.push(FN);
                }
            });
        } catch (E) {
        }

        return F;
    },
    promiseAll: function (list) {
        return when.all(lodash.map(list, AValidator.promise));
    },
    request: function (D, cb) {
        if (!lodash.isFunction(cb)) {
            throw {
                error: [{
                    'type': 'input',
                    message: 'No callback for AValidator.request'
                }]
            };
        }

        if (!D) {
            return cb({
                error: [{
                    'type': 'input',
                    message: 'No input for AValidator.request'
                }]
            });
        }

        if (!D.url) {
            return cb({
                error: [{
                    'type': 'input',
                    message: 'No input.url for AValidator.request'
                }]
            });
        }

        D.json = true;

        REQ(D, function (E, R, B) {
            if (E) {
                return cb({
                    error: [{
                        'type': 'request',
                        message: E.message,
                        response: R,
                        body: B
                    }]
                });
            }

            D.data = B;
            cb(AValidator.one(D));
        });
    },
    promise: function (D) {
        return when.promise(function (resolve) {
            AValidator.request(D, function (E) {
                resolve(E);
            });
        });
    },
    all: function (list) {
        if (!lodash.isArray(list)) {
            return {
                error: [{
                    'type': 'input',
                    message: 'Input is not array for AValidator.all'
                }]
            };
        }

        return lodash.map(list, AValidator.one);
    },
    one: function (D) {
        var E, err;

        if (!D) {
            return {
                error: [{
                    'type': 'internal',
                    message: 'No input for AValidator.one'
                }]
            };
        }

        if (!D.schema) {
            return {
                error: [{
                    'type': 'input',
                    message: 'No schema in input for AValidator.one'
                }]
            };
        }

        E = jjv();
        err = E.validate(D.schema, D.data);

        return err ? {error: lodash.map(err.validation, AValidator.normalizeError)} : null;
    }
};

module.exports = AValidator;
<commit_msg>trigger build<commit_after>/*jslint node: true */
'use strict';

var lodash = require('lodash'),
    jjv = require('jjv'),
    REQ = require('request'),
    when = require('when'),
    fs = require('fs'),

AValidator = {
    normalizeError: function (V, I) {
        return {
            type: 'validation',
            target: I,
            rule: V
        };
    },
    findSchemaFiles: function (base, match) {
        var F = [],
            D = base || process.cwd();

        try {
            fs.readdirSync(D).forEach(function (N) {
                var FN = D + '/' + N,
                    S = fs.statSync(FN);

                if (S.isDirectory()) {
                    lodash.map(AValidator.findSchemaFiles(FN), function (O) {
                        F.push(O);
                    });
                    return;
                }

                if (N.match(match || /(schema)?\.json$/)) {
                    F.push(FN);
                }
            });
        } catch (E) {
        }

        return F;
    },
    promiseAll: function (list) {
        return when.all(lodash.map(list, AValidator.promise));
    },
    request: function (D, cb) {
        if (!lodash.isFunction(cb)) {
            throw {
                error: [{
                    'type': 'input',
                    message: 'No callback for AValidator.request'
                }]
            };
        }

        if (!D) {
            return cb({
                error: [{
                    'type': 'input',
                    message: 'No input for AValidator.request'
                }]
            });
        }

        if (!D.url) {
            return cb({
                error: [{
                    'type': 'input',
                    message: 'No input.url for AValidator.request'
                }]
            });
        }

        D.json = true;

        REQ(D, function (E, R, B) {
            if (E) {
                return cb({
                    error: [{
                        'type': 'request',
                        message: E.message,
                        response: R,
                        body: B
                    }]
                });
            }

            D.data = B;
            cb(AValidator.one(D));
        });
    },
    promise: function (D) {
        return when.promise(function (resolve) {
            AValidator.request(D, function (E) {
                resolve(E);
            });
        });
    },
    all: function (list) {
        if (!lodash.isArray(list)) {
            return {
                error: [{
                    'type': 'input',
                    message: 'Input is not array for AValidator.all'
                }]
            };
        }

        return lodash.map(list, AValidator.one);
    },
    one: function (D) {
        var E, err;

        if (!D) {
            return {
                error: [{
                    'type': 'internal',
                    message: 'No input for AValidator.one'
                }]
            };
        }

        if (!D.schema) {
            return {
                error: [{
                    'type': 'input',
                    message: 'No schema in input for AValidator.one'
                }]
            };
        }

        E = jjv();
        err = E.validate(D.schema, D.data);

        return err ? {error: lodash.map(err.validation, AValidator.normalizeError)} : null;
    }
};

module.exports = AValidator;
<|endoftext|>


<commit_before>define([
    "sprd/data/SprdModel",
    'js/core/List',
    'sprd/model/ProductType',
    'js/data/AttributeTypeResolver',
    'sprd/entity/DesignConfiguration',
    'sprd/entity/TextConfiguration',
    'sprd/entity/Appearance',
    'js/data/TypeResolver', 'js/data/Entity', "underscore", "flow", "sprd/util/ProductUtil"],
    function (SprdModel, List, ProductType, AttributeTypeResolver, DesignConfiguration, TextConfiguration, Appearance, TypeResolver, Entity, _, flow, ProductUtil) {
        return SprdModel.inherit("sprd.model.Product", {

            schema: {
                productType: ProductType,
                appearance: {
                    type: Appearance,
                    isReference: true
                },
                configurations: [new AttributeTypeResolver({
                    attribute: "type",
                    mapping: {
                        "design": DesignConfiguration,
                        "text": TextConfiguration
                    }
                })],
                restrictions: Object
            },

            defaults: {
                productType: null,
                appearance: null,
                view: null,
                configurations: List
            },

            price: function () {
                // TODO format price with currency
                return this.$.price.vatIncluded;
            },

            getDefaultView: function () {

                if (this.$.productType) {
                    var defaultViewId = this.getDefaultViewId();

                    if (defaultViewId !== null) {
                        return this.$.productType.getViewById(defaultViewId);
                    } else {
                        return this.$.productType.getDefaultView();
                    }
                }

            },

            getDefaultViewId: function(){
                if (this.$.defaultValues) {
                    return this.$.defaultValues.defaultView.id;
                }
                return null;
            },

            getDefaultAppearance: function() {
                if(this.$.appearance && this.$.productType){
                    return this.$.productType.getAppearanceById(this.$.appearance.$.id);
                }
            },

            _addConfiguration: function(configuration) {
                this.$.configurations.add(configuration);
            },

            /***
             * set the product type and converts all configurations
             *
             * @param {sprd.model.ProductType} productType
             * @param callback
             */
            setProductType: function(productType, callback) {

                var self = this,
                    appearance;

                flow()
                    .seq(function(cb) {
                        productType.fetch(null, cb);
                    })
                    .seq(function() {

                        if (self.$.appearance) {
                            appearance = productType.getClosestAppearance(self.$.appearance.getMainColor());
                        } else {
                            appearance = productType.getDefaultAppearance();
                        }
                    })
                    .seq(function () {
                        // TODO: convert all configurations: size, position, print type

                        var configurations = self.$.configurations.$items,
                            removeConfigurations = [];

                        for (var i = 0; i < configurations.length; i++) {
                            var configuration = configurations[i],
                                currentView = configuration.$.printArea.getDefaultView(),
                                targetView = null,
                                targetPrintArea = null;

                            if (currentView) {
                                targetView = productType.getViewByPerspective(currentView.$.perspective);
                            }

                            if (targetView) {
                                targetPrintArea = targetView.getDefaultPrintArea();
                            }

                            if (targetPrintArea) {
                                configuration.set('printArea', targetPrintArea);
                            } else {
                                // no print area found, remove configuration
                                removeConfigurations.push(configuration);
                            }
                        }

                        self.$.configurations.remove(removeConfigurations);

                    })
                    .seq(function() {
                        // first set product type
                        self.set("productType", productType);
                        // and then the appearance, because appearance depends on product type
                        self.set("appearance", appearance);
                    })
                    .exec(callback)

            },

            addDesign: function (params, callback) {
                params = _.defaults({}, params, {
                    design: null,
                    perspective: null, // front, back, etc...
                    view: null,
                    printArea: null,
                    printType: null
                });

                var self = this,
                    design = params.design,
                    productType = this.$.productType,
                    printArea = params.printArea,
                    view = params.view,
                    appearance = this.$.appearance,
                    printType = params.printType;

                if (!design) {
                    callback(new Error("No design"));
                    return;
                }

                if (!productType) {
                    callback(new Error("ProductType not set"));
                    return;
                }

                if (!appearance) {
                    callback(new Error("Appearance for product not set"));
                    return;
                }

                flow()
                    .par(function (cb) {
                        design.fetch(null, cb);
                    }, function (cb) {
                        productType.fetch(null, cb);
                    })
                    .seq("printArea", function () {

                        if (!printArea && params.perspective && !view) {
                            view = productType.getViewByPerspective(params.perspective);
                        }

                        if (!printArea && view) {
                            // get print area by view
                            if (!productType.containsView(view)) {
                                throw new Error("View not on ProductType");
                            }

                            // TODO: look for print area that supports print types, etc...
                            printArea = view.getDefaultPrintArea();
                        }

                        view = self.$.view || self.getDefaultView();
                        if (!printArea && view) {
                            printArea = view.getDefaultPrintArea();
                        }

                        if (!printArea) {
                            throw new Error("target PrintArea couldn't be found.");
                        }

                        return printArea;
                    })
                    .seq("printType", function() {
                        var possiblePrintTypes = ProductUtil.getPossiblePrintTypesForDesignOnPrintArea(design, printArea, appearance.$.id);

                        if (printType && !_.contains(possiblePrintTypes, printType)) {
                            throw new Error("PrintType not possible for design and printArea");
                        }

                        printType = printType || possiblePrintTypes[0];

                        if (!printType) {
                            throw new Error("No printType available");
                        }

                        return printType;
                    })
                    .seq(function(cb) {
                        printType.fetch(null, cb);
                    })
                    .seq(function() {
                        var configuration = new DesignConfiguration({
                            printType: printType,
                            printArea: printArea,
                            design: design
                        });

                        self._addConfiguration(configuration);
                    })
                    .exec(callback)

            } ,

            compose: function(){
                var ret = this.callBase();

                ret.restrictions = {
                    freeColorSelection: false,
                    example: false
                };

                return ret;
            }
        });
    });
<commit_msg>simple scale and offset<commit_after>define([
    "sprd/data/SprdModel",
    'js/core/List',
    'sprd/model/ProductType',
    'js/data/AttributeTypeResolver',
    'sprd/entity/DesignConfiguration',
    'sprd/entity/TextConfiguration',
    'sprd/entity/Appearance',
    'js/data/TypeResolver', 'js/data/Entity', "underscore", "flow", "sprd/util/ProductUtil"],
    function (SprdModel, List, ProductType, AttributeTypeResolver, DesignConfiguration, TextConfiguration, Appearance, TypeResolver, Entity, _, flow, ProductUtil) {
        return SprdModel.inherit("sprd.model.Product", {

            schema: {
                productType: ProductType,
                appearance: {
                    type: Appearance,
                    isReference: true
                },
                configurations: [new AttributeTypeResolver({
                    attribute: "type",
                    mapping: {
                        "design": DesignConfiguration,
                        "text": TextConfiguration
                    }
                })],
                restrictions: Object
            },

            defaults: {
                productType: null,
                appearance: null,
                view: null,
                configurations: List
            },

            price: function () {
                // TODO format price with currency
                return this.$.price.vatIncluded;
            },

            getDefaultView: function () {

                if (this.$.productType) {
                    var defaultViewId = this.getDefaultViewId();

                    if (defaultViewId !== null) {
                        return this.$.productType.getViewById(defaultViewId);
                    } else {
                        return this.$.productType.getDefaultView();
                    }
                }

            },

            getDefaultViewId: function(){
                if (this.$.defaultValues) {
                    return this.$.defaultValues.defaultView.id;
                }
                return null;
            },

            getDefaultAppearance: function() {
                if(this.$.appearance && this.$.productType){
                    return this.$.productType.getAppearanceById(this.$.appearance.$.id);
                }
            },

            _addConfiguration: function(configuration) {
                this.$.configurations.add(configuration);
            },

            /***
             * set the product type and converts all configurations
             *
             * @param {sprd.model.ProductType} productType
             * @param callback
             */
            setProductType: function(productType, callback) {

                var self = this,
                    appearance,
                    view;

                flow()
                    .seq(function(cb) {
                        productType.fetch(null, cb);
                    })
                    .seq(function() {
                        if (self.$.appearance) {
                            appearance = productType.getClosestAppearance(self.$.appearance.getMainColor());
                        } else {
                            appearance = productType.getDefaultAppearance();
                        }
                    })
                    .seq(function() {
                        // determinate closest view for new product type
                        var currentView = self.$.view;

                        if (currentView) {
                            view = productType.getViewByPerspective(currentView.$.perspective);
                        }

                        if (!view) {
                            view = productType.getDefaultView();
                        }

                        // self.set('view', view);

                    })
                    .seq(function () {
                        // TODO: convert all configurations: size, position, print type

                        var configurations = self.$.configurations.$items,
                            removeConfigurations = [];

                        for (var i = 0; i < configurations.length; i++) {
                            var configuration = configurations[i],
                                currentPrintArea = configuration.$.printArea,
                                currentView = currentPrintArea.getDefaultView(),
                                targetView = null,
                                targetPrintArea = null;

                            if (currentView) {
                                targetView = productType.getViewByPerspective(currentView.$.perspective);
                            }

                            if (targetView) {
                                targetPrintArea = targetView.getDefaultPrintArea();
                            }

                            if (targetPrintArea) {
                                configuration.set('printArea', targetPrintArea);

                                var factor = targetPrintArea.get("boundary.size.width") / currentPrintArea.get("boundary.size.width");
                                configuration.set('scale', {
                                    x: configuration.$.scale.x * factor,
                                    y: configuration.$.scale.y * factor
                                });
                                configuration.$.offset.set({
                                    x: configuration.$.offset.$.x * factor,
                                    y: configuration.$.offset.$.y * factor
                                });

                            } else {
                                // no print area found, remove configuration
                                removeConfigurations.push(configuration);
                            }
                        }

                        self.$.configurations.remove(removeConfigurations);

                    })
                    .seq(function() {
                        // first set product type
                        self.set("productType", productType);
                        // and then the appearance, because appearance depends on product type
                        self.set("appearance", appearance);
                    })
                    .exec(callback)

            },

            addDesign: function (params, callback) {
                params = _.defaults({}, params, {
                    design: null,
                    perspective: null, // front, back, etc...
                    view: null,
                    printArea: null,
                    printType: null
                });

                var self = this,
                    design = params.design,
                    productType = this.$.productType,
                    printArea = params.printArea,
                    view = params.view,
                    appearance = this.$.appearance,
                    printType = params.printType;

                if (!design) {
                    callback(new Error("No design"));
                    return;
                }

                if (!productType) {
                    callback(new Error("ProductType not set"));
                    return;
                }

                if (!appearance) {
                    callback(new Error("Appearance for product not set"));
                    return;
                }

                flow()
                    .par(function (cb) {
                        design.fetch(null, cb);
                    }, function (cb) {
                        productType.fetch(null, cb);
                    })
                    .seq("printArea", function () {

                        if (!printArea && params.perspective && !view) {
                            view = productType.getViewByPerspective(params.perspective);
                        }

                        if (!printArea && view) {
                            // get print area by view
                            if (!productType.containsView(view)) {
                                throw new Error("View not on ProductType");
                            }

                            // TODO: look for print area that supports print types, etc...
                            printArea = view.getDefaultPrintArea();
                        }

                        view = self.$.view || self.getDefaultView();
                        if (!printArea && view) {
                            printArea = view.getDefaultPrintArea();
                        }

                        if (!printArea) {
                            throw new Error("target PrintArea couldn't be found.");
                        }

                        return printArea;
                    })
                    .seq("printType", function() {
                        var possiblePrintTypes = ProductUtil.getPossiblePrintTypesForDesignOnPrintArea(design, printArea, appearance.$.id);

                        if (printType && !_.contains(possiblePrintTypes, printType)) {
                            throw new Error("PrintType not possible for design and printArea");
                        }

                        printType = printType || possiblePrintTypes[0];

                        if (!printType) {
                            throw new Error("No printType available");
                        }

                        return printType;
                    })
                    .seq(function(cb) {
                        printType.fetch(null, cb);
                    })
                    .seq(function() {
                        var configuration = new DesignConfiguration({
                            printType: printType,
                            printArea: printArea,
                            design: design
                        });

                        self._addConfiguration(configuration);
                    })
                    .exec(callback)

            } ,

            compose: function(){
                var ret = this.callBase();

                ret.restrictions = {
                    freeColorSelection: false,
                    example: false
                };

                return ret;
            }
        });
    });
<|endoftext|>


<commit_before>/*global window:false, alert:false, jasmine:false, Node:false, */
/*jshint curly:false*/

'use strict';

var phantom = {};

if (window._phantom) {
  console.log = function(){
    phantom.sendMessage('verbose',Array.prototype.slice.apply(arguments).join(', '));
  };
}

phantom.sendMessage = function() {
  var args = [].slice.call( arguments );
  var payload = JSON.stringify( args );
  if (window._phantom) {
    // alerts are the communication bridge to grunt
    alert( payload );
  }
};

(function(){

  function PhantomReporter() {
    this.started = false;
    this.finished = false;
    this.suites_ = [];
    this.results_ = {};
    this.buffer = '';
  }

  PhantomReporter.prototype.reportRunnerStarting = function(runner) {
    this.started = true;

    var suites = runner.topLevelSuites();
    for (var i = 0; i < suites.length; i++) {
      var suite = suites[i];
      this.suites_.push(this.summarize_(suite));
    }
    phantom.sendMessage('jasmine.reportRunnerStarting', this.suites_);
  };

  PhantomReporter.prototype.reportSpecStarting = function(spec) {
    spec.startTime = (new Date()).getTime();
    var message = {
      suite : {
        description : spec.suite.description
      },
      description : spec.description
    };
    phantom.sendMessage('jasmine.reportSpecStarting', message);
  };

  PhantomReporter.prototype.suites = function() {
    return this.suites_;
  };

  PhantomReporter.prototype.summarize_ = function(suiteOrSpec) {
    var isSuite = suiteOrSpec instanceof jasmine.Suite;
    var summary = {
      id: suiteOrSpec.id,
      name: suiteOrSpec.description,
      type: isSuite ? 'suite' : 'spec',
      children: []
    };

    if (isSuite) {
      var children = suiteOrSpec.children();
      for (var i = 0; i < children.length; i++) {
        summary.children.push(this.summarize_(children[i]));
      }
    }
    return summary;
  };

  PhantomReporter.prototype.results = function() {
    return this.results_;
  };

  PhantomReporter.prototype.resultsForSpec = function(specId) {
    return this.results_[specId];
  };

  PhantomReporter.prototype.reportRunnerResults = function(runner) {
    this.finished = true;
    var specIds = runner.specs().map(function(a){return a.id;});
    var summary = this.resultsForSpecs(specIds);
    phantom.sendMessage('jasmine.reportRunnerResults',summary);
    phantom.sendMessage('jasmine.reportJUnitResults', this.generateJUnitSummary(runner));
    phantom.sendMessage('jasmine.done.PhantomReporter');
  };

  PhantomReporter.prototype.reportSuiteResults = function(suite) {
    if (suite.specs().length) {
      suite.timestamp = new Date();
      suite.duration = suite.timestamp.getTime() - suite.specs()[0].startTime;
      phantom.sendMessage('jasmine.reportSuiteResults',{
        description : suite.description,
        results : suite.results()
      });
    }
  };

  function stringify(obj) {
    if (typeof obj !== 'object') return obj;

    var cache = [], keyMap = [], index;

    var string = JSON.stringify(obj, function(key, value) {
      // Let json stringify falsy values
      if (!value) return value;

      // If we're a node
      if (value instanceof Node) return '[ Node ]';

      // If we're a window (logic stolen from jQuery)
      if (value.window && value.window === value.window.window) return '[ Window ]';

      // Simple function reporting
      if (typeof value === 'function') return '[ Function ]';

      if (typeof value === 'object' && value !== null) {

        if (index = cache.indexOf(value) !== -1) {
          // If we have it in cache, report the circle with the key we first found it in
          return '[ Circular {' + (keyMap[index] || 'root') + '} ]';
        }
        cache.push(value);
        keyMap.push(key);
      }
      return value;
    });
    return string;
  }

  PhantomReporter.prototype.reportSpecResults = function(spec) {
    spec.duration = (new Date()).getTime() - spec.startTime;
    var _results = spec.results();
    var results = {
      description : _results.description,
      messages    : _results.getItems(),
      failedCount : _results.failedCount,
      totalCount  : _results.totalCount,
      passedCount : _results.passedCount,
      skipped     : _results.skipped,
      passed      : _results.passed(),
      msg         : _results.failedCount > 0 ? "failed" : "passed"
    };
    this.results_[spec.id] = results;

    // Quick hack to alleviate cyclical object breaking JSONification.
    results.messages.forEach(function(item){
      if (item.expected) {
        item.expected = stringify(item.expected);
      }
      if (item.actual) {
        item.actual = stringify(item.actual);
      }
    });

    phantom.sendMessage( 'jasmine.reportSpecResults', spec.id, results, this.getFullName(spec));
  };

  PhantomReporter.prototype.getFullName = function(spec) {
    return getNestedSuiteName(spec.suite, ':: ') +  ':: ' + spec.description;
  };

  PhantomReporter.prototype.resultsForSpecs = function(specIds){
    var results = {};
    for (var i = 0; i < specIds.length; i++) {
      var specId = specIds[i];
      results[specId] = this.summarizeResult_(this.results_[specId]);
    }
    return results;
  };

  PhantomReporter.prototype.summarizeResult_ = function(result){
    var summaryMessages = [];
    var messagesLength = result.messages.length;
    for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) {
      var resultMessage = result.messages[messageIndex];
      summaryMessages.push({
        text: resultMessage.type === 'log' ? resultMessage.toString() : jasmine.undefined,
        passed: resultMessage.passed ? resultMessage.passed() : true,
        type: resultMessage.type,
        message: resultMessage.message,
        trace: {
          stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined
        }
      });
    }

    return {
      result : result.result,
      messages : summaryMessages
    };
  };

  function getNestedSuiteName(suite, sep) {
    var names = [];
    while (suite) {
      names.unshift(suite.description);
      suite = suite.parentSuite;
    }
    return names.join(sep ? sep : ' ');
  }

  function getTopLevelSuiteId(suite) {
    var id;
    while (suite) {
      id = suite.id;
      suite = suite.parentSuite;
    }
    return id;
  }

  PhantomReporter.prototype.generateJUnitSummary = function(runner) {
    var consolidatedSuites = {},
        suites = runner.suites().map(function(suite) {
          var failures = 0;

          var testcases = suite.specs().map(function(spec) {
            var failureMessages = [];
            if (spec.results().failedCount) {
              failures++;
              spec.results().items_.forEach(function(expectation) {
                if (!expectation.passed()) {
                  failureMessages.push(expectation.message);
                }
              });
            }
            return {
              assertions: spec.results().items_.length,
              className: getNestedSuiteName(spec.suite),
              name: spec.description,
              time: spec.duration / 1000,
              failureMessages: failureMessages
            };
          });

          var data = {
              name: getNestedSuiteName(suite),
              time: suite.duration / 1000,
              timestamp: suite.timestamp,
              tests: suite.specs().length,
              errors: 0, // TODO: These exist in the JUnit XML but not sure how they map to jasmine things
              testcases: testcases,
              failures: failures
            };

          if (suite.parentSuite) {
            consolidatedSuites[getTopLevelSuiteId(suite)].push(data);
          } else {
            consolidatedSuites[suite.id] = [data];
          }
          return data;
        });

    return {
      suites: suites,
      consolidatedSuites: consolidatedSuites
    };
  };

  jasmine.getEnv().addReporter( new PhantomReporter() );
}());
<commit_msg>Intercepts jasmine.Spec to stringify it as "[ Spec ]" instead of JSON.<commit_after>/*global window:false, alert:false, jasmine:false, Node:false, */
/*jshint curly:false*/

'use strict';

var phantom = {};

if (window._phantom) {
  console.log = function(){
    phantom.sendMessage('verbose',Array.prototype.slice.apply(arguments).join(', '));
  };
}

phantom.sendMessage = function() {
  var args = [].slice.call( arguments );
  var payload = JSON.stringify( args );
  if (window._phantom) {
    // alerts are the communication bridge to grunt
    alert( payload );
  }
};

(function(){

  function PhantomReporter() {
    this.started = false;
    this.finished = false;
    this.suites_ = [];
    this.results_ = {};
    this.buffer = '';
  }

  PhantomReporter.prototype.reportRunnerStarting = function(runner) {
    this.started = true;

    var suites = runner.topLevelSuites();
    for (var i = 0; i < suites.length; i++) {
      var suite = suites[i];
      this.suites_.push(this.summarize_(suite));
    }
    phantom.sendMessage('jasmine.reportRunnerStarting', this.suites_);
  };

  PhantomReporter.prototype.reportSpecStarting = function(spec) {
    spec.startTime = (new Date()).getTime();
    var message = {
      suite : {
        description : spec.suite.description
      },
      description : spec.description
    };
    phantom.sendMessage('jasmine.reportSpecStarting', message);
  };

  PhantomReporter.prototype.suites = function() {
    return this.suites_;
  };

  PhantomReporter.prototype.summarize_ = function(suiteOrSpec) {
    var isSuite = suiteOrSpec instanceof jasmine.Suite;
    var summary = {
      id: suiteOrSpec.id,
      name: suiteOrSpec.description,
      type: isSuite ? 'suite' : 'spec',
      children: []
    };

    if (isSuite) {
      var children = suiteOrSpec.children();
      for (var i = 0; i < children.length; i++) {
        summary.children.push(this.summarize_(children[i]));
      }
    }
    return summary;
  };

  PhantomReporter.prototype.results = function() {
    return this.results_;
  };

  PhantomReporter.prototype.resultsForSpec = function(specId) {
    return this.results_[specId];
  };

  PhantomReporter.prototype.reportRunnerResults = function(runner) {
    this.finished = true;
    var specIds = runner.specs().map(function(a){return a.id;});
    var summary = this.resultsForSpecs(specIds);
    phantom.sendMessage('jasmine.reportRunnerResults',summary);
    phantom.sendMessage('jasmine.reportJUnitResults', this.generateJUnitSummary(runner));
    phantom.sendMessage('jasmine.done.PhantomReporter');
  };

  PhantomReporter.prototype.reportSuiteResults = function(suite) {
    if (suite.specs().length) {
      suite.timestamp = new Date();
      suite.duration = suite.timestamp.getTime() - suite.specs()[0].startTime;
      phantom.sendMessage('jasmine.reportSuiteResults',{
        description : suite.description,
        results : suite.results()
      });
    }
  };

  function stringify(obj) {
    if (typeof obj !== 'object') return obj;

    var cache = [], keyMap = [], index;

    var string = JSON.stringify(obj, function(key, value) {
      // Let json stringify falsy values
      if (!value) return value;

      // If we're a node
      if (value instanceof Node) return '[ Node ]';

      // jasmine-given has expectations on Specs. We intercept to return a
      // String to avoid stringifying the entire Jasmine environment, which
      // results in exponential string growth
      if (value instanceof jasmine.Spec) return '[ Spec: ' + value.description + ' ]';

      // If we're a window (logic stolen from jQuery)
      if (value.window && value.window === value.window.window) return '[ Window ]';

      // Simple function reporting
      if (typeof value === 'function') return '[ Function ]';

      if (typeof value === 'object' && value !== null) {

        if (index = cache.indexOf(value) !== -1) {
          // If we have it in cache, report the circle with the key we first found it in
          return '[ Circular {' + (keyMap[index] || 'root') + '} ]';
        }
        cache.push(value);
        keyMap.push(key);
      }
      return value;
    });
    return string;
  }

  PhantomReporter.prototype.reportSpecResults = function(spec) {
    spec.duration = (new Date()).getTime() - spec.startTime;
    var _results = spec.results();
    var results = {
      description : _results.description,
      messages    : _results.getItems(),
      failedCount : _results.failedCount,
      totalCount  : _results.totalCount,
      passedCount : _results.passedCount,
      skipped     : _results.skipped,
      passed      : _results.passed(),
      msg         : _results.failedCount > 0 ? "failed" : "passed"
    };
    this.results_[spec.id] = results;

    // Quick hack to alleviate cyclical object breaking JSONification.
    results.messages.forEach(function(item){
      if (item.expected) {
        item.expected = stringify(item.expected);
      }
      if (item.actual) {
        item.actual = stringify(item.actual);
      }
    });

    phantom.sendMessage( 'jasmine.reportSpecResults', spec.id, results, this.getFullName(spec));
  };

  PhantomReporter.prototype.getFullName = function(spec) {
    return getNestedSuiteName(spec.suite, ':: ') +  ':: ' + spec.description;
  };

  PhantomReporter.prototype.resultsForSpecs = function(specIds){
    var results = {};
    for (var i = 0; i < specIds.length; i++) {
      var specId = specIds[i];
      results[specId] = this.summarizeResult_(this.results_[specId]);
    }
    return results;
  };

  PhantomReporter.prototype.summarizeResult_ = function(result){
    var summaryMessages = [];
    var messagesLength = result.messages.length;
    for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) {
      var resultMessage = result.messages[messageIndex];
      summaryMessages.push({
        text: resultMessage.type === 'log' ? resultMessage.toString() : jasmine.undefined,
        passed: resultMessage.passed ? resultMessage.passed() : true,
        type: resultMessage.type,
        message: resultMessage.message,
        trace: {
          stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined
        }
      });
    }

    return {
      result : result.result,
      messages : summaryMessages
    };
  };

  function getNestedSuiteName(suite, sep) {
    var names = [];
    while (suite) {
      names.unshift(suite.description);
      suite = suite.parentSuite;
    }
    return names.join(sep ? sep : ' ');
  }

  function getTopLevelSuiteId(suite) {
    var id;
    while (suite) {
      id = suite.id;
      suite = suite.parentSuite;
    }
    return id;
  }

  PhantomReporter.prototype.generateJUnitSummary = function(runner) {
    var consolidatedSuites = {},
        suites = runner.suites().map(function(suite) {
          var failures = 0;

          var testcases = suite.specs().map(function(spec) {
            var failureMessages = [];
            if (spec.results().failedCount) {
              failures++;
              spec.results().items_.forEach(function(expectation) {
                if (!expectation.passed()) {
                  failureMessages.push(expectation.message);
                }
              });
            }
            return {
              assertions: spec.results().items_.length,
              className: getNestedSuiteName(spec.suite),
              name: spec.description,
              time: spec.duration / 1000,
              failureMessages: failureMessages
            };
          });

          var data = {
              name: getNestedSuiteName(suite),
              time: suite.duration / 1000,
              timestamp: suite.timestamp,
              tests: suite.specs().length,
              errors: 0, // TODO: These exist in the JUnit XML but not sure how they map to jasmine things
              testcases: testcases,
              failures: failures
            };

          if (suite.parentSuite) {
            consolidatedSuites[getTopLevelSuiteId(suite)].push(data);
          } else {
            consolidatedSuites[suite.id] = [data];
          }
          return data;
        });

    return {
      suites: suites,
      consolidatedSuites: consolidatedSuites
    };
  };

  jasmine.getEnv().addReporter( new PhantomReporter() );
}());
<|endoftext|>


<commit_before>/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50, white: true bitwise:true continue: true */
/*global vec2, vec3, vec4,
         Actor, Script, Physics, Box2D,
         renderer, directions, Blob, $ */

function Collision(actor, direction)
{
    'use strict';

    this.actor     = actor;
    this.direction = direction;
}

function DynamicActor(name, position, scale, rotation, color, type)
{
    'use strict';

    Actor.call(this, position, scale, rotation, color);

    this.name       = name;
    this.type       = type;
    this.actorClass = "";
    this.script     = null;
    this.body       = null;

    this.collisions = [];
}

DynamicActor.prototype = Object.create(Actor.prototype);
DynamicActor.prototype.constructor = DynamicActor;

DynamicActor.prototype.checkCollisions = function(actorClass,
                                                   direction)
{
    'use strict';

    var i = 0;

    for(i = 0; i < this.collisions.length; i++)
    {
        if((actorClass !== "" || this.collisions[i].actor.actorClass === actorClass) &&
           (direction === directions.Any || direction === this.collisions[i].direction))
        {
            return true;
        }
    }
};

function Game()
{
    'use strict';

    this.physics = null;
    this.actors  = [];
    this.scripts = [];

    this.player = null;

    this.running = false;

    this.gravity = -10;
}

Game.prototype.update = function(dt)
{
    'use strict';

    //Sort actors by depth
    this.actors.sort(function(actor1, actor2)
      {
            if (actor1.position[2] < actor2.position[2])
            {
                return true;
            } else
            {
                return false;
            }
      });

    //Update

    if(!this.running)
    {
        return;
    }

    this.runScripts();

    var i;

    //Clear collisions
    /*
    for(i = 0; i < this.actors.length; i++)
    {
        this.actors[i].collisions = [];
    }
    */

    this.physics.world.Step(dt, //frame-rate
                            10,     //velocity iterations
                            10);    //position iterations

    this.physics.world.ClearForces();

    //Update positions

    for(i = 0; i < this.actors.length; i++)
    {
        var actor = this.actors[i];

        actor.position[0] = actor.body.GetPosition().x;
        actor.position[1] = actor.body.GetPosition().y;
        actor.rotation    = actor.body.GetAngle();
        actor.updateWorld();
    }

    if(this.player !== null)
    {
        renderer.setCameraPosition(this.player.position[0],
                                   this.player.position[1],
                                   0);
    }
};

Game.prototype.runScripts = function()
{
    'use strict';

    var i;
    var j;
    var k;

    for(i = 0; i < this.actors.length; i++)
    {
        var actor = this.actors[i];

        if(actor.script === null || actor.script === undefined)
        {
            continue;
        }

        for(j = 0; j < actor.script.rules.length; j++)
        {
            var rule = actor.script.rules[j];

            var flag = true;

            //Check conditions
            for(k = 0; k < rule.conditions.length; k++)
            {
                var condition = rule.conditions[k];

                if(!condition.snippet.func(actor, condition.args))
                {
                    if(!condition.args.not)
                    {
                        flag = false;
                    }
                } else if(condition.args.not)
                {
                    flag = false;
                }
            }

            if(!flag) //If not all conditions are met
            {
                continue;
            }

            //Execute actions
            for(k = 0; k < rule.actions.length; k++)
            {
                var action = rule.actions[k];
                action.snippet.func(actor, action.args);
            }
        }
    }
};

Game.prototype.addActor = function(position, scale, rotation, color, type)
{
    'use strict';

    var x = new DynamicActor("actor"+this.actors.length,
                             position,
                             scale, rotation,
                             color, type);

    x.updateWorld();

    this.actors.push(x);

    return x;
};

Game.prototype.newScript = function()
{
    'use strict';

    var x = new Script("script"+this.scripts.length);

    this.scripts.push(x);

    return x;
};

var contactListener = new Box2D.Dynamics.b2ContactListener();

contactListener.BeginContact = function(contact)
{
   'use strict';

    var a = contact.GetFixtureA().GetBody().GetUserData();
    var b = contact.GetFixtureB().GetBody().GetUserData();

    var w_manifold = new Box2D.Collision.b2WorldManifold();
    contact.GetWorldManifold(w_manifold);

    var x = Math.atan2(w_manifold.m_normal.y, w_manifold.m_normal.x);
    x = 180*x/Math.PI;

    var dir1;
    var dir2;

    if(x >= -45 && x <= 45)
    {
        dir1 = directions.Right;
        dir2 = directions.Left;
    } else if(x >= 45 && x <= 135)
    {
        dir1 = directions.Top;
        dir2 = directions.Bottom;
    } else if( (x >= 135 && x <= 180) || (x >= -180 && x <= -135))
    {
        dir1 = directions.Left;
        dir2 = directions.Right;
    } else if(x >= -135 && x <= -45)
    {
        dir1 = directions.Bottom;
        dir2 = directions.Top;
    }

    a.collisions.push(new Collision(b, dir1));
    b.collisions.push(new Collision(a, dir2));
};

contactListener.EndContact = function(contact)
{
   'use strict';

    var a = contact.GetFixtureA().GetBody().GetUserData();
    var b = contact.GetFixtureB().GetBody().GetUserData();

    var w_manifold = new Box2D.Collision.b2WorldManifold();
    contact.GetWorldManifold(w_manifold);

    var x = Math.atan2(w_manifold.m_normal.y, w_manifold.m_normal.x);
    x = 180*x/Math.PI;

    var dir1;
    var dir2;

    if(x >= -45 && x <= 45)
    {
        dir1 = directions.Right;
        dir2 = directions.Left;
    } else if(x >= 45 && x <= 135)
    {
        dir1 = directions.Top;
        dir2 = directions.Bottom;
    } else if( (x >= 135 && x <= 180) || (x >= -180 && x <= -135))
    {
        dir1 = directions.Left;
        dir2 = directions.Right;
    } else if(x >= -135 && x <= -45)
    {
        dir1 = directions.Bottom;
        dir2 = directions.Top;
    }

    var i;

    for(i = 0; i < a.collisions.length; i++)
    {
        if(a.collisions[i].actor === b)
        {
            a.collisions.splice(i);
            break;
        }
    }

    for(i = 0; i < b.collisions.length; i++)
    {
        if(b.collisions[i].actor === a)
        {
            b.collisions.splice(i);
            break;
        }
    }
};

Game.prototype.restartPhysics = function()
{
    'use strict';

    this.physics = new Physics(this.gravity);
    this.physics.world.SetContactListener(contactListener);

    var i;

    for(i = 0; i < this.actors.length; i++)
    {
        var actor = this.actors[i];

        actor.body = this.physics.createBox(actor.position[0],
                                            actor.position[1],
                                            actor.scale[0]/2,
                                            actor.scale[1]/2,
                                            actor.type);

        actor.body.SetUserData(actor);
    }
};

Game.prototype.clone = function()
{
    'use strict';

    var clone = new Game();

    clone.scripts = this.scripts;

    var i;

    for(i = 0; i < this.actors.length; i++)
    {
        var actor = this.actors[i];

        var x = clone.addActor(vec3.clone(actor.position),
                               vec3.clone(actor.scale),
                               actor.rotation,
                               vec4.clone(actor.color),
                               actor.type);

        x.actorClass = actor.actorClass;
        x.script     = actor.script;
    }

    if(this.player !== null)
    {
        var playerIndex = this.actors.indexOf(this.player);
        clone.player = clone.actors[playerIndex];
    }

    clone.gravity = this.gravity;

    return clone;
};

Game.prototype.save = function()
{
    'use strict';

    var x = "";

    return x;
};
<commit_msg>Bug fixes.<commit_after>/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50, white: true bitwise:true continue: true */
/*global vec2, vec3, vec4,
         Actor, Script, Physics, Box2D,
         renderer, directions, Blob, $ */

function Collision(actor, direction)
{
    'use strict';

    this.actor     = actor;
    this.direction = direction;
}

function DynamicActor(name, position, scale, rotation, color, type)
{
    'use strict';

    Actor.call(this, position, scale, rotation, color);

    this.name       = name;
    this.type       = type;
    this.actorClass = "";
    this.script     = null;
    this.body       = null;

    this.collisions = [];
}

DynamicActor.prototype = Object.create(Actor.prototype);
DynamicActor.prototype.constructor = DynamicActor;

DynamicActor.prototype.checkCollisions = function(actorClass,
                                                   direction)
{
    'use strict';

    var i = 0;

    for(i = 0; i < this.collisions.length; i++)
    {
        if((actorClass === "" || this.collisions[i].actor.actorClass === actorClass) &&
           (direction === directions.Any || direction === this.collisions[i].direction))
        {
            return true;
        }
    }
};

function Game()
{
    'use strict';

    this.physics = null;
    this.actors  = [];
    this.scripts = [];

    this.player = null;

    this.running = false;

    this.gravity = -10;
}

Game.prototype.update = function(dt)
{
    'use strict';

    //Sort actors by depth
    this.actors.sort(function(actor1, actor2)
      {
            if (actor1.position[2] < actor2.position[2])
            {
                return true;
            } else
            {
                return false;
            }
      });

    //Update

    if(!this.running)
    {
        return;
    }

    this.runScripts();

    var i;

    //Clear collisions
    /*
    for(i = 0; i < this.actors.length; i++)
    {
        this.actors[i].collisions = [];
    }
    */

    this.physics.world.Step(dt, //frame-rate
                            10,     //velocity iterations
                            10);    //position iterations

    this.physics.world.ClearForces();

    //Update positions

    for(i = 0; i < this.actors.length; i++)
    {
        var actor = this.actors[i];

        actor.position[0] = actor.body.GetPosition().x;
        actor.position[1] = actor.body.GetPosition().y;
        actor.rotation    = actor.body.GetAngle();
        actor.updateWorld();
    }

    if(this.player !== null)
    {
        renderer.setCameraPosition(this.player.position[0],
                                   this.player.position[1],
                                   0);
    }
};

Game.prototype.runScripts = function()
{
    'use strict';

    var i;
    var j;
    var k;

    for(i = 0; i < this.actors.length; i++)
    {
        var actor = this.actors[i];

        if(actor.script === null || actor.script === undefined)
        {
            continue;
        }

        for(j = 0; j < actor.script.rules.length; j++)
        {
            var rule = actor.script.rules[j];

            var flag = true;

            //Check conditions
            for(k = 0; k < rule.conditions.length; k++)
            {
                var condition = rule.conditions[k];

                if(!condition.snippet.func(actor, condition.args))
                {
                    if(!condition.args.not)
                    {
                        flag = false;
                    }
                } else if(condition.args.not)
                {
                    flag = false;
                }
            }

            if(!flag) //If not all conditions are met
            {
                continue;
            }

            //Execute actions
            for(k = 0; k < rule.actions.length; k++)
            {
                var action = rule.actions[k];
                action.snippet.func(actor, action.args);
            }
        }
    }
};

Game.prototype.addActor = function(position, scale, rotation, color, type)
{
    'use strict';

    var x = new DynamicActor("actor"+this.actors.length,
                             position,
                             scale, rotation,
                             color, type);

    x.updateWorld();

    this.actors.push(x);

    return x;
};

Game.prototype.newScript = function()
{
    'use strict';

    var x = new Script("script"+this.scripts.length);

    this.scripts.push(x);

    return x;
};

var contactListener = new Box2D.Dynamics.b2ContactListener();

contactListener.BeginContact = function(contact)
{
   'use strict';

    var a = contact.GetFixtureA().GetBody().GetUserData();
    var b = contact.GetFixtureB().GetBody().GetUserData();

    var w_manifold = new Box2D.Collision.b2WorldManifold();
    contact.GetWorldManifold(w_manifold);

    var x = Math.atan2(w_manifold.m_normal.y, w_manifold.m_normal.x);
    x = 180*x/Math.PI;

    var dir1;
    var dir2;

    if(x >= -45 && x <= 45)
    {
        dir1 = directions.Right;
        dir2 = directions.Left;
    } else if(x >= 45 && x <= 135)
    {
        dir1 = directions.Top;
        dir2 = directions.Bottom;
    } else if( (x >= 135 && x <= 180) || (x >= -180 && x <= -135))
    {
        dir1 = directions.Left;
        dir2 = directions.Right;
    } else if(x >= -135 && x <= -45)
    {
        dir1 = directions.Bottom;
        dir2 = directions.Top;
    }

    a.collisions.push(new Collision(b, dir1));
    b.collisions.push(new Collision(a, dir2));
};

contactListener.EndContact = function(contact)
{
   'use strict';

    var a = contact.GetFixtureA().GetBody().GetUserData();
    var b = contact.GetFixtureB().GetBody().GetUserData();

    var w_manifold = new Box2D.Collision.b2WorldManifold();
    contact.GetWorldManifold(w_manifold);

    var x = Math.atan2(w_manifold.m_normal.y, w_manifold.m_normal.x);
    x = 180*x/Math.PI;

    var dir1;
    var dir2;

    if(x >= -45 && x <= 45)
    {
        dir1 = directions.Right;
        dir2 = directions.Left;
    } else if(x >= 45 && x <= 135)
    {
        dir1 = directions.Top;
        dir2 = directions.Bottom;
    } else if( (x >= 135 && x <= 180) || (x >= -180 && x <= -135))
    {
        dir1 = directions.Left;
        dir2 = directions.Right;
    } else if(x >= -135 && x <= -45)
    {
        dir1 = directions.Bottom;
        dir2 = directions.Top;
    }

    var i;

    for(i = 0; i < a.collisions.length; i++)
    {
        if(a.collisions[i].actor === b)
        {
            a.collisions.splice(i);
            break;
        }
    }

    for(i = 0; i < b.collisions.length; i++)
    {
        if(b.collisions[i].actor === a)
        {
            b.collisions.splice(i);
            break;
        }
    }
};

Game.prototype.restartPhysics = function()
{
    'use strict';

    this.physics = new Physics(this.gravity);
    this.physics.world.SetContactListener(contactListener);

    var i;

    for(i = 0; i < this.actors.length; i++)
    {
        var actor = this.actors[i];

        actor.body = this.physics.createBox(actor.position[0],
                                            actor.position[1],
                                            actor.scale[0]/2,
                                            actor.scale[1]/2,
                                            actor.type);

        actor.body.SetUserData(actor);
    }
};

Game.prototype.clone = function()
{
    'use strict';

    var clone = new Game();

    clone.scripts = this.scripts;

    var i;

    for(i = 0; i < this.actors.length; i++)
    {
        var actor = this.actors[i];

        var x = clone.addActor(vec3.clone(actor.position),
                               vec3.clone(actor.scale),
                               actor.rotation,
                               vec4.clone(actor.color),
                               actor.type);

        x.actorClass = actor.actorClass;
        x.script     = actor.script;
    }

    if(this.player !== null)
    {
        var playerIndex = this.actors.indexOf(this.player);
        clone.player = clone.actors[playerIndex];
    }

    clone.gravity = this.gravity;

    return clone;
};

Game.prototype.save = function()
{
    'use strict';

    var x = "";

    return x;
};
<|endoftext|>


<commit_before>var fs        = require('fs');
var path      = require('path');
var exec      = require('child_process').exec;
var http      = require('http');
var recursive = require('recursive-readdir');

var removeWWW = function(url) {
	if(url.indexOf('www') > -1)
		return url.substring(4, url.length);

	return url;
};

var removePort = function(host) {
	indexOfPort = host.indexOf(':');

	if(indexOfPort > -1)
		return host.substring(0, indexOfPort);

	return host;
};

var getFileType = function(file) {
	var suffix = '';
	for (var i = file.length - 1; i >= 0 && file[i] != '.'; i--) {
		suffix += file[i];
	}

	return suffix.split('').reverse().join('');
};

var getFilesFromDirectory = function(directory, callback) {
	var ignoreFunc = function(file, stats) {
	  return (stats.isDirectory() &&
	  		 (path.basename(file) == 'node_modules' ||
	  		  path.basename(file) == '.git'));
	};

	recursive(directory, ['.htaccess', ignoreFunc], function (err, files) {
	  callback(files);
	});
};

var constructURLFromPath = function(dom, filepath) {
	var index = filepath.indexOf(dom.baseDirectory);
	if(index > -1) {
		return filepath.substring(index + dom.baseDirectory.length, filepath.length);
	}

	return '';
};

var executePHP = function(res, file) {
	var cmd = 'php ' + file;
	exec(cmd, function(error, stdout, stderr) {
		res.writeHead(200, {'Content-Type':'text/html'});
		res.end(stdout);
	});
};

SimpleServer = function() {
	var self            = this;
	this.dispatcher     = require('httpdispatcher');
	this.domains        = [];
	this.port           = 8080;
	this.domainIndexSet = {};
	this.mimeTypeLookup = require('mime-types').lookup;

	this.server         = http.createServer(function(req, res) {
		try {
			var requestedHost = req.headers.host;
			requestedHost     = removeWWW(requestedHost);
			requestedHost     = removePort(requestedHost);

			for(var i in self.domains) {
				if(requestedHost == self.domains[i].host)
					self.domains[i].dispatcher.dispatch(req, res);
			}

	        // self.dispatcher.dispatch(req, res);
	    }
	    catch(err) {
	        console.log(err);
	    }
	});
};

SimpleServer.prototype.setPort = function(port) {
	this.port = port;
};

SimpleServer.prototype.generateDispatcherRequest = function(dom, file) {
	var requestURL = constructURLFromPath(dom, file);
	var mimeType   = this.mimeTypeLookup(getFileType(file));

	var handleGetRequest = function(req, res) {
		if(getFileType(file) == 'php')
			executePHP(res, file);
		else {
			res.writeHead(200, {'Content-Type': mimeType});

			fs.readFile(file, function(error, response) {
				res.end(response);
			});
		}
	};

	var handlePostRequest = function(req, res) {
		if(getFileType(file) == 'php')
			executePHP(res, file);
		else {
			res.writeHead(200, {'Content-Type': mimeType});

			fs.readFile(file, function(error, response) {
				res.end(response);
			});
		}

		if(dom.onPost !== undefined)
			dom.onPost(req.params, file);
	};

	dom.dispatcher.onGet(requestURL, handleGetRequest);
	dom.dispatcher.onPost(requestURL, handlePostRequest);

	if(this.domainIndexSet[dom.host] === undefined && requestURL.indexOf('index') > -1) {
		dom.dispatcher.onGet('/', handleGetRequest);
		dom.dispatcher.onPost('/', handlePostRequest);
		this.domainIndexSet[dom.host] = true;
	}
};

SimpleServer.prototype.setupNewDomain = function(dom) {
	dom.host       = removeWWW(dom.host);
	dom.dispatcher = require('httpdispatcher');
	var self       = this;
	getFilesFromDirectory(dom.baseDirectory, function(files) {
		if(files !== undefined) {
			for (var i = files.length - 1; i >= 0; i--) {
				if(dom.allowedFileTypes == '*' || dom.allowedFileTypes.indexOf(getFileType(files[i])) > -1) {
					var file = files[i];
					self.generateDispatcherRequest(dom, file);
				}
			}
		}
	});

	dom.dispatcher.onError(function(req, res) {
	    res.writeHead(404);
	    res.end('404 - Page does not exist.');
	});
};

/*
 * This function takes a JSON object with the
 * following fields:
 * - host
 * - baseDirectory
 * - allowedFileTypes (optional)
 */
SimpleServer.prototype.addDomain = function(dom) {
	// if(dom.host.indexOf(':') == -1)
	// 	dom.host += (':' + this.port);

    this.domains.push(dom);
    this.setupNewDomain(dom);
};

//Takes an array of JSON objects as described above
SimpleServer.prototype.addDomains = function(doms) {
	for (var key in doms) {
		if(key !== undefined) {
			this.addDomain(doms[key]);
		}
	}
};

SimpleServer.prototype.setAllowedFileTypes = function(host, types) {
    for (var i = this.domains.length - 1; i >= 0; i--) {
        if(this.domains[i].host == host) {
            this.domains[i].allowedFileTypes = types;
            break;
        }
    }
};

SimpleServer.prototype.start = function() {
	var self = this;
	this.server.listen(this.port, function(){
	    console.log('Listening on: http://localhost:%s', self.port);
	});
};

module.exports = new SimpleServer();<commit_msg>Added debugging info...<commit_after>var fs        = require('fs');
var path      = require('path');
var exec      = require('child_process').exec;
var http      = require('http');
var recursive = require('recursive-readdir');

var removeWWW = function(url) {
	if(url.indexOf('www') > -1)
		return url.substring(4, url.length);

	return url;
};

var removePort = function(host) {
	indexOfPort = host.indexOf(':');

	if(indexOfPort > -1)
		return host.substring(0, indexOfPort);

	return host;
};

var getFileType = function(file) {
	var suffix = '';
	for (var i = file.length - 1; i >= 0 && file[i] != '.'; i--) {
		suffix += file[i];
	}

	return suffix.split('').reverse().join('');
};

var getFilesFromDirectory = function(directory, callback) {
	var ignoreFunc = function(file, stats) {
	  return (stats.isDirectory() &&
	  		 (path.basename(file) == 'node_modules' ||
	  		  path.basename(file) == '.git'));
	};

	recursive(directory, ['.htaccess', ignoreFunc], function (err, files) {
	  callback(files);
	});
};

var constructURLFromPath = function(dom, filepath) {
	var index = filepath.indexOf(dom.baseDirectory);
	if(index > -1) {
		return filepath.substring(index + dom.baseDirectory.length, filepath.length);
	}

	return '';
};

var executePHP = function(res, file) {
	var cmd = 'php ' + file;
	exec(cmd, function(error, stdout, stderr) {
		res.writeHead(200, {'Content-Type':'text/html'});
		res.end(stdout);
	});
};

SimpleServer = function() {
	var self            = this;
	this.dispatcher     = require('httpdispatcher');
	this.domains        = [];
	this.port           = 8080;
	this.domainIndexSet = {};
	this.mimeTypeLookup = require('mime-types').lookup;

	this.server         = http.createServer(function(req, res) {
		try {
			var requestedHost = req.headers.host;
			requestedHost     = removeWWW(requestedHost);
			requestedHost     = removePort(requestedHost);
			console.log('Received request for: ' + requestedHost);

			for(var i in self.domains) {
				if(requestedHost == self.domains[i].host) {
					console.log('Sending request to dom: ' + self.domains[i].host);
					self.domains[i].dispatcher.dispatch(req, res);
				}
			}

	        // self.dispatcher.dispatch(req, res);
	    }
	    catch(err) {
	        console.log(err);
	    }
	});
};

SimpleServer.prototype.setPort = function(port) {
	this.port = port;
};

SimpleServer.prototype.generateDispatcherRequest = function(dom, file) {
	var requestURL = constructURLFromPath(dom, file);
	var mimeType   = this.mimeTypeLookup(getFileType(file));

	var handleGetRequest = function(req, res) {
		if(getFileType(file) == 'php')
			executePHP(res, file);
		else {
			res.writeHead(200, {'Content-Type': mimeType});

			fs.readFile(file, function(error, response) {
				res.end(response);
			});
		}
	};

	var handlePostRequest = function(req, res) {
		if(getFileType(file) == 'php')
			executePHP(res, file);
		else {
			res.writeHead(200, {'Content-Type': mimeType});

			fs.readFile(file, function(error, response) {
				res.end(response);
			});
		}

		if(dom.onPost !== undefined)
			dom.onPost(req.params, file);
	};

	dom.dispatcher.onGet(requestURL, handleGetRequest);
	dom.dispatcher.onPost(requestURL, handlePostRequest);

	console.log('Mapping file to dom: ', 'File: ' + file, 'Domain: ' + dom.host);

	if(this.domainIndexSet[dom.host] === undefined && requestURL.indexOf('index') > -1) {
		dom.dispatcher.onGet('/', handleGetRequest);
		dom.dispatcher.onPost('/', handlePostRequest);
		this.domainIndexSet[dom.host] = true;
	}
};

SimpleServer.prototype.setupNewDomain = function(dom) {
	console.log('Setting up domain: ' + dom.host);
	dom.host       = removeWWW(dom.host);
	dom.dispatcher = require('httpdispatcher');
	var self       = this;
	getFilesFromDirectory(dom.baseDirectory, function(files) {
		if(files !== undefined) {
			for (var i = files.length - 1; i >= 0; i--) {
				if(dom.allowedFileTypes == '*' || dom.allowedFileTypes.indexOf(getFileType(files[i])) > -1) {
					var file = files[i];
					self.generateDispatcherRequest(dom, file);
				}
			}
		}
	});

	dom.dispatcher.onError(function(req, res) {
	    res.writeHead(404);
	    res.end('404 - Page does not exist.');
	});
};

/*
 * This function takes a JSON object with the
 * following fields:
 * - host
 * - baseDirectory
 * - allowedFileTypes (optional)
 */
SimpleServer.prototype.addDomain = function(dom) {
	this.domains.push(dom);
    this.setupNewDomain(dom);
};

//Takes an array of JSON objects as described above
SimpleServer.prototype.addDomains = function(doms) {
	for (var key in doms) {
		if(key !== undefined) {
			this.addDomain(doms[key]);
		}
	}
};

SimpleServer.prototype.setAllowedFileTypes = function(host, types) {
    for (var i = this.domains.length - 1; i >= 0; i--) {
        if(this.domains[i].host == host) {
            this.domains[i].allowedFileTypes = types;
            break;
        }
    }
};

SimpleServer.prototype.start = function() {
	var self = this;
	this.server.listen(this.port, function(){
	    console.log('Listening on: http://localhost:%s', self.port);
	});
};

module.exports = new SimpleServer();<|endoftext|>


<commit_before>import React from 'react';
import classNames from 'classnames';
import bootstrapUtils, { bsStyles, bsClass } from './utils/bootstrapUtils';
import { State } from './styleMaps';

let Alert = React.createClass({

  propTypes: {
    onDismiss: React.PropTypes.func,
    dismissAfter: React.PropTypes.number,
    closeLabel: React.PropTypes.string
  },

  getDefaultProps() {
    return {
      closeLabel: 'Close Alert'
    };
  },

  renderDismissButton() {
    return (
      <button
        type="button"
        className="close"
        onClick={this.props.onDismiss}
        aria-hidden="true">
        ×
      </button>
    );
  },

  renderSrOnlyDismissButton() {
    return (
      <button
        type="button"
        className="close sr-only"
        onClick={this.props.onDismiss}>
        {this.props.closeLabel}
      </button>
    );
  },

  render() {
    let classes = bootstrapUtils.getClassSet(this.props);
    let isDismissable = !!this.props.onDismiss;

    classes[bootstrapUtils.prefix(this.props, 'dismissable')] = isDismissable;

    return (

        {isDismissable ? this.renderDismissButton() : null}
        {this.props.children}
        {isDismissable ? this.renderSrOnlyDismissButton() : null}

    );
  },

  componentDidMount() {
    if (this.props.dismissAfter && this.props.onDismiss) {
      this.dismissTimer = setTimeout(this.props.onDismiss, this.props.dismissAfter);
    }
  },

  componentWillUnmount() {
    clearTimeout(this.dismissTimer);
  }
});

export default bsStyles(State.values(), State.INFO,
  bsClass('alert', Alert)
);
<commit_msg>[fixed] a11y: setting tabIndex="-1" for the dismiss button of Alerts since aria-hidden="true"<commit_after>import React from 'react';
import classNames from 'classnames';
import bootstrapUtils, { bsStyles, bsClass } from './utils/bootstrapUtils';
import { State } from './styleMaps';

let Alert = React.createClass({

  propTypes: {
    onDismiss: React.PropTypes.func,
    dismissAfter: React.PropTypes.number,
    closeLabel: React.PropTypes.string
  },

  getDefaultProps() {
    return {
      closeLabel: 'Close Alert'
    };
  },

  renderDismissButton() {
    return (
      <button
        type="button"
        className="close"
        onClick={this.props.onDismiss}
        aria-hidden="true"
        tabIndex="-1">
        ×
      </button>
    );
  },

  renderSrOnlyDismissButton() {
    return (
      <button
        type="button"
        className="close sr-only"
        onClick={this.props.onDismiss}>
        {this.props.closeLabel}
      </button>
    );
  },

  render() {
    let classes = bootstrapUtils.getClassSet(this.props);
    let isDismissable = !!this.props.onDismiss;

    classes[bootstrapUtils.prefix(this.props, 'dismissable')] = isDismissable;

    return (

        {isDismissable ? this.renderDismissButton() : null}
        {this.props.children}
        {isDismissable ? this.renderSrOnlyDismissButton() : null}

    );
  },

  componentDidMount() {
    if (this.props.dismissAfter && this.props.onDismiss) {
      this.dismissTimer = setTimeout(this.props.onDismiss, this.props.dismissAfter);
    }
  },

  componentWillUnmount() {
    clearTimeout(this.dismissTimer);
  }
});

export default bsStyles(State.values(), State.INFO,
  bsClass('alert', Alert)
);
<|endoftext|>


<commit_before>/*jslint node: true */
'use strict';

var lodash = require('lodash'),
    jjv = require('jjv'),
    REQ = require('request'),
    when = require('when'),

AValidator = {
    normalizeError: function (V, I) {
        return {
            type: 'validation',
            target: I,
            rule: V
        };
    },
    promiseAll: function (list) {
        return when.all(lodash.map(list, AValidator.promise));
    },
    request: function (D, cb) {
        if (!lodash.isFunction(cb)) {
            throw {
                error: [{
                    'type': 'input',
                    message: 'No callback for AValidator.request'
                }]
            };
        }

        if (!D) {
            return cb({
                error: [{
                    'type': 'input',
                    message: 'No input for AValidator.request'
                }]
            });
        }

        if (!D.url) {
            return cb({
                error: [{
                    'type': 'input',
                    message: 'No input.url for AValidator.request'
                }]
            });
        }

        D.json = true;

        REQ(D, function (E, R, B) {
            if (E) {
                return cb({
                    error: [{
                        'type': 'request',
                        message: E.message,
                        response: R,
                        body: B
                    }]
                });
            }

            D.data = B;
            cb(AValidator.one(D));
        });
    },
    promise: function (D) {
        return when.promise(function (resolve, reject) {
            AValidator.request(D, function (E) {
                resolve(E);
            });
        });
    },
    all: function (list) {
        if (!lodash.isArray(list)) {
            return {
                error: [{
                    'type': 'input',
                    message: 'Input is not array for AValidator.all'
                }]
            };
        }

        return lodash.map(list, AValidator.one);
    },
    one: function (D) {
        var E, err;

        if (!D) {
            return {
                error: [{
                    'type': 'internal',
                    message: 'No input for AValidator.one'
                }]
            };
        }

        if (!D.schema) {
            return {
                error: [{
                    'type': 'input',
                    message: 'No schema in input for AValidator.one'
                }]
            };
        }

        E = jjv();
        err = E.validate(D.schema, D.data);

        return err ? {error: lodash.map(err.validation, AValidator.normalizeError)} : null;
    }
};

module.exports = AValidator;
<commit_msg>remove unused reject<commit_after>/*jslint node: true */
'use strict';

var lodash = require('lodash'),
    jjv = require('jjv'),
    REQ = require('request'),
    when = require('when'),

AValidator = {
    normalizeError: function (V, I) {
        return {
            type: 'validation',
            target: I,
            rule: V
        };
    },
    promiseAll: function (list) {
        return when.all(lodash.map(list, AValidator.promise));
    },
    request: function (D, cb) {
        if (!lodash.isFunction(cb)) {
            throw {
                error: [{
                    'type': 'input',
                    message: 'No callback for AValidator.request'
                }]
            };
        }

        if (!D) {
            return cb({
                error: [{
                    'type': 'input',
                    message: 'No input for AValidator.request'
                }]
            });
        }

        if (!D.url) {
            return cb({
                error: [{
                    'type': 'input',
                    message: 'No input.url for AValidator.request'
                }]
            });
        }

        D.json = true;

        REQ(D, function (E, R, B) {
            if (E) {
                return cb({
                    error: [{
                        'type': 'request',
                        message: E.message,
                        response: R,
                        body: B
                    }]
                });
            }

            D.data = B;
            cb(AValidator.one(D));
        });
    },
    promise: function (D) {
        return when.promise(function (resolve) {
            AValidator.request(D, function (E) {
                resolve(E);
            });
        });
    },
    all: function (list) {
        if (!lodash.isArray(list)) {
            return {
                error: [{
                    'type': 'input',
                    message: 'Input is not array for AValidator.all'
                }]
            };
        }

        return lodash.map(list, AValidator.one);
    },
    one: function (D) {
        var E, err;

        if (!D) {
            return {
                error: [{
                    'type': 'internal',
                    message: 'No input for AValidator.one'
                }]
            };
        }

        if (!D.schema) {
            return {
                error: [{
                    'type': 'input',
                    message: 'No schema in input for AValidator.one'
                }]
            };
        }

        E = jjv();
        err = E.validate(D.schema, D.data);

        return err ? {error: lodash.map(err.validation, AValidator.normalizeError)} : null;
    }
};

module.exports = AValidator;
<|endoftext|>


<commit_before>define(["sprd/data/SprdModel", 'js/core/List', 'sprd/model/ProductType'], function (SprdModel, List, ProductType) {
    return SprdModel.inherit("sprd.model.Product", {

        $schema: {
            productType: ProductType
        },

        defaults: {
            productType: null,
            configurations: List
        },

        price: function () {
            // TODO format price with currency
            return this.$.price.vatIncluded;
        },
        getDefaultView: function () {
            if (this.$.defaultValues && this.$.productType) {
                return this.$.productType.getViewById(this.$.defaultValues.defaultView.id);
            }
            return null;
        }
    });
});
<commit_msg>extended schema to parse configurations via AttributeTypeResolver<commit_after>define(["sprd/data/SprdModel", 'js/core/List', 'sprd/model/ProductType',
    'js/data/AttributeTypeResolver', 'sprd/entity/DesignConfiguration', 'sprd/entity/TextConfiguration', 'js/data/TypeResolver'],
    function (SprdModel, List, ProductType, AttributeTypeResolver, DesignConfiguration, TextConfiguration, TypeResolver) {
        return SprdModel.inherit("sprd.model.Product", {

            $schema: {
                productType: ProductType,

                configurations: [new AttributeTypeResolver({
                    attribute: "type",
                    mapping: {
                        "design": DesignConfiguration,
                        "text": TextConfiguration
                    }
                })]
            },

            defaults: {
                productType: null,
                configurations: List
            },

            price: function () {
                // TODO format price with currency
                return this.$.price.vatIncluded;
            },
            getDefaultView: function () {
                if (this.$.defaultValues && this.$.productType) {
                    return this.$.productType.getViewById(this.$.defaultValues.defaultView.id);
                }
                return null;
            }
        });
    });
<|endoftext|>