<commit_before>// +----------------------------------------------------------------------+
// | Bitflux Editor                                                       |
// +----------------------------------------------------------------------+
// | Copyright (c) 2003 Bitflux GmbH                                      |
// +----------------------------------------------------------------------+
// | This software is published under the terms of the Apache Software    |
// | License a copy of which has been included with this distribution in  |
// | the LICENSE file and is available through the web at                 |
// | http://bitflux.ch/editor/license.html                                |
// +----------------------------------------------------------------------+
// | Author: Christian Stocker <chregu@bitflux.ch>                        |
// +----------------------------------------------------------------------+
//
// $Id: bxeLoader.js,v 1.168 2003/12/27 02:30:07 chregu Exp $

const BXE_VERSION = "0.1alpha";
const BXE_BUILD = "200312270330"

const E_FATAL = 1;

if (window.location.protocol == "file:" || window.location.host.match(/localhost.*/)) {
	var DebugOutput = false;
} else {
	var DebugOutput = false;
}

mozile_js_files = new Array();

mozile_js_files.push("mozile/mozWrappers.js");
mozile_js_files.push("js/widget.js");

mozile_js_files.push("mozile/eDOM.js");
mozile_js_files.push("js/bxeConfig.js");
mozile_js_files.push("mozile/eDOMXHTML.js");
mozile_js_files.push("js/bxeXMLNode.js");
mozile_js_files.push("js/bxeNodeElements.js");
mozile_js_files.push("js/bxeXMLDocument.js");
mozile_js_files.push("mozile/mozileTransportDriver.js");
mozile_js_files.push("mozile/td/http.js");
mozile_js_files.push("mozile/domlevel3.js");
mozile_js_files.push("mozile/mozCE.js");
mozile_js_files.push("mozile/mozIECE.js");
//mozile_js_files.push("mozile/mozileModify.js");
mozile_js_files.push("js/eDOMEvents.js");
mozile_js_files.push("js/bxeFunctions.js");

var mozile_root_dir = "./";

// some global vars, no need to change them
var mozile_corescript_loaded = 0;
var mozile_script_loaded = 0;
var bxe_config = new Object();
var bxe_about_box = null;
var bxe_format_list = null;
var bxe_context_menu = null;
var bxe_delayedUpdate = false;
var eDOM_bxe_mode = true;
var bxe_editable_page = true;

var startTimer = new Date();

function bxe_start(config_file,fromUrl, configArray) {

	/*if (! (BX_checkUnsupportedBrowsers())) {
		return false;
	}*/

	if((navigator.product == 'Gecko') && (navigator.userAgent.indexOf("Safari") == -1))
	{
		// navigator.productSub > '20020801' (test to see what the date should be)

		// POST04: if document.documentElement != HTML then ... or no "head" ...
		var head = document.getElementsByTagName("head")[0];
		bxe_config.file = config_file;
		bxe_config.fromUrl = fromUrl;
		bxe_config.configArray = configArray;
		if(head)
		{
			// get the location of this script and reuse it for the others
			for(var i=0; i<head.childNodes.length; i++)
			{
				var mozileLoaderRE = /(.*)bxeLoader.js$/;
				if(head.childNodes[i].localName == "SCRIPT")
				{
					var src = head.childNodes[i].src;
					var result = mozileLoaderRE.exec(src);
					if(result)
					{
						mozile_root_dir = result[1];
						break;
					}
				}
			}
			for (var i=0; i < mozile_js_files.length; i++)
			{
				var scr = document.createElementNS("http://www.w3.org/1999/xhtml","script");
				var src = mozile_root_dir + mozile_js_files[i];
				if (mozile_js_files[i] == "js/widget.js") {
					scr.onload = widget_loaded;
				} else {
					scr.onload = corescript_loaded;
				}
				scr.setAttribute("src", src);

				scr.setAttribute("language","JavaScript");
				head.appendChild(scr);
			}
			//when last include src is loaded, call onload handler

		}
		else {
			alert("*** ALERT: MozileLoader only works in XHTML - load Mozile JS explicitly in XML files");
		}
	}

}

// Detect Gecko but exclude Safari (for now); for now, only support XHTML

function bxe_load_xml (xmlfile) {

	var td = new mozileTransportDriver("webdav");
	function callback (e) {
		if (e.isError) {
			alert("Error loading xml file \n"+e.statusText);
			return false;
		}
		var xmldoc =  e.document;
		bxe_config.xmldoc = xmldoc;
		xmldoc.init();
		if (bxe_config.xhtmlfile) {
			xmldoc.importXHTMLDocument(bxe_config.xhtmlfile)
		} else if (bxe_config.xslfile) {
			xmldoc.transformToXPathMode(bxe_config.xslfile)
		} else {
			xmldoc.insertIntoHTMLDocument();
			xml_loaded(xmldoc);
		}

	}
	td.load(xmlfile,callback);

	return true;
}

function widget_loaded(e) {
	bxe_about_box = new Widget_AboutBox();
	bxe_about_box.draw();
	bxe_about_box.setText("Loading files ...");
	corescript_loaded(e);

}

function corescript_loaded(e) {
	mozile_corescript_loaded++;
	debug("from core script " + mozile_corescript_loaded + " of " + mozile_js_files.length  + "loaded: " + e.currentTarget.src);
	if ( mozile_js_files.length == mozile_corescript_loaded) {
		debug("call mozile_core_loaded()");
		mozile_core_loaded();
	} else {
		if (bxe_about_box) {
			bxe_about_box.addText(mozile_corescript_loaded );
		}
	}
}

function script_loaded(e) {
	mozile_script_loaded++;
	debug("from config script " + mozile_script_loaded + " loaded: " + e.currentTarget.src );
	if ( bxe_config.scriptfiles.length == mozile_script_loaded ) {
		debug("call mozile_loaded()");
		mozile_loaded();
	} else {
		bxe_about_box.addText(mozile_script_loaded );
	}
}

function mozile_core_loaded() {
	bxe_about_box.addText("Scripts loaded ...");
	bxe_about_box.addText("Load Config ");
	try {
		bxe_config = new bxeConfig(bxe_config.file, bxe_config.fromUrl, bxe_config.configArray);
	} catch (e) {
		bxe_catch_alert(e);
	}
}

function mozile_loaded() {
	defaultContainerName = "p";

	bxe_about_box.addText("Load XML ...");
	bxe_load_xml(bxe_config.xmlfile);

}

function xml_loaded(xmldoc) {
	bxe_about_box.addText("Load RelaxNG " + bxe_config.validationfile + " ");
	if (!(bxe_config.validationfile && xmldoc.XMLNode.loadSchema(bxe_config.validationfile,validation_loaded))) {
		bxe_about_box.addText("RelaxNG File was not found");
	}
	bxe_history_snapshot();
	document.eDOMaddEventListener("toggleSourceMode",bxe_toggleSourceMode,false);
	document.eDOMaddEventListener("toggleTagMode",bxe_toggleTagMode,false);
	document.eDOMaddEventListener("toggleNormalMode",bxe_toggleNormalMode,false);
	document.eDOMaddEventListener("DocumentSave",__bxeSave,false);
	document.eDOMaddEventListener("ToggleTextClass",bxe_toggleTextClass,false);
	document.eDOMaddEventListener("appendNode",bxe_appendNode,false);
	document.eDOMaddEventListener("appendChildNode",bxe_appendChildNode,false);
	document.eDOMaddEventListener("InsertLink",bxe_InsertLink,false);
	document.eDOMaddEventListener("InsertTable",bxe_InsertTable,false);
	document.eDOMaddEventListener("InsertImage",bxe_InsertObject,false);
	document.eDOMaddEventListener("OrderedList",bxe_OrderedList,false);
	document.eDOMaddEventListener("UnorderedList",bxe_UnorderedList,false);

	document.eDOMaddEventListener("changeLinesContainer",bxe_changeLinesContainer,false);
	document.eDOMaddEventListener("Exit",bxe_exit,false);

	document.eDOMaddEventListener("ClipboardCopy",function(e) { window.getSelection().copy()},false);
	document.eDOMaddEventListener("ClipboardPaste",function(e) { window.getSelection().paste()},false);
	document.eDOMaddEventListener("ClipboardCut",function(e) { window.getSelection().cut()},false);

	document.eDOMaddEventListener("Undo",function(e) { bxe_history_undo()}, false);
	document.eDOMaddEventListener("Redo",function(e) { bxe_history_redo()}, false);

	//document.eDOMaddEventListener("NodeInsertedParent",bxe_NodeInsertedParent, false);
	document.eDOMaddEventListener("NodeInsertedBefore",bxe_NodeInsertedBefore,false);
	document.eDOMaddEventListener("NodeBeforeDelete",bxe_NodeBeforeDelete,false);
	/*document.eDOMaddEventListener("NodeChanged",bxe_NodeChanged,false);

	document.eDOMaddEventListener("NodeRemovedChildOnly",bxe_NodeRemovedChildOnly,false);
	*/
	//document.eDOMaddEventListener("NodeAppendedChild",bxe_NodeAppendedChild,false);
	document.eDOMaddEventListener("NodePositionChanged",bxe_NodePositionChanged,false);

	document.eDOMaddEventListener("ContextPopup",bxe_ContextPopup,false);
	document.addEventListener("contextmenu",bxe_ContextMenuEvent, false);

	bxe_context_menu = new Widget_ContextMenu();
}

function validation_loaded(vdom) {
	bxe_about_box.addText("Validation Loaded ...");

	var vali = bxe_config.xmldoc.XMLNode.validateDocument();
	if (!vali) {
		bxe_about_box.addText("Document is *not* valid.");
		//alert(vali.getErrorMessagesAsText());
		bxe_disableEditablePage();
	}
	else {
		bxe_about_box.addText("<br/>Document is valid.");

	}
	var endTimer = new Date();
	debug ("startTime: " + startTimer);
	debug ("endTime  : " + endTimer);
	dump ("Total Start Time: " + (endTimer - startTimer)/1000 + " sec\n");
}

function config_loaded(bxe_config_in) {
	bxe_about_box.addText("& Parsed ...");

	bxe_config = bxe_config_in;
	var head = document.getElementsByTagName("head")[0];
	for (var i=0; i < bxe_config.cssfiles.length; i++)
	{
		var scr = document.createElementNS(XHTMLNS,"link");
		scr.setAttribute("type","text/css");
		scr.setAttribute("rel","stylesheet");
		scr.setAttribute("href",bxe_config.cssfiles[i]);
		head.appendChild(scr);
	}

	for (var i=0; i < bxe_config.scriptfiles.length; i++)
	{
		var scr = document.createElementNS("http://www.w3.org/1999/xhtml","script");
		var src = mozile_root_dir + bxe_config.scriptfiles[i];
		scr.onload = script_loaded;
		scr.setAttribute("src", src);
		scr.setAttribute("language","JavaScript");
		head.appendChild(scr);
	}

}

debug = function (text, options) {

	if (DebugOutput) {

		fn =  bxe_getCaller(debug);

		dump( fn.getName() +  ": " + text + "\n");
		if (options) {

			if (options.evalArguments) {
				var fname= fn.getName();
					dump("  Arguments: (");
					for (var i = 0; i < fn.arguments.length; i++) {
						dump("[" + typeof fn.arguments[i] + "] ");
						switch( typeof( fn.arguments[i] )) {
							case "function":
								dump (fn.arguments[i].getName());
								break;
							case "string":
								dump('"' + fn.arguments[i] + '"');
								break;
							default:
								dump(fn.arguments[i]);
						}
						if (i < fn.arguments.length - 1 ) {
							dump(", ");
						}
					}
					dump (")\n");

			}

			if (options.callstack) {
				var callstack =  new Array();
				dump ("  Callstack: \n");
				dump ("  ----------\n");
				while (fn) {

					callstack.unshift(fn.getName() + "\n");
					var newfn = JsUtil_getCaller(fn);
					if (fn == newfn) {
						callstack.unshift ("  [javascript recursion]\n");
						break;
					}
					fn = newfn;
				}
				for (var i = 0; i < callstack.length; i++) {
					dump("  " +i +": " +callstack[i]);
				}
				dump ("  ----------\n");

			}

		}

	}
}

Function.prototype.getName = function () {
	var r = /function (\w*)([^\{\}]*\))/
	var s = new String( this);
	var m = s.match( r );
	if (m) {
		var f = "";
		if (m[1]) {
			f = m[1];
		} else {
			r = /var id = "(.+)"/;
			var n = s.match(r);
			if (n && n[1]) {
				f = n[1];
			} else {
				f = "anoynmous function";
			}
		}
		var args = m[2];
		return (f+args);
	} else {
		return "anonymous function";
	}
}

function bxe_getCaller( fn )
{
	switch( typeof( fn ))
	{
		case "undefined":
			return bxe_getCaller( bxe_getCaller );

		case "function":
			if( fn.caller )
				return fn.caller;
			if( fn.arguments && fn.arguments.caller )
				return fn.arguments.caller;
	}
	return undefined;
}

<commit_msg>automatic BuildDate Update<commit_after>// +----------------------------------------------------------------------+
// | Bitflux Editor                                                       |
// +----------------------------------------------------------------------+
// | Copyright (c) 2003 Bitflux GmbH                                      |
// +----------------------------------------------------------------------+
// | This software is published under the terms of the Apache Software    |
// | License a copy of which has been included with this distribution in  |
// | the LICENSE file and is available through the web at                 |
// | http://bitflux.ch/editor/license.html                                |
// +----------------------------------------------------------------------+
// | Author: Christian Stocker <chregu@bitflux.ch>                        |
// +----------------------------------------------------------------------+
//
// $Id: bxeLoader.js,v 1.169 2003/12/28 02:30:08 chregu Exp $

const BXE_VERSION = "0.1alpha";
const BXE_BUILD = "200312280330"

const E_FATAL = 1;

if (window.location.protocol == "file:" || window.location.host.match(/localhost.*/)) {
	var DebugOutput = false;
} else {
	var DebugOutput = false;
}

mozile_js_files = new Array();

mozile_js_files.push("mozile/mozWrappers.js");
mozile_js_files.push("js/widget.js");

mozile_js_files.push("mozile/eDOM.js");
mozile_js_files.push("js/bxeConfig.js");
mozile_js_files.push("mozile/eDOMXHTML.js");
mozile_js_files.push("js/bxeXMLNode.js");
mozile_js_files.push("js/bxeNodeElements.js");
mozile_js_files.push("js/bxeXMLDocument.js");
mozile_js_files.push("mozile/mozileTransportDriver.js");
mozile_js_files.push("mozile/td/http.js");
mozile_js_files.push("mozile/domlevel3.js");
mozile_js_files.push("mozile/mozCE.js");
mozile_js_files.push("mozile/mozIECE.js");
//mozile_js_files.push("mozile/mozileModify.js");
mozile_js_files.push("js/eDOMEvents.js");
mozile_js_files.push("js/bxeFunctions.js");

var mozile_root_dir = "./";

// some global vars, no need to change them
var mozile_corescript_loaded = 0;
var mozile_script_loaded = 0;
var bxe_config = new Object();
var bxe_about_box = null;
var bxe_format_list = null;
var bxe_context_menu = null;
var bxe_delayedUpdate = false;
var eDOM_bxe_mode = true;
var bxe_editable_page = true;

var startTimer = new Date();

function bxe_start(config_file,fromUrl, configArray) {

	/*if (! (BX_checkUnsupportedBrowsers())) {
		return false;
	}*/

	if((navigator.product == 'Gecko') && (navigator.userAgent.indexOf("Safari") == -1))
	{
		// navigator.productSub > '20020801' (test to see what the date should be)

		// POST04: if document.documentElement != HTML then ... or no "head" ...
		var head = document.getElementsByTagName("head")[0];
		bxe_config.file = config_file;
		bxe_config.fromUrl = fromUrl;
		bxe_config.configArray = configArray;
		if(head)
		{
			// get the location of this script and reuse it for the others
			for(var i=0; i<head.childNodes.length; i++)
			{
				var mozileLoaderRE = /(.*)bxeLoader.js$/;
				if(head.childNodes[i].localName == "SCRIPT")
				{
					var src = head.childNodes[i].src;
					var result = mozileLoaderRE.exec(src);
					if(result)
					{
						mozile_root_dir = result[1];
						break;
					}
				}
			}
			for (var i=0; i < mozile_js_files.length; i++)
			{
				var scr = document.createElementNS("http://www.w3.org/1999/xhtml","script");
				var src = mozile_root_dir + mozile_js_files[i];
				if (mozile_js_files[i] == "js/widget.js") {
					scr.onload = widget_loaded;
				} else {
					scr.onload = corescript_loaded;
				}
				scr.setAttribute("src", src);

				scr.setAttribute("language","JavaScript");
				head.appendChild(scr);
			}
			//when last include src is loaded, call onload handler

		}
		else {
			alert("*** ALERT: MozileLoader only works in XHTML - load Mozile JS explicitly in XML files");
		}
	}

}

// Detect Gecko but exclude Safari (for now); for now, only support XHTML

function bxe_load_xml (xmlfile) {

	var td = new mozileTransportDriver("webdav");
	function callback (e) {
		if (e.isError) {
			alert("Error loading xml file \n"+e.statusText);
			return false;
		}
		var xmldoc =  e.document;
		bxe_config.xmldoc = xmldoc;
		xmldoc.init();
		if (bxe_config.xhtmlfile) {
			xmldoc.importXHTMLDocument(bxe_config.xhtmlfile)
		} else if (bxe_config.xslfile) {
			xmldoc.transformToXPathMode(bxe_config.xslfile)
		} else {
			xmldoc.insertIntoHTMLDocument();
			xml_loaded(xmldoc);
		}

	}
	td.load(xmlfile,callback);

	return true;
}

function widget_loaded(e) {
	bxe_about_box = new Widget_AboutBox();
	bxe_about_box.draw();
	bxe_about_box.setText("Loading files ...");
	corescript_loaded(e);

}

function corescript_loaded(e) {
	mozile_corescript_loaded++;
	debug("from core script " + mozile_corescript_loaded + " of " + mozile_js_files.length  + "loaded: " + e.currentTarget.src);
	if ( mozile_js_files.length == mozile_corescript_loaded) {
		debug("call mozile_core_loaded()");
		mozile_core_loaded();
	} else {
		if (bxe_about_box) {
			bxe_about_box.addText(mozile_corescript_loaded );
		}
	}
}

function script_loaded(e) {
	mozile_script_loaded++;
	debug("from config script " + mozile_script_loaded + " loaded: " + e.currentTarget.src );
	if ( bxe_config.scriptfiles.length == mozile_script_loaded ) {
		debug("call mozile_loaded()");
		mozile_loaded();
	} else {
		bxe_about_box.addText(mozile_script_loaded );
	}
}

function mozile_core_loaded() {
	bxe_about_box.addText("Scripts loaded ...");
	bxe_about_box.addText("Load Config ");
	try {
		bxe_config = new bxeConfig(bxe_config.file, bxe_config.fromUrl, bxe_config.configArray);
	} catch (e) {
		bxe_catch_alert(e);
	}
}

function mozile_loaded() {
	defaultContainerName = "p";

	bxe_about_box.addText("Load XML ...");
	bxe_load_xml(bxe_config.xmlfile);

}

function xml_loaded(xmldoc) {
	bxe_about_box.addText("Load RelaxNG " + bxe_config.validationfile + " ");
	if (!(bxe_config.validationfile && xmldoc.XMLNode.loadSchema(bxe_config.validationfile,validation_loaded))) {
		bxe_about_box.addText("RelaxNG File was not found");
	}
	bxe_history_snapshot();
	document.eDOMaddEventListener("toggleSourceMode",bxe_toggleSourceMode,false);
	document.eDOMaddEventListener("toggleTagMode",bxe_toggleTagMode,false);
	document.eDOMaddEventListener("toggleNormalMode",bxe_toggleNormalMode,false);
	document.eDOMaddEventListener("DocumentSave",__bxeSave,false);
	document.eDOMaddEventListener("ToggleTextClass",bxe_toggleTextClass,false);
	document.eDOMaddEventListener("appendNode",bxe_appendNode,false);
	document.eDOMaddEventListener("appendChildNode",bxe_appendChildNode,false);
	document.eDOMaddEventListener("InsertLink",bxe_InsertLink,false);
	document.eDOMaddEventListener("InsertTable",bxe_InsertTable,false);
	document.eDOMaddEventListener("InsertImage",bxe_InsertObject,false);
	document.eDOMaddEventListener("OrderedList",bxe_OrderedList,false);
	document.eDOMaddEventListener("UnorderedList",bxe_UnorderedList,false);

	document.eDOMaddEventListener("changeLinesContainer",bxe_changeLinesContainer,false);
	document.eDOMaddEventListener("Exit",bxe_exit,false);

	document.eDOMaddEventListener("ClipboardCopy",function(e) { window.getSelection().copy()},false);
	document.eDOMaddEventListener("ClipboardPaste",function(e) { window.getSelection().paste()},false);
	document.eDOMaddEventListener("ClipboardCut",function(e) { window.getSelection().cut()},false);

	document.eDOMaddEventListener("Undo",function(e) { bxe_history_undo()}, false);
	document.eDOMaddEventListener("Redo",function(e) { bxe_history_redo()}, false);

	//document.eDOMaddEventListener("NodeInsertedParent",bxe_NodeInsertedParent, false);
	document.eDOMaddEventListener("NodeInsertedBefore",bxe_NodeInsertedBefore,false);
	document.eDOMaddEventListener("NodeBeforeDelete",bxe_NodeBeforeDelete,false);
	/*document.eDOMaddEventListener("NodeChanged",bxe_NodeChanged,false);

	document.eDOMaddEventListener("NodeRemovedChildOnly",bxe_NodeRemovedChildOnly,false);
	*/
	//document.eDOMaddEventListener("NodeAppendedChild",bxe_NodeAppendedChild,false);
	document.eDOMaddEventListener("NodePositionChanged",bxe_NodePositionChanged,false);

	document.eDOMaddEventListener("ContextPopup",bxe_ContextPopup,false);
	document.addEventListener("contextmenu",bxe_ContextMenuEvent, false);

	bxe_context_menu = new Widget_ContextMenu();
}

function validation_loaded(vdom) {
	bxe_about_box.addText("Validation Loaded ...");

	var vali = bxe_config.xmldoc.XMLNode.validateDocument();
	if (!vali) {
		bxe_about_box.addText("Document is *not* valid.");
		//alert(vali.getErrorMessagesAsText());
		bxe_disableEditablePage();
	}
	else {
		bxe_about_box.addText("<br/>Document is valid.");

	}
	var endTimer = new Date();
	debug ("startTime: " + startTimer);
	debug ("endTime  : " + endTimer);
	dump ("Total Start Time: " + (endTimer - startTimer)/1000 + " sec\n");
}

function config_loaded(bxe_config_in) {
	bxe_about_box.addText("& Parsed ...");

	bxe_config = bxe_config_in;
	var head = document.getElementsByTagName("head")[0];
	for (var i=0; i < bxe_config.cssfiles.length; i++)
	{
		var scr = document.createElementNS(XHTMLNS,"link");
		scr.setAttribute("type","text/css");
		scr.setAttribute("rel","stylesheet");
		scr.setAttribute("href",bxe_config.cssfiles[i]);
		head.appendChild(scr);
	}

	for (var i=0; i < bxe_config.scriptfiles.length; i++)
	{
		var scr = document.createElementNS("http://www.w3.org/1999/xhtml","script");
		var src = mozile_root_dir + bxe_config.scriptfiles[i];
		scr.onload = script_loaded;
		scr.setAttribute("src", src);
		scr.setAttribute("language","JavaScript");
		head.appendChild(scr);
	}

}

debug = function (text, options) {

	if (DebugOutput) {

		fn =  bxe_getCaller(debug);

		dump( fn.getName() +  ": " + text + "\n");
		if (options) {

			if (options.evalArguments) {
				var fname= fn.getName();
					dump("  Arguments: (");
					for (var i = 0; i < fn.arguments.length; i++) {
						dump("[" + typeof fn.arguments[i] + "] ");
						switch( typeof( fn.arguments[i] )) {
							case "function":
								dump (fn.arguments[i].getName());
								break;
							case "string":
								dump('"' + fn.arguments[i] + '"');
								break;
							default:
								dump(fn.arguments[i]);
						}
						if (i < fn.arguments.length - 1 ) {
							dump(", ");
						}
					}
					dump (")\n");

			}

			if (options.callstack) {
				var callstack =  new Array();
				dump ("  Callstack: \n");
				dump ("  ----------\n");
				while (fn) {

					callstack.unshift(fn.getName() + "\n");
					var newfn = JsUtil_getCaller(fn);
					if (fn == newfn) {
						callstack.unshift ("  [javascript recursion]\n");
						break;
					}
					fn = newfn;
				}
				for (var i = 0; i < callstack.length; i++) {
					dump("  " +i +": " +callstack[i]);
				}
				dump ("  ----------\n");

			}

		}

	}
}

Function.prototype.getName = function () {
	var r = /function (\w*)([^\{\}]*\))/
	var s = new String( this);
	var m = s.match( r );
	if (m) {
		var f = "";
		if (m[1]) {
			f = m[1];
		} else {
			r = /var id = "(.+)"/;
			var n = s.match(r);
			if (n && n[1]) {
				f = n[1];
			} else {
				f = "anoynmous function";
			}
		}
		var args = m[2];
		return (f+args);
	} else {
		return "anonymous function";
	}
}

function bxe_getCaller( fn )
{
	switch( typeof( fn ))
	{
		case "undefined":
			return bxe_getCaller( bxe_getCaller );

		case "function":
			if( fn.caller )
				return fn.caller;
			if( fn.arguments && fn.arguments.caller )
				return fn.arguments.caller;
	}
	return undefined;
}

<|endoftext|>


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

  var unpackHttpRes = function(fn, value) {
    if (angular.isObject(value) && value.data && value.status && value.headers && value.config && value.statusText && angular.isFunction(value.headers)) {
      return fn(value.data, value.status, value.headers, value.config);
    } else {
      return fn(value);
    }
  };

  angular.module('jutaz.quasar', []).config(['$provide', function($provide) {
    $provide.decorator('$q', ['$delegate', function($delegate) {
      var q = {
        when: $delegate.when,
        reject: $delegate.reject,
        all: $delegate.all,
        defer: $delegate.defer,
      };

      function decoratePromise(promise) {
        promise._then = promise.then;
        promise.extended = true; // Good to have for tests

        promise.catch = function(errFn, bind) {
          if (angular.isObject(bind)) {
            errFn = errFn.bind(bind);
          }

          return this.then(null, errFn);
        };

        promise.then = function(thenFn, errFn, notifyFn) {
          if (angular.isObject(errFn)) {
            thenFn = thenFn.bind(errFn);
          }

          var p = promise._then(thenFn, errFn, notifyFn);
          return decoratePromise(p);
        };

        promise.success = function(fn) {
          return promise.then(unpackHttpRes.bind(undefined, fn));
        };

        promise.error = function(fn) {
          return promise.then(null, unpackHttpRes.bind(undefined, fn));
        };

        promise.spread = function(fn, context) {
          return promise.then(function(data) {
            if (!angular.isArray(data)) {
              return fn.call(context, data);
            } else {
              return q.all(data).then(function(resolved) {
                return fn.apply(context, resolved);
              }); // Resolve promises, if any
            }
          });
        };

        promise.delay = promise.timeout = function(fn, time, context) {
          // In case people have other preference
          if (angular.isNumber(fn) && angular.isFunction(time)) {
            var tmp = fn;
            fn = time;
            time = tmp;
          }

          var deferred = q.defer();
          setTimeout(function() {
            promise.then(fn, context).then(deferred.resolve);
          }, time);

          return decoratePromise(deferred.promise);
        };

        promise.all = function(fn, context) {
          var p = promise.then(function(data) {
            if (angular.isArray(data)) {
              return q.all(data);
            } else {
              return data;
            }
          }).then(fn, context);
          return p;
        };

        return promise;
      }

      $delegate.fcall = function(fn, context) {
        return $delegate.when().then(fn, context);
      };

      $delegate.defer = function() {
        var deferred = q.defer();
        decoratePromise(deferred.promise);
        return deferred;
      };

      ['all', 'reject', 'when'].forEach(function(fn) {
        $delegate[fn] = function() {
          return decoratePromise(q[fn].apply(this, arguments));
        };
      });

      return $delegate;
    },
  ]);
  },
]);
})();
<commit_msg>Add support for object resolves<commit_after>(function() {
  'use strict';

  var unpackHttpRes = function(fn, value) {
    if (angular.isObject(value) && value.data && value.status && value.headers && value.config && value.statusText && angular.isFunction(value.headers)) {
      return fn(value.data, value.status, value.headers, value.config);
    } else {
      return fn(value);
    }
  };

  angular.module('jutaz.quasar', []).config(['$provide', function($provide) {
    $provide.decorator('$q', ['$delegate', function($delegate) {
      var q = {
        when: $delegate.when,
        reject: $delegate.reject,
        all: $delegate.all,
        defer: $delegate.defer,
      };

      function decoratePromise(promise) {
        promise._then = promise.then;
        promise.extended = true; // Good to have for tests

        promise.catch = function(errFn, bind) {
          if (angular.isObject(bind)) {
            errFn = errFn.bind(bind);
          }

          return this.then(null, errFn);
        };

        promise.then = function(thenFn, errFn, notifyFn) {
          if (angular.isObject(errFn)) {
            thenFn = thenFn.bind(errFn);
          }

          var p = promise._then(thenFn, errFn, notifyFn);
          return decoratePromise(p);
        };

        promise.success = function(fn) {
          return promise.then(unpackHttpRes.bind(undefined, fn));
        };

        promise.error = function(fn) {
          return promise.then(null, unpackHttpRes.bind(undefined, fn));
        };

        promise.spread = function(fn, context) {
          return promise.then(function(data) {
            if (!angular.isArray(data)) {
              return fn.call(context, data);
            } else {
              return q.all(data).then(function(resolved) {
                return fn.apply(context, resolved);
              }); // Resolve promises, if any
            }
          });
        };

        promise.delay = promise.timeout = function(fn, time, context) {
          // In case people have other preference
          if (angular.isNumber(fn) && angular.isFunction(time)) {
            var tmp = fn;
            fn = time;
            time = tmp;
          }

          var deferred = q.defer();
          setTimeout(function() {
            promise.then(fn, context).then(deferred.resolve);
          }, time);

          return decoratePromise(deferred.promise);
        };

        promise.all = function(fn, context) {
          var p = promise.then(function(data) {
            if (angular.isArray(data) || angular.isObject(data)) {
              return q.all(data);
            } else {
              return data;
            }
          }).then(fn, context);
          return p;
        };

        return promise;
      }

      $delegate.fcall = function(fn, context) {
        return $delegate.when().then(fn, context);
      };

      $delegate.defer = function() {
        var deferred = q.defer();
        decoratePromise(deferred.promise);
        return deferred;
      };

      ['all', 'reject', 'when'].forEach(function(fn) {
        $delegate[fn] = function() {
          return decoratePromise(q[fn].apply(this, arguments));
        };
      });

      return $delegate;
    },
  ]);
  },
]);
})();
<|endoftext|>


<commit_before>'use strict';

// stdlib
import React from 'react';
import PropTypes from 'prop-types';
import createReactClass from 'create-react-class';

// third-party lib
import ModalComponent from '../../../../libs/bootstrap/modal';
import { Form, FormMixin, Input } from '../../../../libs/bootstrap/form';
import _ from 'underscore';

// Internal lib
import { extraEvidence } from './segregationData';
import { external_url_map } from '../../../globals';
import { RestMixin } from '../../../rest';
import * as curator from '../../../curator';

let EvidenceSheet = createReactClass({
    mixins: [FormMixin, RestMixin],

    propTypes: {
        ready: PropTypes.bool,                      // Flag if ready for second modal
        sheetDone: PropTypes.func,                  // Function to call to add or edit an evidence
        data: PropTypes.object,                     // Data relevant to this particular piece of evidence
        allData: PropTypes.object,                  // All extra evidence across all entries for this variant
        isNew: PropTypes.bool,                      // If we are adding a new piece of evidence or editing an existing piece
        isFromMaster: PropTypes.bool,               // If editing an existing evidence by clicking edit button in master/tally table
        subcategory: PropTypes.string,              // Subcategory (usually the panel) the evidence is part of
        evidenceType: PropTypes.string              // Evidence source type
    },

    getInitialState: function() {
        let data =  {};
        let hpoUnaffected = false;
        let hpoData = [];
        if (this.props.data) {
            data = this.props.data;
            hpoUnaffected = this.props.data.is_disease_associated_with_probands;
            hpoData = this.props.data.hpoData ? this.props.data.hpoData : [];
        }
        return {
            data: data,
            hpoData: hpoData,
            hpoUnaffected: hpoUnaffected,  // Flag for "Disease associated with proband(s) (HPO)" checkbox
            backgroundGreen: '#00FF0030',
            errorMsg: '',
            enableSubmit: true             // Flag to enable Submit button
        };
    },

    componentDidMount() {
        this.props.onRef(this);
    },

    componentWillUnmount() {
        this.props.onRef(null);
    },

    handleModalClose() {
        this.child.closeModal();
    },

    cancel() {
        this.props.sheetDone(null);
        this.handleModalClose();
    },

    showError(msg) {
        this.setState({
            errorMsg: msg
        });
    },

    enableSubmitButton(flag) {
        this.setState({
            enableSubmit: flag
        });
    },

    clearHpoTerms() {
        this.setState({ hpoData: [] });
        this.clrFormErrors('proband_hpo_ids');
    },

    /**
     * Submit button is clicked.  Save all form data and call function to save in db.
     * Close the modal.
     *
     * @param {object} e    // event
     */
    submitNewEvidence(e) {
        e.preventDefault();
        e.stopPropagation();

        this.saveAllFormValues();
        const formValues = this.getAllFormValues();

        let formError = false;
        if (this.validateDefault()) {
            // Check HPO ID format
            const hpoIds = curator.capture.hpoids(this.getFormValue('proband_hpo_ids'));
            const filteredIds = this.filterOutExtraHpo(hpoIds);
            const duplicateExists = this.checkForDuplicateHpo(hpoIds);
            if (hpoIds && hpoIds.length && _(hpoIds).any(id => id === null)) {
                // HPOID list is bad
                formError = true;
                this.setFormErrors('proband_hpo_ids', 'Use HPO IDs (e.g. HP:0000001) separated by commas');
            } else if (duplicateExists) {
                formError = true;
                this.setFormErrors('proband_hpo_ids', 'Please remove duplicate IDs.')
            } else if (filteredIds && filteredIds.length) {
                // Input and hpoData don't match
                formError = true;
                this.setFormErrors('proband_hpo_ids', `The terms and IDs above do not match. Please remove or retrieve terms again. (${filteredIds.join(', ')})`)
            }
            if (!formError) {
                let allData = null;
                let hpoData = {hpoData: this.state.hpoData};
                if (this.props.isNew) {
                    allData = Object.assign(this.props.data, formValues, hpoData);
                } else {
                    allData = Object.assign({}, this.props.data);
                    Object.assign(allData, formValues, hpoData);
                }
                this.handleModalClose();
                this.resetAllFormValues();
                this.setState({
                    data: {},
                    hpoData: [],
                    hpoUnaffected: false
                });
                this.props.sheetDone(allData);
            }
        }
    },

    /**
     * Given the subcategory, return a list of allowed fields.
     * This is used to highlight the input.
     */
    allowedFields() {
        let tableObj = _.find(extraEvidence.tableCols(), o => o.subcategory === this.props.subcategory);
        let fields = tableObj && tableObj.cols ? tableObj.cols.map(col => col.key) : [];
        if (fields.indexOf('comments') != -1) {
            fields.splice(fields.indexOf('comments'), 1);
        }
        return fields;
    },

    /**
     * If the "Disease associated with proband(s) (HPO) (Check here if unaffected)"
     * checkbox is toggled, save its current state.
     *
     * @param {string} ref
     * @param {event} e
     */
    handleCheckboxChange(ref, e) {
        if (ref === 'is_disease_associated_with_probands') {
            this.setState({hpoUnaffected: this.refs[ref].toggleValue()});
        }
    },

    /**
     * Check for duplicates and return a boolean value accordingly
     * @param {array} inputIds
     */
    checkForDuplicateHpo(inputIds) {
        return inputIds.some((id, index) => inputIds.indexOf(id) !== index)
    },

    /**
     * Check that hpoData and proband_hpo_ids are the same
     * If not, returns array of rejected ids for form validation
     * @param {array} inputIds
     */
    filterOutExtraHpo(inputIds) {
        const hpoData = this.state.hpoData;
        if (hpoData && hpoData.length) {
            const idsFromHpoData = [];
            hpoData.forEach(obj =>{
                idsFromHpoData.push(obj.hpoId);
            });
            if (inputIds.length > idsFromHpoData.length) {
                return inputIds.filter(id => !idsFromHpoData.includes(id));
            } else if (idsFromHpoData.length > inputIds.length) {
                return idsFromHpoData.filter(id => !inputIds.includes(id));
            }
        }
    },

    /**
     * Display the input fields with available values
     */
    inputs() {
        let jsx = [];
        let i = 0;
        let trStyle = {
            'display': 'flex',
            'alignItems': 'flex-end'
        };

        // Get a list of allowed fields
        let fields = this.allowedFields();

        extraEvidence.evidenceInputs.forEach(row => {
            let rowTDs = [];
            let done = false;
            row.cols.forEach(col => {
                let value = '';
                if (this.state.data != null && Object.keys(this.state.data).length > 0) {
                    value = this.state.data[col.name];
                }

                // Set up the label for the input
                let codes = extraEvidence.fieldToCriteriaCodeMapping
                    .filter(obj => obj.key === col.name)
                    .map(obj => obj.codes);
                let label = col.label;
                if (codes.length > 0) {
                    label += ` (${codes.join(', ')})`;
                }

                let node = [<div className={`col-md-${col.width}`}  style={{textAlign: 'left'}} key={i++}>
                    <Input
                        type = {col.kind}
                        label = {label}
                        name = {col.name}
                        ref = {col.name}
                        value = {col.kind != 'checkbox' ? value : null}
                        checked = {col.name === 'is_disease_associated_with_probands' && this.state.hpoUnaffected != undefined ? this.state.hpoUnaffected : false}
                        handleChange = {col.kind === 'checkbox' ? this.handleCheckboxChange : null}
                        error = {this.getFormError(col.name)}
                        clearError = {this.clrFormErrors.bind(null, col.name)}
                        fieldStyle = {fields.indexOf(col.name) == -1 || this.props.isFromMaster ? null : {backgroundColor: this.state.backgroundGreen}}
                    />

]
                if ('lookup' in col) {
                    // Push nodes separately so elements do not stack vertically
                    node.push(

                            <Input
                                type="button"
                                inputClassName="btn btn-primary btn-default get-terms-btn"
                                title="Get Terms"
                                clickHandler={() => this.lookupTerm()}
                            >
                            </Input>

                    );
                    node.push(

                            <Input
                                type="button"
                                inputClassName="btn btn-danger btn-default clear-terms-btn"
                                title="Clear Terms"
                                clickHandler={() => this.clearHpoTerms()}
                            >
                            </Input>

                    );
                    node.push(

                            Terms for phenotypic feature(s) associated with proband(s):
                            {this.renderLookupResult()}

                    );
                }
                rowTDs.push(node);
                // if field needs to be put in its own row, add it here.
                if (col.width === 12) {
                    let rowTR =

                        {rowTDs}

                    jsx.push(rowTR);
                    rowTDs = [];
                    done = true;
                }
            });
            // if row has not been added, add it here.
            if (!done) {
                let rowTR =

                    {rowTDs}

                jsx.push(rowTR);
            }
        });
        return jsx;
    },

    /**
     * Renders list of saved HPO terms and their respective ids
     */
    renderLookupResult() {
        if (this.state.hpoData && !this.state.hpoData.length) {
            return null;
        }
        if (this.state.hpoData && this.state.hpoData.length) {
            let hpo = this.state.hpoData.map((obj, i) => {
                return
{obj.hpoTerm} ({obj.hpoId})

            });

            let node = (

                        {hpo}

            );
            return node;
        }
    },

    /**
     *
     * @param {string} hpoIds
     */
    validateHpo(hpoIds) {
        const checkIds = curator.capture.hpoids(hpoIds);
        // Check HPO ID format
        if (checkIds && checkIds.length && _(checkIds).any(id => id === null)) {
            // HPOID list is bad
            this.setFormErrors('proband_hpo_ids', 'For term lookup, use HPO IDs (e.g. HP:0000001) separated by commas');
        }
        else if (checkIds && checkIds.length && !_(checkIds).any(id => id === null)) {
            const hpoIdList = _.without(checkIds, null);
            return _.uniq(hpoIdList);
        }
    },

    /**
     * Fetch terms from proband_hpo_id form value, save to state as array of objects
     */
    lookupTerm() {
        this.saveAllFormValues();
        const hpoIds = this.getFormValue('proband_hpo_ids');
        const validatedHpoList = this.validateHpo(hpoIds);
        const hpoWithTerms = [];
        if (validatedHpoList) {
            validatedHpoList.forEach(id => {
                let url = external_url_map['HPOApi'] + id;
                this.getRestData(url).then(result => {
                    const term = result['details']['name'];
                    const hpo = {hpoId: id, hpoTerm: term};
                    hpoWithTerms.push(hpo);
                    this.setState({ hpoData: hpoWithTerms });
                }).catch(err => {
                    // Unsuccessful retrieval
                    console.warn('Error in fetching HPO data =: %o', err);
                    const term = 'Term not found';
                    const hpo = {hpoId: id, hpoTerm: term};
                    hpoWithTerms.push(hpo);
                    this.setState({ hpoData: hpoWithTerms });
                });
            });
            this.clrFormErrors('proband_hpo_ids');
        }
    },

    render() {
        var submitErrClass = 'submit-err ' + (this.anyFormErrors() ? '' : ' hidden');
        var errMsgClass = this.state.errorMsg === '' ? 'hidden' : '';
        var submitClass = "btn-default btn-inline-spacer btn-primary" + (this.state.errorMsg === '' && this.state.enableSubmit === true ? '' : ' disabled');
        var showMsgClass = this.props.isFromMaster ? 'hidden' : '';

        return  <ModalComponent
            modalTitle={this.props.isNew ? "Add Evidence Details" : "Edit Evidence Details"}
            modalClass="modal-default"
            modalWrapperClass="input-inline add-resource-id-modal"
            onRef={ref => (this.child = ref)}
            actuatorDisabled={!this.props.ready}
            modalOpen={this.props.ready}
            modalWidthPct={90}
        >

                    {this.state.errorMsg}

                    For {extraEvidence.typeMapping[this.props.evidenceType].name} evidence details

                    Fields marked in a green background are specifically relevant to this Criteria Code.

                <Form submitHandler={this.submitNewEvidence} formClassName="form-horizontal form-std">
                {this.inputs()}

{this.state.errorMsg}

Please fix errors on the form and resubmit.

                    <Input type="submit" inputClassName={submitClass} title="Submit" id="submit" />
                    <Input type="button" inputClassName="btn-default btn-inline-spacer" clickHandler={this.cancel} title="Cancel" />

                </Form>

        </ModalComponent>
    }
});

module.exports = {
    EvidenceSheet: EvidenceSheet
};
<commit_msg>fixes submit error when proband_hpo_id is null<commit_after>'use strict';

// stdlib
import React from 'react';
import PropTypes from 'prop-types';
import createReactClass from 'create-react-class';

// third-party lib
import ModalComponent from '../../../../libs/bootstrap/modal';
import { Form, FormMixin, Input } from '../../../../libs/bootstrap/form';
import _ from 'underscore';

// Internal lib
import { extraEvidence } from './segregationData';
import { external_url_map } from '../../../globals';
import { RestMixin } from '../../../rest';
import * as curator from '../../../curator';

let EvidenceSheet = createReactClass({
    mixins: [FormMixin, RestMixin],

    propTypes: {
        ready: PropTypes.bool,                      // Flag if ready for second modal
        sheetDone: PropTypes.func,                  // Function to call to add or edit an evidence
        data: PropTypes.object,                     // Data relevant to this particular piece of evidence
        allData: PropTypes.object,                  // All extra evidence across all entries for this variant
        isNew: PropTypes.bool,                      // If we are adding a new piece of evidence or editing an existing piece
        isFromMaster: PropTypes.bool,               // If editing an existing evidence by clicking edit button in master/tally table
        subcategory: PropTypes.string,              // Subcategory (usually the panel) the evidence is part of
        evidenceType: PropTypes.string              // Evidence source type
    },

    getInitialState: function() {
        let data =  {};
        let hpoUnaffected = false;
        let hpoData = [];
        if (this.props.data) {
            data = this.props.data;
            hpoUnaffected = this.props.data.is_disease_associated_with_probands;
            hpoData = this.props.data.hpoData ? this.props.data.hpoData : [];
        }
        return {
            data: data,
            hpoData: hpoData,
            hpoUnaffected: hpoUnaffected,  // Flag for "Disease associated with proband(s) (HPO)" checkbox
            backgroundGreen: '#00FF0030',
            errorMsg: '',
            enableSubmit: true             // Flag to enable Submit button
        };
    },

    componentDidMount() {
        this.props.onRef(this);
    },

    componentWillUnmount() {
        this.props.onRef(null);
    },

    handleModalClose() {
        this.child.closeModal();
    },

    cancel() {
        this.props.sheetDone(null);
        this.handleModalClose();
    },

    showError(msg) {
        this.setState({
            errorMsg: msg
        });
    },

    enableSubmitButton(flag) {
        this.setState({
            enableSubmit: flag
        });
    },

    clearHpoTerms() {
        this.setState({ hpoData: [] });
        this.clrFormErrors('proband_hpo_ids');
    },

    /**
     * Submit button is clicked.  Save all form data and call function to save in db.
     * Close the modal.
     *
     * @param {object} e    // event
     */
    submitNewEvidence(e) {
        e.preventDefault();
        e.stopPropagation();

        this.saveAllFormValues();
        const formValues = this.getAllFormValues();

        let formError = false;
        if (this.validateDefault()) {
            // Check HPO ID format
            const hpoIds = curator.capture.hpoids(this.getFormValue('proband_hpo_ids'));
            const filteredIds = this.filterOutExtraHpo(hpoIds);
            const duplicateExists = this.checkForDuplicateHpo(hpoIds);
            if (hpoIds && hpoIds.length && _(hpoIds).any(id => id === null)) {
                // HPOID list is bad
                formError = true;
                this.setFormErrors('proband_hpo_ids', 'Use HPO IDs (e.g. HP:0000001) separated by commas');
            } else if (duplicateExists) {
                formError = true;
                this.setFormErrors('proband_hpo_ids', 'Please remove duplicate IDs.')
            } else if (filteredIds && filteredIds.length) {
                // Input and hpoData don't match
                formError = true;
                this.setFormErrors('proband_hpo_ids', `The terms and IDs above do not match. Please remove or retrieve terms again. (${filteredIds.join(', ')})`)
            }
            if (!formError) {
                let allData = null;
                let hpoData = {hpoData: this.state.hpoData};
                if (this.props.isNew) {
                    allData = Object.assign(this.props.data, formValues, hpoData);
                } else {
                    allData = Object.assign({}, this.props.data);
                    Object.assign(allData, formValues, hpoData);
                }
                this.handleModalClose();
                this.resetAllFormValues();
                this.setState({
                    data: {},
                    hpoData: [],
                    hpoUnaffected: false
                });
                this.props.sheetDone(allData);
            }
        }
    },

    /**
     * Given the subcategory, return a list of allowed fields.
     * This is used to highlight the input.
     */
    allowedFields() {
        let tableObj = _.find(extraEvidence.tableCols(), o => o.subcategory === this.props.subcategory);
        let fields = tableObj && tableObj.cols ? tableObj.cols.map(col => col.key) : [];
        if (fields.indexOf('comments') != -1) {
            fields.splice(fields.indexOf('comments'), 1);
        }
        return fields;
    },

    /**
     * If the "Disease associated with proband(s) (HPO) (Check here if unaffected)"
     * checkbox is toggled, save its current state.
     *
     * @param {string} ref
     * @param {event} e
     */
    handleCheckboxChange(ref, e) {
        if (ref === 'is_disease_associated_with_probands') {
            this.setState({hpoUnaffected: this.refs[ref].toggleValue()});
        }
    },

    /**
     * Check for duplicates and return a boolean value accordingly
     * @param {array} inputIds
     */
    checkForDuplicateHpo(inputIds) {
        if (inputIds && inputIds.length) {
            return inputIds.some((id, index) => inputIds.indexOf(id) !== index)
        }
    },

    /**
     * Check that hpoData and proband_hpo_ids are the same
     * If not, returns array of rejected ids for form validation
     * @param {array} inputIds
     */
    filterOutExtraHpo(inputIds) {
        const hpoData = this.state.hpoData;
        if (hpoData && hpoData.length) {
            const idsFromHpoData = [];
            hpoData.forEach(obj =>{
                idsFromHpoData.push(obj.hpoId);
            });
            if (inputIds.length > idsFromHpoData.length) {
                return inputIds.filter(id => !idsFromHpoData.includes(id));
            } else if (idsFromHpoData.length > inputIds.length) {
                return idsFromHpoData.filter(id => !inputIds.includes(id));
            }
        }
    },

    /**
     * Display the input fields with available values
     */
    inputs() {
        let jsx = [];
        let i = 0;
        let trStyle = {
            'display': 'flex',
            'alignItems': 'flex-end'
        };

        // Get a list of allowed fields
        let fields = this.allowedFields();

        extraEvidence.evidenceInputs.forEach(row => {
            let rowTDs = [];
            let done = false;
            row.cols.forEach(col => {
                let value = '';
                if (this.state.data != null && Object.keys(this.state.data).length > 0) {
                    value = this.state.data[col.name];
                }

                // Set up the label for the input
                let codes = extraEvidence.fieldToCriteriaCodeMapping
                    .filter(obj => obj.key === col.name)
                    .map(obj => obj.codes);
                let label = col.label;
                if (codes.length > 0) {
                    label += ` (${codes.join(', ')})`;
                }

                let node = [<div className={`col-md-${col.width}`}  style={{textAlign: 'left'}} key={i++}>
                    <Input
                        type = {col.kind}
                        label = {label}
                        name = {col.name}
                        ref = {col.name}
                        value = {col.kind != 'checkbox' ? value : null}
                        checked = {col.name === 'is_disease_associated_with_probands' && this.state.hpoUnaffected != undefined ? this.state.hpoUnaffected : false}
                        handleChange = {col.kind === 'checkbox' ? this.handleCheckboxChange : null}
                        error = {this.getFormError(col.name)}
                        clearError = {this.clrFormErrors.bind(null, col.name)}
                        fieldStyle = {fields.indexOf(col.name) == -1 || this.props.isFromMaster ? null : {backgroundColor: this.state.backgroundGreen}}
                    />

]
                if ('lookup' in col) {
                    // Push nodes separately so elements do not stack vertically
                    node.push(

                            <Input
                                type="button"
                                inputClassName="btn btn-primary btn-default get-terms-btn"
                                title="Get Terms"
                                clickHandler={() => this.lookupTerm()}
                            >
                            </Input>

                    );
                    node.push(

                            <Input
                                type="button"
                                inputClassName="btn btn-danger btn-default clear-terms-btn"
                                title="Clear Terms"
                                clickHandler={() => this.clearHpoTerms()}
                            >
                            </Input>

                    );
                    node.push(

                            Terms for phenotypic feature(s) associated with proband(s):
                            {this.renderLookupResult()}

                    );
                }
                rowTDs.push(node);
                // if field needs to be put in its own row, add it here.
                if (col.width === 12) {
                    let rowTR =

                        {rowTDs}

                    jsx.push(rowTR);
                    rowTDs = [];
                    done = true;
                }
            });
            // if row has not been added, add it here.
            if (!done) {
                let rowTR =

                    {rowTDs}

                jsx.push(rowTR);
            }
        });
        return jsx;
    },

    /**
     * Renders list of saved HPO terms and their respective ids
     */
    renderLookupResult() {
        if (this.state.hpoData && !this.state.hpoData.length) {
            return null;
        }
        if (this.state.hpoData && this.state.hpoData.length) {
            let hpo = this.state.hpoData.map((obj, i) => {
                return
{obj.hpoTerm} ({obj.hpoId})

            });

            let node = (

                        {hpo}

            );
            return node;
        }
    },

    /**
     *
     * @param {string} hpoIds
     */
    validateHpo(hpoIds) {
        const checkIds = curator.capture.hpoids(hpoIds);
        // Check HPO ID format
        if (checkIds && checkIds.length && _(checkIds).any(id => id === null)) {
            // HPOID list is bad
            this.setFormErrors('proband_hpo_ids', 'For term lookup, use HPO IDs (e.g. HP:0000001) separated by commas');
        }
        else if (checkIds && checkIds.length && !_(checkIds).any(id => id === null)) {
            const hpoIdList = _.without(checkIds, null);
            return _.uniq(hpoIdList);
        }
    },

    /**
     * Fetch terms from proband_hpo_id form value, save to state as array of objects
     */
    lookupTerm() {
        this.saveAllFormValues();
        const hpoIds = this.getFormValue('proband_hpo_ids');
        const validatedHpoList = this.validateHpo(hpoIds);
        const hpoWithTerms = [];
        if (validatedHpoList) {
            validatedHpoList.forEach(id => {
                let url = external_url_map['HPOApi'] + id;
                this.getRestData(url).then(result => {
                    const term = result['details']['name'];
                    const hpo = {hpoId: id, hpoTerm: term};
                    hpoWithTerms.push(hpo);
                    this.setState({ hpoData: hpoWithTerms });
                }).catch(err => {
                    // Unsuccessful retrieval
                    console.warn('Error in fetching HPO data =: %o', err);
                    const term = 'Term not found';
                    const hpo = {hpoId: id, hpoTerm: term};
                    hpoWithTerms.push(hpo);
                    this.setState({ hpoData: hpoWithTerms });
                });
            });
            this.clrFormErrors('proband_hpo_ids');
        }
    },

    render() {
        var submitErrClass = 'submit-err ' + (this.anyFormErrors() ? '' : ' hidden');
        var errMsgClass = this.state.errorMsg === '' ? 'hidden' : '';
        var submitClass = "btn-default btn-inline-spacer btn-primary" + (this.state.errorMsg === '' && this.state.enableSubmit === true ? '' : ' disabled');
        var showMsgClass = this.props.isFromMaster ? 'hidden' : '';

        return  <ModalComponent
            modalTitle={this.props.isNew ? "Add Evidence Details" : "Edit Evidence Details"}
            modalClass="modal-default"
            modalWrapperClass="input-inline add-resource-id-modal"
            onRef={ref => (this.child = ref)}
            actuatorDisabled={!this.props.ready}
            modalOpen={this.props.ready}
            modalWidthPct={90}
        >

                    {this.state.errorMsg}

                    For {extraEvidence.typeMapping[this.props.evidenceType].name} evidence details

                    Fields marked in a green background are specifically relevant to this Criteria Code.

                <Form submitHandler={this.submitNewEvidence} formClassName="form-horizontal form-std">
                {this.inputs()}

{this.state.errorMsg}

Please fix errors on the form and resubmit.

                    <Input type="submit" inputClassName={submitClass} title="Submit" id="submit" />
                    <Input type="button" inputClassName="btn-default btn-inline-spacer" clickHandler={this.cancel} title="Cancel" />

                </Form>

        </ModalComponent>
    }
});

module.exports = {
    EvidenceSheet: EvidenceSheet
};
<|endoftext|>


<commit_before>var current_page = 1;

function handlePaginationClick(new_page_index, pagination_container) {
  showLinks(new_page_index);
  current_page = new_page_index;
  return false;
}

function initPagination(number_pages) {
  $(".navigation").pagination(number_pages, {
    items_per_page:100,
    callback:handlePaginationClick
  });
}

function initTrees() {
  $(".details-tree").treeview();

  // fix '+' and '-' icons:
  $("li.expandable").removeClass("expandable").addClass("collapsable");
  $("li.lastExpandable").removeClass("lastExpandable").addClass("lastCollapsable");
  $("div.expandable-hitarea").removeClass("expandable-hitarea").addClass("collapsable-hitarea");

  $(".confidencebar").each(function(index) {
    $(this).progressbar({
      value: parseInt($(this).text())
    });
  });
}

function toggleLinkDetails(linkid) {
  if ($("#details" + linkid).is(":visible")) {
    $("#toggle" + linkid + " > span").removeClass('ui-icon-triangle-1-s').addClass('ui-icon-triangle-1-e');
    $("#details" + linkid).slideUp(300);
  } else {
    $("#toggle" + linkid + " > span").removeClass('ui-icon-triangle-1-e').addClass('ui-icon-triangle-1-s');
    $("#details" + linkid).slideDown(300);
  }
}

function expand_all() {
  $(".link-details").show();
}
function hide_all() {
  $(".link-details").hide();
}

$(function() {
  $("#selectLinks").buttonset();

  $(".link-header").live('click', function(e) {
    var link_id = $(this).parent().attr('id');
    if ($(e.target).is('a')) return;
    toggleLinkDetails(link_id);
  });

});<commit_msg>don't toggle link details if clicked on img button<commit_after>var current_page = 1;

function handlePaginationClick(new_page_index, pagination_container) {
  showLinks(new_page_index);
  current_page = new_page_index;
  return false;
}

function initPagination(number_pages) {
  $(".navigation").pagination(number_pages, {
    items_per_page:100,
    callback:handlePaginationClick
  });
}

function initTrees() {
  $(".details-tree").treeview();

  // fix '+' and '-' icons:
  $("li.expandable").removeClass("expandable").addClass("collapsable");
  $("li.lastExpandable").removeClass("lastExpandable").addClass("lastCollapsable");
  $("div.expandable-hitarea").removeClass("expandable-hitarea").addClass("collapsable-hitarea");

  $(".confidencebar").each(function(index) {
    $(this).progressbar({
      value: parseInt($(this).text())
    });
  });
}

function toggleLinkDetails(linkid) {
  if ($("#details" + linkid).is(":visible")) {
    $("#toggle" + linkid + " > span").removeClass('ui-icon-triangle-1-s').addClass('ui-icon-triangle-1-e');
    $("#details" + linkid).slideUp(300);
  } else {
    $("#toggle" + linkid + " > span").removeClass('ui-icon-triangle-1-e').addClass('ui-icon-triangle-1-s');
    $("#details" + linkid).slideDown(300);
  }
}

function expand_all() {
  $(".link-details").show();
}
function hide_all() {
  $(".link-details").hide();
}

$(function() {
  $("#selectLinks").buttonset();

  $(".link-header").live('click', function(e) {
    var link_id = $(this).parent().attr('id');
    if ($(e.target).is('a, img')) return;
    toggleLinkDetails(link_id);
  });

});<|endoftext|>


<commit_before>var Blog = require("blog");
var config = require("config");

module.exports = function(req, res, next) {
  var identifier, handle, redirect, previewTemplate, err;
  var host = req.get("host");

  // Not sure why this happens but it do
  if (!host) {
    err = new Error("No blog");
    err.code = "ENOENT";
    return next(err);
  }

  // Cache the original host for use in templates
  // this should be req.locals.originalHost
  req.originalHost = host;

  // We don't want to serve a blog in place of
  // the main blot site so leave now.
  if (host === config.host) return next();

  // Redirect www subdomain of main blot site to
  // the apex domain on which it is served.
  if (host === "www." + config.host) {
    return res.redirect(req.protocol + "://" + config.host + req.originalUrl);
  }

  handle = extractHandle(host);

  if (handle) {
    identifier = { handle: handle };
  } else {
    identifier = { domain: host };
  }

  Blog.get(identifier, function(err, blog) {
    if (err) return next(err);

    if (!blog || blog.isDisabled || blog.isUnpaid) {
      err = new Error("No blog");
      err.code = "ENOENT";
      return next(err);
    }

    // Probably a www -> apex redirect
    if (identifier.domain && blog.domain !== identifier.domain)
      redirect = req.protocol + "://" + blog.domain + req.originalUrl;

    // Redirect HTTP to HTTPS
    if (identifier.domain && blog.forceSSL && req.protocol !== "https")
      redirect = "https://" + blog.domain + req.originalUrl;

    // Redirect old handle
    if (identifier.handle && blog.handle !== identifier.handle)
      redirect =
        req.protocol + "://" + blog.handle + "." + config.host + req.originalUrl;

    // Redirect Blot subdomain to custom domain we use
    // 302 temporary since the domain might break in future
    if (identifier.handle && blog.domain && blog.redirectSubdomain)
      return res.status(302).redirect(req.protocol + "://" + blog.domain + req.originalUrl);

    // Should we be using 302 temporary for this?
    if (redirect) return res.status(301).redirect(redirect);

    previewTemplate = extractPreviewTemplate(host, blog.id);

    // Retrieve the name of the template from the host
    // If the request came from a preview domain
    // e.g preview.original.david.blot.im
    if (previewTemplate) {
      req.preview = true;
      res.set("Cache-Control", "no-cache");

      // construct the template ID
      blog.template = previewTemplate;

      // don't use the deployed asset for preview subdomains
      blog.cssURL = Blog.url.css(blog.cacheID);
      blog.scriptURL = Blog.url.js(blog.cacheID);
    } else {
      req.preview = false;
    }

    // Load in pretty and shit...
    // this must follow preview
    // since cssURL and scriptURL
    // for subdomains.
    blog = Blog.extend(blog);

    blog.locals = blog.locals || {};

    // Store the original request's url so templates {{blogURL}}
    blog.locals.blogURL = req.protocol + "://" + req.originalHost;
    blog.locals.siteURL = "https://" + config.host;

    // Store the blog's info so routes can access it
    req.blog = blog;

    return next();
  });
};

function isSubdomain(host) {
  return (
    host.slice(-config.host.length) === config.host &&
    host.slice(0, -config.host.length).length > 1
  );
}

function extractHandle(host) {
  if (!isSubdomain(host, config.host)) return false;

  return host
    .slice(0, -config.host.length - 1)
    .split(".")
    .pop();
}

function extractPreviewTemplate(host, blogID) {
  if (!isSubdomain(host, config.host)) return false;

  var subdomains = host.slice(0, -config.host.length - 1).split(".");
  var handle = subdomains.pop();
  var prefix = subdomains.shift();

  if (!subdomains || !subdomains.length || prefix !== "preview") return false;

  var name = subdomains.pop();
  var isBlots = !subdomains.pop();

  if (host === handle + "." + config.host) return false;

  var owner = isBlots ? "SITE" : blogID;

  return owner + ":" + name;
}
<commit_msg>Redirect insecure Blot subdomains when possible<commit_after>var Blog = require("blog");
var config = require("config");

module.exports = function(req, res, next) {
  var identifier, handle, redirect, previewTemplate, err;
  var host = req.get("host");

  // Not sure why this happens but it do
  if (!host) {
    err = new Error("No blog");
    err.code = "ENOENT";
    return next(err);
  }

  // Cache the original host for use in templates
  // this should be req.locals.originalHost
  req.originalHost = host;

  // We don't want to serve a blog in place of
  // the main blot site so leave now.
  if (host === config.host) return next();

  // Redirect www subdomain of main blot site to
  // the apex domain on which it is served.
  if (host === "www." + config.host) {
    return res.redirect(req.protocol + "://" + config.host + req.originalUrl);
  }

  handle = extractHandle(host);

  if (handle) {
    identifier = { handle: handle };
  } else {
    identifier = { domain: host };
  }

  Blog.get(identifier, function(err, blog) {
    if (err) return next(err);

    if (!blog || blog.isDisabled || blog.isUnpaid) {
      err = new Error("No blog");
      err.code = "ENOENT";
      return next(err);
    }

    previewTemplate = extractPreviewTemplate(host, blog.id);

    // Probably a www -> apex redirect
    if (identifier.domain && blog.domain !== identifier.domain)
      redirect = req.protocol + "://" + blog.domain + req.originalUrl;

    // Redirect old handle
    if (identifier.handle && blog.handle !== identifier.handle)
      redirect =
        req.protocol + "://" + blog.handle + "." + config.host + req.originalUrl;

    // Redirect Blot subdomain to custom domain we use
    // 302 temporary since the domain might break in future
    if (identifier.handle && blog.domain && blog.redirectSubdomain)
      return res.status(302).redirect(req.protocol + "://" + blog.domain + req.originalUrl);

    // Redirect HTTP to HTTPS. Preview subdomains are not currently
    // available over HTTPS but when they are, remove this.
    if (blog.forceSSL && req.protocol === "http" && !previewTemplate)
      redirect = "https://" + blog.domain + req.originalUrl;

    // Should we be using 302 temporary for this?
    if (redirect) return res.status(301).redirect(redirect);

    // Retrieve the name of the template from the host
    // If the request came from a preview domain
    // e.g preview.original.david.blot.im
    if (previewTemplate) {
      req.preview = true;
      res.set("Cache-Control", "no-cache");

      // construct the template ID
      blog.template = previewTemplate;

      // don't use the deployed asset for preview subdomains
      blog.cssURL = Blog.url.css(blog.cacheID);
      blog.scriptURL = Blog.url.js(blog.cacheID);
    } else {
      req.preview = false;
    }

    // Load in pretty and shit...
    // this must follow preview
    // since cssURL and scriptURL
    // for subdomains.
    blog = Blog.extend(blog);

    blog.locals = blog.locals || {};

    // Store the original request's url so templates {{blogURL}}
    blog.locals.blogURL = req.protocol + "://" + req.originalHost;
    blog.locals.siteURL = "https://" + config.host;

    // Store the blog's info so routes can access it
    req.blog = blog;

    return next();
  });
};

function isSubdomain(host) {
  return (
    host.slice(-config.host.length) === config.host &&
    host.slice(0, -config.host.length).length > 1
  );
}

function extractHandle(host) {
  if (!isSubdomain(host, config.host)) return false;

  return host
    .slice(0, -config.host.length - 1)
    .split(".")
    .pop();
}

function extractPreviewTemplate(host, blogID) {
  if (!isSubdomain(host, config.host)) return false;

  var subdomains = host.slice(0, -config.host.length - 1).split(".");
  var handle = subdomains.pop();
  var prefix = subdomains.shift();

  if (!subdomains || !subdomains.length || prefix !== "preview") return false;

  var name = subdomains.pop();
  var isBlots = !subdomains.pop();

  if (host === handle + "." + config.host) return false;

  var owner = isBlots ? "SITE" : blogID;

  return owner + ":" + name;
}
<|endoftext|>


<commit_before>class Candidate {

	constructor (config) {

		this.skills = [];
		this.contact = {
			phones: [],
			emails: [],
			sites : []
		};
		this.experiences = [];
		this.education = [];

		if (!config) {

			return;

		}

		this.setName(config.name);

		this.setRole(config.role);

		this.addSkill(config.skills || config.skill);

		this.addPhone(config.phones || config.phone);
		this.addEmail(config.emails || config.email);
		this.addSite(config.sites || config.site);
		if (config.contact) {

			this.addPhone(config.contact.phones || config.contact.phone);
			this.addEmail(config.contact.emails || config.contact.email);
			this.addSite(config.contact.sites || config.contact.site);

		}

		this.setSummary(config.summary);

		this.addExperience(config.experiences || config.experience);

		this.addEducation(config.education);

		this.render();

	}

	setName (name) {

		this.name = name || 'Annon Candidate';

		this.render();

	}

	setRole (role) {

		this.role = role || '';

		this.render();

	}

	setSummary (summary) {

		this.summary = summary || '';

		this.render();

	}

	addSkill (skill) {

		if (!skill) return;

		this._checkIsSimple(this.skills, skill, this.addSkill);
		this.render();

	}

	addPhone (phone) {

		if (!phone) return;

		this._checkIsSimple(this.contact.phones, phone, this.addPhone);
		this.render();

	}

	addEmail (email) {

		if (!email) return;

		this._checkIsSimple(this.contact.emails, email, this.addEmail);
		this.render();

	}

	addSite (site) {

		if (!site) return;

		this._checkIsSimple(this.contact.sites, site, this.addSite);
		this.render();

	}

	addExperience (experience) {

		if (!experience) return;

		this._checkIsSimple(this.experiences, experience, this.addExperience);
		this.render();

	}

	addEducation (education) {

		if (!education) return;

		this._checkIsSimple(this.education, education, this.addEducation);
		this.render();

	}

	_checkType (obj) {

		return Object.prototype.toString.call(obj).match(/\s(.*)\]/)[1].toLowerCase();

	}

	_checkIsSimple (oldObj, newObj, method) {

		switch (this._checkType(newObj)) {
		case 'object':
		case 'string':
		case 'number':
			oldObj.push(newObj);
			break;
		case 'array':
			newObj.forEach(each => method.call(this, each));
			break;
		}

	}

	render() {

		document.title = this.name + ' - CV';
		// console.log(this);

		var text = `

${this.name}

${this.role}

${this.summary}

		`;

		text += '
';
		this.skills.forEach(skill => {

			text += `

${skill}

			`;

		});
		text += '
';

		text += '
';
		this.contact.phones.forEach(phone => {

			text += `<div><a href="tel:${phone}">✆ ${phone}</a></div>`;

		});

		this.contact.emails.forEach(email => {

			text += `<div><a href="mailto:${email}">✉ ${email}</a></div>`;

		});

		this.contact.sites.forEach(site => {

			var siteName = site.match(/\/\/([^\.]*)\./)[1];
			text += `<div><a href="${site}" target="_blank">˃ ${siteName}</a></div>`;

		});
		text += '
';

		text += '
Experiences
';
		this.experiences.forEach(experience => {

			var role = experience.is || experience.was;

			text += '
';
			text += `

${role}

${experience.at}

			`;

			if (experience.on) {

				text += '
';

				if (experience.on.start) {

					text += `<span>from ${experience.on.start}</span> `;

				}

				if (experience.on && experience.on.end) {

					text += ` <span>to ${experience.on.end}</span>`;

				}

				text += '
';

			}
			text += '
';

			if (experience.tools && experience.tools.front) {

				text += '
';

				experience.tools.front.forEach(tool => {

					text += ` <span class="job-experience__tool">${tool}</span> `;

				});

				text += '
';

			}

			if (experience.portfolio) {

				text += "
";

				if (experience.portfolio.released) {

					experience.portfolio.released.forEach(url => {

						var siteName = url.match(/\/\/([^\.]*)\./)[1];
						text += ` <span><a href="${url}" target="_blank">˃ ${siteName}</a></span> `;

					});

				}

				if (experience.portfolio.unreleased) {

					experience.portfolio.unreleased.forEach(url => {

						var siteName = url.match(/\/\/([^\.]*)\./)[1];
						text += ` <span><a href="${url}" target="_blank">˃ ${siteName}</a></span> `;

					});

				}

				if (experience.portfolio.dismissed) {

					experience.portfolio.dismissed.forEach(url => {

						var siteName = url.match(/\/\/([^\.]*)\./)[1];
						text += ` <span><a href="${url}" target="_blank">˃ ${siteName}</a></span> `;

					});

				}

				text += "
";

			}

			text += (function () {
				var description = experience.description.replace(/(\n)(\n)/g, '$1

$2');
				return `<p>${description}</p>`;
			}());

			text += "
";

		});

		text += '
Education
';
		this.education.forEach(education => {

			text += '
';
			if (education.titles) {

				education.titles.forEach(title => {

					text += `<h4>${title}</h4>`;

				});

			}

			text += `
				${education.on}
				@ ${education.at}
			`;
			text += "
";

		});

		document.body.innerHTML = text;

	}

}
<commit_msg>Separate the templates<commit_after>templates = {

	header: function (name, role) {

		return `

${name}

${role}

`;

	},

	skillSet: function (skills) {

		var text = '
';
		skills.forEach(skill => {

			text += `<li class="skill-set__item">${skill}</li>`;

		});
		text += '
';

		return text;

	},

	contactSet: function (contact) {

		var text = '

';
		contact.emails.forEach(email => {

			text += `<span><a href="mailto:${email}">✉ ${email}</a></span>`;

		});
		text += `</div><div class="contact-set__row">`;
		contact.phones.forEach(phone => {

			text += `<span><a href="tel:${phone}">✆ ${phone}</a></span>`;

		});
		text += `</div><div class="contact-set__row">`;
		text += contact.sites.map(templates.url).join('');
		text += '

';

		return text;

	},

	experience: function (experiences) {

		var text = '
Experiences

';
		experiences.forEach(experience => {

			var role = experience.is || experience.was;

			text += '
';
			text += `

${role}

${experience.at}

			`;

			if (experience.on) {

				text += '
';

				if (experience.on.start) {

					text += `<span>from ${experience.on.start}</span> `;

				}

				if (experience.on && experience.on.end) {

					text += ` <span>to ${experience.on.end}</span>`;

				}

				text += '
';

			}
			text += '
';

			if (experience.tools && experience.tools.front) {

				text += '
';

				experience.tools.front.forEach(tool => {

					text += ` <span class="job-experience__tool">${tool}</span> `;

				});

				text += '
';

			}

			if (experience.portfolio) {

				text += '
';

				if (experience.portfolio.released) {

					text += experience.portfolio.released.map(templates.url).join('');

				}

				if (experience.portfolio.unreleased) {

					text += experience.portfolio.unreleased.map(templates.url).join('');

				}

				if (experience.portfolio.dismissed) {

					text += experience.portfolio.dismissed.map(templates.url).join('');

				}

				text += "
";

			}

			text += templates.summary('job-experience__summary', experience.description);

			text += "

";

		});

		return text;

	},

	education: function (educations) {

		var text = '
Education

';
		educations.forEach(education => {

			text += '
';
			if (education.titles) {

				education.titles.forEach(title => {

					text += `<h4 class="education-experience__title">${title}</h4>`;

				});

			}

			text += `
				${education.on}
				@ ${education.at}
			`;

			text += "

";

		});

		return text;

	},

	url: function (url) {

		var siteName = url.match(/\/\/([^\.]*)\./)[1];
		return ` <span><a href="${url}" target="_blank">˃ ${siteName}</a></span> `;

	},

	summary: function (className, summary) {

		var text = summary.replace(/(\n)(\n)/g, '$1

$2');
		return `<p class="${className}">${text}</p>`;

	}

};

class Candidate {

	constructor (config) {

		this.skills = [];
		this.contact = {
			phones: [],
			emails: [],
			sites : []
		};
		this.experiences = [];
		this.education = [];

		if (!config) {

			return;

		}

		this.setName(config.name);

		this.setRole(config.role);

		this.addSkill(config.skills || config.skill);

		this.addPhone(config.phones || config.phone);
		this.addEmail(config.emails || config.email);
		this.addSite(config.sites || config.site);
		if (config.contact) {

			this.addPhone(config.contact.phones || config.contact.phone);
			this.addEmail(config.contact.emails || config.contact.email);
			this.addSite(config.contact.sites || config.contact.site);

		}

		this.setSummary(config.summary);

		this.addExperience(config.experiences || config.experience);

		this.addEducation(config.education);

		this.render();

	}

	setName (name) {

		this.name = name || 'Annon Candidate';

		this.render();

	}

	setRole (role) {

		this.role = role || '';

		this.render();

	}

	setSummary (summary) {

		this.summary = summary || '';

		this.render();

	}

	addSkill (skill) {

		if (!skill) return;

		this._checkIsSimple(this.skills, skill, this.addSkill);
		this.render();

	}

	addPhone (phone) {

		if (!phone) return;

		this._checkIsSimple(this.contact.phones, phone, this.addPhone);
		this.render();

	}

	addEmail (email) {

		if (!email) return;

		this._checkIsSimple(this.contact.emails, email, this.addEmail);
		this.render();

	}

	addSite (site) {

		if (!site) return;

		this._checkIsSimple(this.contact.sites, site, this.addSite);
		this.render();

	}

	addExperience (experience) {

		if (!experience) return;

		this._checkIsSimple(this.experiences, experience, this.addExperience);
		this.render();

	}

	addEducation (education) {

		if (!education) return;

		this._checkIsSimple(this.education, education, this.addEducation);
		this.render();

	}

	_checkType (obj) {

		return Object.prototype.toString.call(obj).match(/\s(.*)\]/)[1].toLowerCase();

	}

	_checkIsSimple (oldObj, newObj, method) {

		switch (this._checkType(newObj)) {
		case 'object':
		case 'string':
		case 'number':
			oldObj.push(newObj);
			break;
		case 'array':
			newObj.forEach(each => method.call(this, each));
			break;
		}

	}

	render() {

		document.title = this.name + ' - CV';

		document.body.innerHTML = '';
		document.body.innerHTML += templates.header(this.name, this.role);
		document.body.innerHTML += templates.contactSet(this.contact);
		document.body.innerHTML += templates.summary('summary', this.summary || '');
		//document.body.innerHTML += templates.skillSet(this.skills);
		document.body.innerHTML += templates.experience(this.experiences);
		document.body.innerHTML += templates.education(this.education);

	}

}
<|endoftext|>


<commit_before>(function(app) {
	app.HTTPService = (function() {
		var HTTPService = function(http) {
			this.http = http;
		};
		HTTPService.parameters = [
			ng.http.Http
		];
		HTTPService.prototype.get = function(reqId, url, o, p) {
			return this.http
				.get(url + '?reqid=' + reqId + '&o=' + o + '&p=' + p, {
					"cache":   false,
					"headers": {
						"Cache-Control":     'no-cache, no-store, must-revalidate',
						"If-Modified-Since": 'Mon, 26 Jul 1997 05:00:00 GMT',
						"Pragma":            'no-cache',
						"X-ReqId":           reqId
					}
				})
				.map(function(response) {
					return {
						"json":  response.json() || {},
						"reqId": parseInt(response.headers.get('X-ReqId')||response.headers.get('x-reqid')),
						"rtt":   parseInt(response.headers.get('X-Angular-Time') || response.headers.get('x-angular-time')),
						"tsn":   (parseFloat(response.headers.get('X-nginX-Time') || response.headers.get('x-nginx-time')) * 1000.0) | 0,
						"exts":  parseFloat(response.headers.get('X-Node-Time') || response.headers.get('x-node-time')),
						"red":   parseFloat(response.headers.get('X-Redis-Time') || response.headers.get('x-redis-time'))
					};
				})
				.catch();
		};
		HTTPService.prototype.post = function(url, body) {
			return this.http
				.post(url + '?time=' + Date.now(), body, {
					"cache":   false,
					"headers": {
						"Cache-Control":     'no-cache, no-store, must-revalidate',
						"If-Modified-Since": 'Mon, 26 Jul 1997 05:00:00 GMT',
						"Pragma":            'no-cache'
					}
				})
				.map(function(response) {
					return response.json() || {};
				})
				.catch();
		};
		return HTTPService;
	})();
})(window.app || (window.app = {}));
<commit_msg>Simpler implementation - operation chosen by client or stress tool<commit_after>(function(app) {
	app.HTTPService = (function() {
		var HTTPService = function(http) {
			this.http = http;
		};
		HTTPService.parameters = [
			ng.http.Http
		];
		HTTPService.prototype.get = function(reqId, url, o, p) {
			return this.http
				.get(url + '?o=' + o + '&p=' + p, {
					"cache":   false,
					"headers": {
						"Cache-Control":     'no-cache, no-store, must-revalidate',
						"If-Modified-Since": 'Mon, 26 Jul 1997 05:00:00 GMT',
						"Pragma":            'no-cache',
						"X-ReqId":           reqId
					}
				})
				.map(function(response) {
					return {
						"json":  response.json() || {},
						"reqId": parseInt(response.headers.get('X-ReqId')||response.headers.get('x-reqid')),
						"rtt":   parseInt(response.headers.get('X-Angular-Time') || response.headers.get('x-angular-time')),
						"tsn":   (parseFloat(response.headers.get('X-nginX-Time') || response.headers.get('x-nginx-time')) * 1000.0) | 0,
						"exts":  parseFloat(response.headers.get('X-Node-Time') || response.headers.get('x-node-time')),
						"red":   parseFloat(response.headers.get('X-Redis-Time') || response.headers.get('x-redis-time'))
					};
				})
				.catch();
		};
		HTTPService.prototype.post = function(url, body) {
			return this.http
				.post(url + '?time=' + Date.now(), body, {
					"cache":   false,
					"headers": {
						"Cache-Control":     'no-cache, no-store, must-revalidate',
						"If-Modified-Since": 'Mon, 26 Jul 1997 05:00:00 GMT',
						"Pragma":            'no-cache'
					}
				})
				.map(function(response) {
					return response.json() || {};
				})
				.catch();
		};
		return HTTPService;
	})();
})(window.app || (window.app = {}));
<|endoftext|>


<commit_before>/**
 * Dataset display page JS module
 */
define([
    'jquery',
    'logger',
    'i18n',
    'auth',
    'api',
    'leaflet',
    'hbs!templates/dataset/resource-modal-body',
    'hbs!templates/dataset/extras-modal-body',
    'hbs!templates/dataset/add-reuse-modal-body',
    'form/common',
    'widgets/modal',
    'widgets/featured',
    'widgets/follow-btn',
    'widgets/issues-btn',
    'widgets/share-btn',
], function($, log, i18n, Auth, API, L, template, extrasTpl, addReuseTpl, forms, modal) {
    'use strict';

    var user_reuses;

    function prepare_resources() {
        $('.resources-list').items('http://schema.org/DataDownload').each(function() {
            var $this = $(this);

            // Prevent default click on link
            $this.find('a[itemprop="url"]').click(function(e) {
                e.preventDefault();
            })

            // Ensure toolbar links does not interfere
            $this.find('.tools a').click(function(e) {
                e.stopPropagation();
            })

            // Display detailled informations in a modal
            $this.click(function() {
                modal({
                    title: $this.property('name').value(),
                    content: template($this.microdata()[0]),
                    actions: [{
                        label: i18n._('Download'),
                        url: $this.property('url').value(),
                        classes: 'btn-success'
                    }]
                });
            });

        });

        // Hide expander on click
        $('.expander').click(function() {
            $(this).animate({height: 0, opacity: 0}, function() {
                $(this).remove();
            });
        });
    }

    function fetch_reuses() {
        if (Auth.user) {
            API.get('/me/reuses/', function(data) {
                user_reuses = data;
            });
        }
    }

    function add_reuse() {
        var $this = $(this);
        if (user_reuses) {
            var url_pattern = $this.data('add-url'),
                $modal = modal({
                    title: i18n._('Add a reuse'),
                    content: addReuseTpl({
                        reuses: $.map(user_reuses, function(reuse) {
                            reuse.add_url = url_pattern.replace('{placeholder}', reuse.id);
                            return reuse;
                        }),
                        new_reuse_url: $this.attr('href'),
                        csrf_token: forms.csrftoken,
                        dataset: $('.dataset-container').attr('itemid')
                    })
                });
            $modal.on('shown.bs.modal', function() {
                forms.handle_postables($modal.find('a.reuse.postable'));
            });
            return false;
        }
    }

    function load_coverage_map() {
        var $el = $('#coverage-map'),
            attributions = '© OpenStreetMap / MapQuest',
            tilesUrl = 'http://otile{s}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png',
            map, layer;

        if (!$el.length) {
            return;
        }

        map = L.map($el[0], {zoomControl: false});
        layer = L.geoJson($el.data('geojson'));

        // Disable drag and zoom handlers.
        map.dragging.disable();
        map.touchZoom.disable();
        map.doubleClickZoom.disable();
        map.scrollWheelZoom.disable();

        // Disable tap handler, if present.
        if (map.tap) map.tap.disable();

        L.tileLayer(tilesUrl, {subdomains: '1234', attribution: attributions}).addTo(map);
        layer.addTo(map);
        map.fitBounds(layer.getBounds());
    }

    function display_extras() {
        var $Dataset = $('body').items('http://schema.org/Dataset').eq(0),
            data = $Dataset.microdata()[0];

        data['id'] = $Dataset.attr('itemid');
        if (typeof data['keywords'] == 'string' || data['keywords'] instanceof String) {
            data['keywords'] = [data['keywords']];
        }
        modal({
            title: i18n._('Details'),
            content: extrasTpl(data)
        });
    }

    return {
        start: function() {
            log.debug('Dataset display page');
            $('.reuse.add').click(add_reuse);
            $('.btn-extras').click(display_extras);
            load_coverage_map();
            prepare_resources();
            fetch_reuses();
        }
    }
});
<commit_msg>Fix tiles in HTTPS<commit_after>/**
 * Dataset display page JS module
 */
define([
    'jquery',
    'logger',
    'i18n',
    'auth',
    'api',
    'leaflet',
    'hbs!templates/dataset/resource-modal-body',
    'hbs!templates/dataset/extras-modal-body',
    'hbs!templates/dataset/add-reuse-modal-body',
    'form/common',
    'widgets/modal',
    'widgets/featured',
    'widgets/follow-btn',
    'widgets/issues-btn',
    'widgets/share-btn',
], function($, log, i18n, Auth, API, L, template, extrasTpl, addReuseTpl, forms, modal) {
    'use strict';

    var user_reuses;

    function prepare_resources() {
        $('.resources-list').items('http://schema.org/DataDownload').each(function() {
            var $this = $(this);

            // Prevent default click on link
            $this.find('a[itemprop="url"]').click(function(e) {
                e.preventDefault();
            })

            // Ensure toolbar links does not interfere
            $this.find('.tools a').click(function(e) {
                e.stopPropagation();
            })

            // Display detailled informations in a modal
            $this.click(function() {
                modal({
                    title: $this.property('name').value(),
                    content: template($this.microdata()[0]),
                    actions: [{
                        label: i18n._('Download'),
                        url: $this.property('url').value(),
                        classes: 'btn-success'
                    }]
                });
            });

        });

        // Hide expander on click
        $('.expander').click(function() {
            $(this).animate({height: 0, opacity: 0}, function() {
                $(this).remove();
            });
        });
    }

    function fetch_reuses() {
        if (Auth.user) {
            API.get('/me/reuses/', function(data) {
                user_reuses = data;
            });
        }
    }

    function add_reuse() {
        var $this = $(this);
        if (user_reuses) {
            var url_pattern = $this.data('add-url'),
                $modal = modal({
                    title: i18n._('Add a reuse'),
                    content: addReuseTpl({
                        reuses: $.map(user_reuses, function(reuse) {
                            reuse.add_url = url_pattern.replace('{placeholder}', reuse.id);
                            return reuse;
                        }),
                        new_reuse_url: $this.attr('href'),
                        csrf_token: forms.csrftoken,
                        dataset: $('.dataset-container').attr('itemid')
                    })
                });
            $modal.on('shown.bs.modal', function() {
                forms.handle_postables($modal.find('a.reuse.postable'));
            });
            return false;
        }
    }

    function load_coverage_map() {
        console.log('protocol', location.protocol);
        var $el = $('#coverage-map'),
            ATTRIBUTIONS = [
                '©',
                'OpenStreetMap',
                '/',
                'MapQuest'
            ].join(' '),
            TILES_PREFIX = location.protocol === 'https:' ? '//otile{s}-s' : '//otile{s}',
            TILES_URL = TILES_PREFIX + '.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png',
            TILES_CONFIG = {subdomains: '1234', attribution: ATTRIBUTIONS},
            map, layer;

        if (!$el.length) {
            return;
        }

        map = L.map($el[0], {zoomControl: false});
        layer = L.geoJson($el.data('geojson'));

        // Disable drag and zoom handlers.
        map.dragging.disable();
        map.touchZoom.disable();
        map.doubleClickZoom.disable();
        map.scrollWheelZoom.disable();

        // Disable tap handler, if present.
        if (map.tap) map.tap.disable();

        L.tileLayer(TILES_URL, TILES_CONFIG).addTo(map);
        layer.addTo(map);
        map.fitBounds(layer.getBounds());
    }

    function display_extras() {
        var $Dataset = $('body').items('http://schema.org/Dataset').eq(0),
            data = $Dataset.microdata()[0];

        data['id'] = $Dataset.attr('itemid');
        if (typeof data['keywords'] == 'string' || data['keywords'] instanceof String) {
            data['keywords'] = [data['keywords']];
        }
        modal({
            title: i18n._('Details'),
            content: extrasTpl(data)
        });
    }

    return {
        start: function() {
            log.debug('Dataset display page');
            $('.reuse.add').click(add_reuse);
            $('.btn-extras').click(display_extras);
            load_coverage_map();
            prepare_resources();
            fetch_reuses();
        }
    }
});
<|endoftext|>