<commit_before>/**
   * These are all the HTML input types we recognize.
   * Inputs can be standalone or grouped to form a browser control.
   *
   * _listen - A function that binds necessary event listeners to the <input> elements
   */
  var inputTypes = {
    checkbox: {
      _listen: function(el, input) {
        el.addEventListener('change', function() {
          el.checked ? input.on() : input.off();
        });
      },
      _update: function(status) {
        document.getElementById(this._element).checked = status;
      }
    },
    range: {
      _listen: function(el, input) {
        el.addEventListener('change', function() {
          input.move()
        });
      },
      _update: function(status) {
        document.getElementById(this._element).value = status;
      },
      _initialize: function() {
        var el = document.getElementById(this._element);

        this.max = el.getAttribute('max') || this.max;
        el.setAttribute('max', this.max);

        this.min = el.getAttribute('min') || this.min;
        el.setAttribute('min', this.min);
      }
    }
  }<commit_msg>Just adding some comments<commit_after>/**
   * These are all the HTML input types we recognize.
   * Inputs can be standalone or grouped to form a browser control.
   *
   * _listen - A function that binds necessary event listeners to the <input> elements
   */
  var inputTypes = {

    /**
     * input type="checkbox"
     *
     * Can be bound to an LED
     **/
    checkbox: {
      _listen: function(el, input) {
        el.addEventListener('change', function() {
          el.checked ? input.on() : input.off();
        });
      },
      _update: function(status) {
        document.getElementById(this._element).checked = status;
      }
    },

    /**
     * input type="range"
     *
     * Can be bound to a servo
     **/
     range: {
      _listen: function(el, input) {
        el.addEventListener('change', function() {
          input.move()
        });
      },
      _update: function(status) {
        document.getElementById(this._element).value = status;
      },
      _initialize: function() {
        var el = document.getElementById(this._element);

        this.max = el.getAttribute('max') || this.max;
        el.setAttribute('max', this.max);

        this.min = el.getAttribute('min') || this.min;
        el.setAttribute('min', this.min);
      }
    }
  }<|endoftext|>


<commit_before>var async = require('../dist/js/async.js');

////////////////////
//DB

//DB common
function errorHandler(tx, error) {
    console.log("Error: " + error.message);
    if (debug)
    	alert("Error: " + error.message);
}
function successHandler(tx, result) {
    console.log("Success: " + result);
    if (debug)
    	alert("Success: " + result);
}

// DB init
function init_DB(callback)
{
	//init base
	if(isMobile)
    	db = window.sqlitePlugin.openDatabase("Database", "1.0", "Demo", -1);
    else
    	db = openDatabase("Database", "1.0", "Demo", -1);
	callback(null,'initDb');
}

function createTableQuestionnaires(callback)
{
	db.transaction(function(tx)
			{

				// id
				// sid : Survey ID
				// sdescription-survey_config : configuration (ex: #scheduling:D#duration:2400#startHour:10/18#maxOccurences:42#dayOff:0#test:1#)
				// gid : group ID?
				// qid : question ID
				// question
				// qtype -> template question
				// qhelp-question_config -> Configuration : template question complément, fréquence (ex: #tpl:sl7#frq:b#)
				// answers : jsontab? ex : radio buttons

				//tx.executeSql('DROP TABLE IF EXISTS "questionnaires"');
				tx.executeSql('CREATE TABLE IF NOT EXISTS "questionnaires" ' +
								' ("id" INTEGER PRIMARY KEY AUTOINCREMENT , ' +
								'  "sid" VARCHAR,' +
								'  "sdescription-survey_config" VARCHAR,' +
								'  "gid" VARCHAR,' +
								'  "qid" VARCHAR,' +
								'  "question" VARCHAR,' +
								'  "qtype" VARCHAR,' +
								'  "qhelp-question_config" VARCHAR,' +
								'  "answers" VARCHAR );');
								//'  "answers" VARCHAR );',[],callback(null,'createQuestionnairesSuccess'),callback(true,'createQuestionnairesError'));
								//'  "answers" VARCHAR );',[],createQuestionnairesSuccess,createQuestionnairesError);
			//});
			},function(tx){callback(true,'createQuestionnairesError')},function(tx){callback(null,'createQuestionnairesSuccess')});
}

function createTableHoraires(callback)
{
	db.transaction(function(tx)
	{
		//tx.executeSql('DROP TABLE IF EXISTS "horaires"');
		tx.executeSql('CREATE TABLE IF NOT EXISTS "horaires" ("id" INTEGER PRIMARY KEY AUTOINCREMENT , "uidquestionnaire" VARCHAR, "tsdebut" INTEGER, "dureevalidite" INTEGER, "notification" INTEGER, "fait" INTEGER);');
	},function(tx){callback(true,'createHorairesError')},function(tx){callback(null,'createHorairesSuccess')});
}

function createTableReponses(callback)
{
	db.transaction(function(tx)
	{
		//tx.executeSql('DROP TABLE IF EXISTS "reponses"');
		tx.executeSql('CREATE TABLE IF NOT EXISTS "reponses" ("id" INTEGER PRIMARY KEY AUTOINCREMENT , "idhoraire" INTEGER DEFAULT (0), "sid" VARCHAR, "gid" VARCHAR, "qid" VARCHAR, "reponse" VARCHAR, "tsreponse" INTEGER, "envoi" BOOLEAN not null default 0);');
	},function(tx){callback(true,'createReponsesError')},function(tx){callback(null,'createReponsesSuccess')});
}

function createQuestionnairesSuccess(callback){

		    var req = new XMLHttpRequest();
		    req.open('GET', '../www/db/questionnaires.txt', true);

		    req.onreadystatechange = function (aEvt) {
		      if (req.readyState == 4) {
		         if(req.status == 200)
		        	 {console.log("200000!!!!");
		        	 if (debug)
		        	    	alert("200000!!!!");
		        	 res = req.responseText;
		        	 insertQuestionnaire(res,callback);
		        	 }
		         else
		        {
		        	 console.log("Erreur pendant le chargement de la page.\n");
		        	 if (debug)
		        	    	alert("Erreur pendant le chargement de la page.\n");
		        	 if(isMobile)
		        	{
		        		 //cas iphone
		        		 store = cordova.file.applicationDirectory;
		        		 fileName = "www/db/questionnaires.txt";
		        		 window.resolveLocalFileSystemURL(store + fileName, function(fileEntry){readQuestionnairesSuccess(fileEntry,callback) }, readQuestionnairesFail);

		        	}
		        }

		      }
		    };
		    req.send(null);
	//}

	console.log("dbquest");
	if (debug)
    	alert("dbquest");
	//callback();
};
function createQuestionnairesError(tx, error) {
    console.log("createQuestionnairesError: " + error.message);
    if (debug)
    	alert("createQuestionnairesError: " + error.message);
}
function readQuestionnairesSuccess(fileEntry,callback) {
	fileEntry.file(function(file) {
		var reader = new FileReader();
		reader.onloadend = function(e) {
			console.log(' reader');
			if (debug)
				alert(' reader');
			res = this.result;
			insertQuestionnaire(res,callback);
		}
		reader.readAsText(file);
	});
}
function readQuestionnairesFail(e) {
	console.log("FileSystem Error");
	if (debug)
		alert("FileSystem Error");
	console.dir(e);
	if (debug)
		alert(JSON.stringify(e));
}
function insertQuestionnaire(res,callback){
	db.transaction(function(tx) {
		var line = res.split("\n");
		for (var linekey in line)
		{
			var line2 = line[linekey].split("';'");
			(function (value) {
				tx.executeSql('SELECT COUNT("id") as cnt FROM "questionnaires" WHERE sid = "'+line2[0].substring(1,line2[0].length)+'";', [], function(tx, res) {
					if (res.rows.item(0).cnt < 1)
					{
						tx.executeSql('INSERT INTO "questionnaires" (sid, "sdescription-survey_config", gid,qid, question, qtype,"qhelp-question_config", answers) VALUES("'+
								value[0].substring(1,value[0].length)+'","'+
								value[1]+'","'+
								value[2]+'","'+
								value[3]+'","'+
								value[4]+'","'+
								value[5]+'","'+
								value[6]+'","'+
								encodeURI(value[7].substring(0,value[7].length-1))+'");',[], successHandler, errorHandler);
					}//fin if
				},errorHandler);//fin select
			})(line2);
		}
	},function(tx){callback(true,'err')},function(tx){callback(null,'ok')});
}

function getQuestionsByGroupe($scope,current,callback)
{
	if (debug)
		alert('getQuestionsByGroupe');
	db.transaction(function(tx) {
		tx.executeSql('SELECT * FROM "questionnaires" WHERE id = '+current+';', [], function(tx, res) {
			if (debug)
				alert('getQuestionsByGroupe1');
			console.log('question');
			//console.log(res);
			//if (res.rows.item(0).cnt < 1)
			if (res.rows.length < 1)
			{
				console.log('fin');
				$scope.quiz.actif = 'fin';
			}
			else

			{
				tx.executeSql('SELECT * FROM "questionnaires" WHERE gid = "'+res.rows.item(0)['gid']+'";', [], function(tx, res2) {
					if (debug)
						alert('getQuestionsByGroupe2');
					var groupes = {}
					var next = 0;
					$.each(res2.rows, function(key, groupe){
						groupe.config = getQuestionConfig(groupe['qhelp-question_config'])
						groupe.reponses = JSON.parse(decodeURI(groupe.answers));
						groupes[key] = groupe;
						next = parseInt(groupe.id) + 1;
					});
					$scope.quiz.groupes = groupes;
					$scope.quiz.next = next;
					$scope.quiz.actif = true;
					if (debug) alert(JSON.stringify($scope.quiz));

				}); //SELECT GROUPE
			}
		});//select
	},function(tx){callback(true,'err')},function(tx){callback(null,'ok')});//DB transaction
	//});//DB transaction

}

function displayQuestionTemplate($scope,current){
	console.log(current);
	if (debug)
		alert('displayQuestionTemplate');
	if (debug)
		alert(current);

	 async.series([ function(callback){ getQuestionsByGroupe($scope,current,callback);if (debug) alert("async");if (debug) alert(JSON.stringify($scope.quiz));}
	],

		function(err, results ){
		 	//$scope.quiz.actif = true;
		 if (debug)
				alert('getQuestionsByGroupeResult');
			console.log(results);
			if (debug) alert(JSON.stringify($scope.quiz));
			$scope.$apply(function(){return true;  if (debug) alert('$scope.$apply');});
			console.log($scope.quiz);
	}
	);//fin  async.series

}

function getSurveyConfig()
{
	var config = {};
	var strSurveyConfig = surveys_languagesettings[0].surveyls_description;
	//alert(surveys_languagesettings[0].surveyls_description);
	var line = strSurveyConfig.split("#");
	for (var linekey in line)
	{
		line2 = line[linekey].split(":");
		if (line2[0]!= "")
		{
			line20=line2[0];
			line21=line2[1];
			config[line20] = line21;
		}
	}
	return config;
}

function getQuestionConfig(qhelp)
{
	var config = {};
	//var strSurveyConfig = question.help;
	//alert(surveys_languagesettings[0].surveyls_description);
	var line = qhelp.split("#");
	for (var linekey in line)
	{
		line2 = line[linekey].split(":");
		if (line2[0]!= "")
		{
			line20=line2[0];
			line21=line2[1];
			config[line20] = line21;
		}
	}
	return config;
}
<commit_msg>add debug<commit_after>var async = require('../dist/js/async.js');

////////////////////
//DB

//DB common
function errorHandler(tx, error) {
    console.log("Error: " + error.message);
    if (debug)
    	alert("Error: " + error.message);
}
function successHandler(tx, result) {
    console.log("Success: " + result);
    if (debug)
    	alert("Success: " + result);
}

// DB init
function init_DB(callback)
{
	//init base
	if(isMobile)
    	db = window.sqlitePlugin.openDatabase("Database", "1.0", "Demo", -1);
    else
    	db = openDatabase("Database", "1.0", "Demo", -1);
	callback(null,'initDb');
}

function createTableQuestionnaires(callback)
{
	db.transaction(function(tx)
			{

				// id
				// sid : Survey ID
				// sdescription-survey_config : configuration (ex: #scheduling:D#duration:2400#startHour:10/18#maxOccurences:42#dayOff:0#test:1#)
				// gid : group ID?
				// qid : question ID
				// question
				// qtype -> template question
				// qhelp-question_config -> Configuration : template question complément, fréquence (ex: #tpl:sl7#frq:b#)
				// answers : jsontab? ex : radio buttons

				//tx.executeSql('DROP TABLE IF EXISTS "questionnaires"');
				tx.executeSql('CREATE TABLE IF NOT EXISTS "questionnaires" ' +
								' ("id" INTEGER PRIMARY KEY AUTOINCREMENT , ' +
								'  "sid" VARCHAR,' +
								'  "sdescription-survey_config" VARCHAR,' +
								'  "gid" VARCHAR,' +
								'  "qid" VARCHAR,' +
								'  "question" VARCHAR,' +
								'  "qtype" VARCHAR,' +
								'  "qhelp-question_config" VARCHAR,' +
								'  "answers" VARCHAR );');
								//'  "answers" VARCHAR );',[],callback(null,'createQuestionnairesSuccess'),callback(true,'createQuestionnairesError'));
								//'  "answers" VARCHAR );',[],createQuestionnairesSuccess,createQuestionnairesError);
			//});
			},function(tx){callback(true,'createQuestionnairesError')},function(tx){callback(null,'createQuestionnairesSuccess')});
}

function createTableHoraires(callback)
{
	db.transaction(function(tx)
	{
		//tx.executeSql('DROP TABLE IF EXISTS "horaires"');
		tx.executeSql('CREATE TABLE IF NOT EXISTS "horaires" ("id" INTEGER PRIMARY KEY AUTOINCREMENT , "uidquestionnaire" VARCHAR, "tsdebut" INTEGER, "dureevalidite" INTEGER, "notification" INTEGER, "fait" INTEGER);');
	},function(tx){callback(true,'createHorairesError')},function(tx){callback(null,'createHorairesSuccess')});
}

function createTableReponses(callback)
{
	db.transaction(function(tx)
	{
		//tx.executeSql('DROP TABLE IF EXISTS "reponses"');
		tx.executeSql('CREATE TABLE IF NOT EXISTS "reponses" ("id" INTEGER PRIMARY KEY AUTOINCREMENT , "idhoraire" INTEGER DEFAULT (0), "sid" VARCHAR, "gid" VARCHAR, "qid" VARCHAR, "reponse" VARCHAR, "tsreponse" INTEGER, "envoi" BOOLEAN not null default 0);');
	},function(tx){callback(true,'createReponsesError')},function(tx){callback(null,'createReponsesSuccess')});
}

function createQuestionnairesSuccess(callback){

		    var req = new XMLHttpRequest();
		    req.open('GET', '../www/db/questionnaires.txt', true);

		    req.onreadystatechange = function (aEvt) {
		      if (req.readyState == 4) {
		         if(req.status == 200)
		        	 {console.log("200000!!!!");
		        	 if (debug)
		        	    	alert("200000!!!!");
		        	 res = req.responseText;
		        	 insertQuestionnaire(res,callback);
		        	 }
		         else
		        {
		        	 console.log("Erreur pendant le chargement de la page.\n");
		        	 if (debug)
		        	    	alert("Erreur pendant le chargement de la page.\n");
		        	 if(isMobile)
		        	{
		        		 //cas iphone
		        		 store = cordova.file.applicationDirectory;
		        		 fileName = "www/db/questionnaires.txt";
		        		 window.resolveLocalFileSystemURL(store + fileName, function(fileEntry){readQuestionnairesSuccess(fileEntry,callback) }, readQuestionnairesFail);

		        	}
		        }

		      }
		    };
		    req.send(null);
	//}

	console.log("dbquest");
	if (debug)
    	alert("dbquest");
	//callback();
};
function createQuestionnairesError(tx, error) {
    console.log("createQuestionnairesError: " + error.message);
    if (debug)
    	alert("createQuestionnairesError: " + error.message);
}
function readQuestionnairesSuccess(fileEntry,callback) {
	fileEntry.file(function(file) {
		var reader = new FileReader();
		reader.onloadend = function(e) {
			console.log(' reader');
			if (debug)
				alert(' reader');
			res = this.result;
			insertQuestionnaire(res,callback);
		}
		reader.readAsText(file);
	});
}
function readQuestionnairesFail(e) {
	console.log("FileSystem Error");
	if (debug)
		alert("FileSystem Error");
	console.dir(e);
	if (debug)
		alert(JSON.stringify(e));
}
function insertQuestionnaire(res,callback){
	db.transaction(function(tx) {
		var line = res.split("\n");
		for (var linekey in line)
		{
			var line2 = line[linekey].split("';'");
			(function (value) {
				tx.executeSql('SELECT COUNT("id") as cnt FROM "questionnaires" WHERE sid = "'+line2[0].substring(1,line2[0].length)+'";', [], function(tx, res) {
					if (res.rows.item(0).cnt < 1)
					{
						tx.executeSql('INSERT INTO "questionnaires" (sid, "sdescription-survey_config", gid,qid, question, qtype,"qhelp-question_config", answers) VALUES("'+
								value[0].substring(1,value[0].length)+'","'+
								value[1]+'","'+
								value[2]+'","'+
								value[3]+'","'+
								value[4]+'","'+
								value[5]+'","'+
								value[6]+'","'+
								encodeURI(value[7].substring(0,value[7].length-1))+'");',[], successHandler, errorHandler);
					}//fin if
				},errorHandler);//fin select
			})(line2);
		}
	},function(tx){callback(true,'err')},function(tx){callback(null,'ok')});
}

function getQuestionsByGroupe($scope,current,callback)
{
	if (debug)
		alert('getQuestionsByGroupe');
	db.transaction(function(tx) {
		tx.executeSql('SELECT * FROM "questionnaires" WHERE id = '+current+';', [], function(tx, res) {
			if (debug)
				alert('getQuestionsByGroupe1');
			if (debug) alert('scope getQuestionsByGroupe1');
			if (debug) alert(JSON.stringify($scope.quiz));
			console.log('question');
			//console.log(res);
			//if (res.rows.item(0).cnt < 1)
			if (res.rows.length < 1)
			{
				console.log('fin');
				$scope.quiz.actif = 'fin';
			}
			else

			{
				tx.executeSql('SELECT * FROM "questionnaires" WHERE gid = "'+res.rows.item(0)['gid']+'";', [], function(tx, res2) {
					if (debug)
						alert('getQuestionsByGroupe2');
					var groupes = {}
					var next = 0;
					$.each(res2.rows, function(key, groupe){
						groupe.config = getQuestionConfig(groupe['qhelp-question_config'])
						groupe.reponses = JSON.parse(decodeURI(groupe.answers));
						groupes[key] = groupe;
						next = parseInt(groupe.id) + 1;
					});
					$scope.quiz.groupes = groupes;
					$scope.quiz.next = next;
					$scope.quiz.actif = true;
					if (debug) alert('scope getQuestionsByGroupe2');
					if (debug) alert(JSON.stringify($scope.quiz));

				}); //SELECT GROUPE
			}
		});//select
	},function(tx){callback(true,'err')},function(tx){callback(null,'ok')});//DB transaction
	//});//DB transaction

}

function displayQuestionTemplate($scope,current){
	console.log(current);
	if (debug)
		alert('displayQuestionTemplate');
	if (debug)
		alert(current);

	 async.series([ function(callback){ getQuestionsByGroupe($scope,current,callback);if (debug) alert("async");if (debug) alert(JSON.stringify($scope.quiz));}
	],

		function(err, results ){
		 	//$scope.quiz.actif = true;
		 if (debug)
				alert('getQuestionsByGroupeResult');
			console.log(results);
			if (debug) alert(JSON.stringify($scope.quiz));
			$scope.$apply(function(){return true;  if (debug) alert('$scope.$apply');});
			console.log($scope.quiz);
	}
	);//fin  async.series

}

function getSurveyConfig()
{
	var config = {};
	var strSurveyConfig = surveys_languagesettings[0].surveyls_description;
	//alert(surveys_languagesettings[0].surveyls_description);
	var line = strSurveyConfig.split("#");
	for (var linekey in line)
	{
		line2 = line[linekey].split(":");
		if (line2[0]!= "")
		{
			line20=line2[0];
			line21=line2[1];
			config[line20] = line21;
		}
	}
	return config;
}

function getQuestionConfig(qhelp)
{
	var config = {};
	//var strSurveyConfig = question.help;
	//alert(surveys_languagesettings[0].surveyls_description);
	var line = qhelp.split("#");
	for (var linekey in line)
	{
		line2 = line[linekey].split(":");
		if (line2[0]!= "")
		{
			line20=line2[0];
			line21=line2[1];
			config[line20] = line21;
		}
	}
	return config;
}
<|endoftext|>


<commit_before>({
    appDir: "../",
    baseUrl: "js",
    dir: "../../r-build",
    paths: {
        //jquery: "empty:"
    },
    locale: "sv",
    optimize: "uglify",
    optimizeCss: "standard",
    inlineText: true,
    //Allows namespacing requirejs, require and define calls to a new name.
    //This allows stronger assurances of getting a module space that will
    //not interfere with others using a define/require AMD-based module
    //system. The example below will rename define() calls to foo.define().
    //See http://requirejs.org/docs/faq-advanced.html#rename for a more
    //complete example.
    //namespace: 'foo',
    modules: [
        {
            name: "main",
            include: ["Highcharts", "HighchartsTheme"]
            //exclude: ["jquery"]
        }
    ],
    mainConfigFile: './main.js'
})<commit_msg>updated build configuration<commit_after>({
    appDir: "../",
    baseUrl: "js",
    dir: "../../war",
    paths: {
        //jquery: "empty:"
    },
    locale: "sv",
    optimize: "uglify",
    optimizeCss: "standard",
    inlineText: true,
    //Allows namespacing requirejs, require and define calls to a new name.
    //This allows stronger assurances of getting a module space that will
    //not interfere with others using a define/require AMD-based module
    //system. The example below will rename define() calls to foo.define().
    //See http://requirejs.org/docs/faq-advanced.html#rename for a more
    //complete example.
    //namespace: 'foo',
    modules: [
        {
            name: "main",
            include: ["Highcharts", "HighchartsTheme"]
            //exclude: ["jquery"]
        }
    ],
    mainConfigFile: './main.js'
})<|endoftext|>


<commit_before>import React from 'react';
import styles from './css/index.scss';
import RecoDisplay from './components/recoDisplay.js';
import First from './components/first.js';
import Result from './components/result.js';

export default class App extends React.Component {

  displayName: 'App';
  props: any;
  constructor(props){
    super(props);
    this.state = { };
  }

  //display is just there for test
  render () {
    return (
      <div className = {styles.main}>
        <RecoDisplay />
      </div>
    );
  }
}
<commit_msg>fixed that reloading bug<commit_after>import React from 'react';
import styles from './css/index.scss';
import RecoDisplay from './components/recoDisplay.js';
import First from './components/first.js';
import Result from './components/result.js';
import getMuiTheme from 'material-ui/styles/getMuiTheme';

export default class App extends React.Component {

  displayName: 'App';
  props: any;

  constructor(props){
    super(props);
    this.state = { };
  }

  getChildContext() {
    return {muiTheme: getMuiTheme()};
  };

  //display is just there for test
  render () {
    return (
      <div /**className = {styles.main}**/>
        <Result />
      </div>
    );
  }
}

App.childContextTypes = {
    muiTheme: React.PropTypes.object.isRequired,
};<|endoftext|>


<commit_before>function getAbstract(html) { //get a text string representative of the document
	var removed = $("" + html + "").remove("div").remove("iframe").remove("script"); //strip out the interactive stuff - we just want a text string
	removed = removed[0].textContent;
	var abstract = removed.substring(0, 175); //the length of the abstract to return
	if (abstract) {
		return abstract;
	} else {
		return "";
	}
}

var document_id = window.location.hash.replace("#", "");
var baseWindowTitle = document.title;

var client = new Dropbox.Client({
	key: "DROPBOX_APP_KEY"
});

// Try to finish OAuth authorization.
client.authenticate({
	interactive: false
}, function (error) {
	if (error) {
		createError({
			error: 'Authentication error: ' + error,
			action: "please log in to Dropbox and try again"
		});
	}
});

if (client.isAuthenticated()) {

	var datastoreManager = client.getDatastoreManager();
	datastoreManager.openDefaultDatastore(function (error, datastore) {
		if (error) {
			createError({
				error: "Error opening datastore: " + error,
				action: "Please try again in a few minutes."
			});
		}

		var documentTable = datastore.getTable('documents');

		documentTable.setResolutionRule('content', 'sum');

		if (!document_id) {
			var currentDocument = documentTable.insert({
				title: "Untitled Document",
				content: "",
				abstract: " ",
				created: new Date(),
				modified: new Date()
			});

			window.location.hash = currentDocument.getId(); //if someone reloads the page, the hash should not still be "new"

		} else {
			try {
				var currentDocument = documentTable.get(document_id);
			} catch (e) {
				createError({
					error: "Document does not exist.",
					action: "This document does not exist, or you do not have permission to view it."
				});
			}
		}

		if (!currentDocument) { //the document doesn't exist
			createError({
				error: "Document does not exist.",
				action: "This document does not exist, or you do not have permission to view it."
			});
		}
		var savedContent = currentDocument.get("content");
		var savedTitle = currentDocument.get("title");

		document.title = savedTitle + " | " + baseWindowTitle;

		$(".doc-name").val(currentDocument.get("title"));

		$("#document-editor").html(currentDocument.get("content"));

		function saveDocument() {
			if ($("#document-editor").html() != savedContent || $(".doc-name").val() != savedTitle) {

				if ($(".doc-name").val() != "") {
					var docTitle = $(".doc-name").val();
				} else {
					var docTitle = "Untitled Document";
				}
				console.log("syncing to dropbox");

				savedContent = $("#document-editor").html(); //in order for recordsChanged to work correctly, these need to update before the actual records
				savedTitle = $(".doc-name").val();
				document.title = savedTitle + " | " + baseWindowTitle; //update the title to reflect the most recent document title

				if (savedContent.length > 99000) {
					$(document.body).prepend('
This document is too long. Changes you make to it may not be saved.
');
				} else {
					$(".floating-message.document-too-long").remove();
				}
				currentDocument.set('title', docTitle);
				currentDocument.set("content", $("#document-editor").html());
				currentDocument.set("modified", new Date());
				currentDocument.set("abstract", getAbstract($("#document-editor").html()));
				return true;
			} else { //end if savedcontent
				return null;
			}
		}

		setInterval(saveDocument, 4000);
		window.onbeforeunload = function () {
			if (saveDocument()) {
				return "Your changes have not been saved yet. Are you sure you want to leave?"
			}
		}

		datastore.recordsChanged.addListener(function (event) {
			setTimeout(function () { //there's a lag in how fast the api updates - adjust for that
				if (currentDocument.get("content") != savedContent || currentDocument.get("title") != savedTitle) { //make sure this was a remote change
					$(".doc-name").val(currentDocument.get("title"));
					$("#document-editor").html(currentDocument.get("content"));
					savedContent = $("#document-editor").html();
					savedTitle = $(".doc-name").val();
				}
			}, 1750); //end settimeout
		});
	});

} else {
	window.location = "https://standaert.net/scratchpad";
}<commit_msg>add missing code<commit_after>function getAbstract(html) { //get a text string representative of the document
	var removed = $("" + html + "").remove("div").remove("iframe").remove("script"); //strip out the interactive stuff - we just want a text string
	removed = removed[0].textContent;
	var abstract = removed.substring(0, 175); //the length of the abstract to return
	if (abstract) {
		return abstract;
	} else {
		return "";
	}
}

function getPosterImage(html) {
	var content = $("" + html + "");
	var images = content.find("img");
	var posterImage = $(images[0]).attr("src");
	return posterImage;
};

var document_id = window.location.hash.replace("#", "");
var baseWindowTitle = document.title;

var client = new Dropbox.Client({
	key: "DROPBOX_APP_KEY"
});

// Try to finish OAuth authorization.
client.authenticate({
	interactive: false
}, function (error) {
	if (error) {
		createError({
			error: 'Authentication error: ' + error,
			action: "please log in to Dropbox and try again"
		});
	}
});

if (client.isAuthenticated()) {

	var datastoreManager = client.getDatastoreManager();
	datastoreManager.openDefaultDatastore(function (error, datastore) {
		if (error) {
			createError({
				error: "Error opening datastore: " + error,
				action: "Please try again in a few minutes."
			});
		}

		var documentTable = datastore.getTable('documents');

		documentTable.setResolutionRule('content', 'sum');

		if (!document_id) {
			var currentDocument = documentTable.insert({
				title: "Untitled Document",
				content: "",
				abstract: " ",
				posterImage: "default",
				created: new Date(),
				modified: new Date(),
			});

			window.location.hash = currentDocument.getId(); //if someone reloads the page, the hash should not still be "new"

		} else {
			try {
				var currentDocument = documentTable.get(document_id);
			} catch (e) {
				createError({
					error: "Document does not exist.",
					action: "This document does not exist, or you do not have permission to view it."
				});
			}
		}

		if (!currentDocument) { //the document doesn't exist
			createError({
				error: "Document does not exist.",
				action: "This document does not exist, or you do not have permission to view it."
			});
		}
		var savedContent = currentDocument.get("content");
		var savedTitle = currentDocument.get("title");

		document.title = savedTitle + " | " + baseWindowTitle;

		$(".doc-name").val(currentDocument.get("title"));

		$("#document-editor").html(currentDocument.get("content"));

		function saveDocument() {
			if ($("#document-editor").html() != savedContent || $(".doc-name").val() != savedTitle) {

				if ($(".doc-name").val() != "") {
					var docTitle = $(".doc-name").val();
				} else {
					var docTitle = "Untitled Document";
				}
				console.log("syncing to dropbox");

				savedContent = $("#document-editor").html(); //in order for recordsChanged to work correctly, these need to update before the actual records
				savedTitle = $(".doc-name").val();
				document.title = savedTitle + " | " + baseWindowTitle; //update the title to reflect the most recent document title

				if (savedContent.length > 99000) {
					$(document.body).prepend('
This document is too long. Changes you make to it may not be saved.
');
				} else {
					$(".floating-message.document-too-long").remove();
				}
				currentDocument.set('title', docTitle);
				currentDocument.set("content", $("#document-editor").html());
				currentDocument.set("modified", new Date());
				currentDocument.set("abstract", getAbstract($("#document-editor").html()));
				currentDocument.set("posterImage", getPosterImage($("#document-editor").html()));
				return true;
			} else { //end if savedcontent
				return null;
			}
		}

		setInterval(saveDocument, 4000);
		window.onbeforeunload = function () {
			if (saveDocument()) {
				return "Your changes have not been saved yet. Are you sure you want to leave?"
			}
		}

		datastore.recordsChanged.addListener(function (event) {
			setTimeout(function () { //there's a lag in how fast the api updates - adjust for that
				if (currentDocument.get("content") != savedContent || currentDocument.get("title") != savedTitle) { //make sure this was a remote change
					$(".doc-name").val(currentDocument.get("title"));
					$("#document-editor").html(currentDocument.get("content"));
					savedContent = $("#document-editor").html();
					savedTitle = $(".doc-name").val();
				}
			}, 1750); //end settimeout
		});
	});

} else {
	window.location = "https://standaert.net/scratchpad";
}<|endoftext|>


<commit_before>var Pontoon = function() {

  /* public  */
  return {

    /*
     * Send data to server
     * Pontoon server push expects a POST with the following properties:
     *
     * id - list of msgid strings, the length of id should match the length of value ['Hello World']
     * value - list of msgstrs, should be empty if no changes, otherwise set to the edited value ['Hallo Welt']
     * project - url of the page being localized
     * locale - locale msgstrs are localized too
    */
    send: function() {
      var project = ('project' in this.client._meta) ? this.client._meta['project'] : this.client._doc.location.href,
          lang = $(this.client._ptn).find('input').val(),
          data = {
            'id': [],
            'value': [],
            'project': project,
            'locale': lang
          },
          entities = [],
          url = ('url' in this.client._meta) ? this.client._meta['url'] : 'http://127.0.0.1:8000/push/';

      $(this.client._entities).each(function() {
        var entity = this,
            trans = entity.translation ? entity.translation : entity.original;
        entities.push({
          'id': entity.original,
          'value': trans
        });
      });

      $(entities).each(function() {
        data['id'].push(this.original);
        if (this.original === this.value) {
          data['value'].push("");
        } else {
          data['value'].push(this.value);
        }
      });

      $.ajaxSettings.traditional = true;
      $.post(url, data, null, "text");
    },

    /*
     * Set language using browser language detection
     *
     * Browser language cannot be generally obtained via navigator.language
     * Using HTTP 'Accept-Language' header via external service temporary
     * Source: http://stackoverflow.com/questions/1043339/javascript-for-detecting-browser-language-preference
     *
     * TODO: explore Jetpack options and develop internal solution
    */
    setLanguage: function() {
      $.ajax({
        url: "http://ajaxhttpheaders.appspot.com",
        dataType: 'jsonp',
        success: function(headers) {
          var language = headers['Accept-Language'].substring(0, 2),
              entry = $('#locale-list .flag.' + language);
          if (entry.length !== 0) {
            $('#flag').addClass(language);
            $('#locale .language').html(entry.next().text());
          }
        }
      }).done(function() {
        $('#pontoon').slideDown();
      });
    },

    /**
     * Build source - translation pairs
     */
    rebuildList: function() {
      var self = this,
          list = $(this.client._ptn).find('#entitylist').empty()
          // tables still need 'cellspacing="0"' in the markup
          // http://meyerweb.com/eric/thoughts/2007/05/01/reset-reloaded/
          .append(
            '
' +
              '

Source	Translation

' +
              '

' +
            '
');

      // Render
      $(this.client._entities).each(function() {
        var tr = $('
' +
        '' +
          '
' + this.original + '
' +
          '
' +
            '

' +
            '

' +
            (this.comment ? '

' : '') +
          '
' +
        '	' +
        '' +
          '
' +
            'Translation' +
            'Translation memory' +
            'Other users' +
            'Other locales' +
          '
' +
          '<textarea>' + (this.translation || '') + '</textarea>' +
        '
', self.client._ptn);

        tr.get(0).entity = this;
        this.node.get(0).entity = this;
        this.ui = tr;

        list.find('tbody').append(tr);
      });

      // Main entity list handlers
      $("#pontoon tr").hover(function() {
        this.entity.hover();
      }, function() {
        this.entity.unhover();
      }).click(function() {
        $(self.client._doc).find('.editableToolbar > .edit').click();
      });

      // Copy original string to translation
      $("#pontoon .copy").click(function(e) {
      	e.stopPropagation();
        var toolbar = $(self.client._doc).find('.editableToolbar');
        toolbar.find('.edit').click().end();

      	var entity = $(this).parents('tr').get(0).entity;
      	$(entity.node).html(entity.original);
        toolbar.find('.save').click();
      });

      this.updateProgress();
    },

    /**
     * Update progress indicator and value
     */
    updateProgress: function() {
      var all = $("#pontoon tbody tr").length,
          translated = $("#pontoon tbody tr.translated").length;
      $('#progress span').width(Math.round(translated*100 / all) + '%');
      $('#progress-value').html(translated + '/' + all);
    },

    /**
     * Attach event handlers
     */
    attachHandlers: function() {
      var self = this;

      // Update entities and progress when saved
      $(".editableToolbar > .save", this.client._doc).click(function() {
        var element = $(this).parent().get(0).target;
        self.updateEntity(element);
        self.updateProgress();
      });

      // Update progress when cancelled
      $(".editableToolbar > .cancel", this.client._doc).click(function() {
        self.updateProgress();
      });

      // Open/close Pontoon UI
      $('#switch').unbind("click.pontoon").bind("click.pontoon", function() {
        if ($('#pontoon').is('.opened')) {
          $('#entitylist').height(0);
        } else {
          $('#entitylist').height(300);
        }
        $('#source').height($(document).height() - $('#pontoon').height());
        $('#pontoon').toggleClass('opened');
      });

      // Locale selector
      $('#locale').unbind("click.pontoon").bind("click.pontoon", function() {
        $('#locale-list').css("left", $("#flag").position().left - 12).toggle();
        $(this).toggleClass('opened');
      });
      $('#locale-list li:not(".add")').unbind("click.pontoon").bind("click.pontoon", function() {
        $('#flag').attr("class", $(this).find('span').attr("class"));
        $('#locale .language').html($(this).find('.language').html());
        $('#locale').click();
      });

      // Send changes to server
      $("#send").click(function () {
        self.send();
      });
    },

    /**
     * Show and render main UI
     * Enable editable text
     */
    renderTools: function() {
      $(this.client._entities).each(function() {
        this.node.editableText();
      });
      this.attachHandlers();
      this.rebuildList();
    },

    /**
     * Update entity and main UI
     *
     * element HTML Element which contains l10n entities
     */
    updateEntity: function(element) {
      var entity = element.entity,
          clone = $(element).clone();

      entity.translation = $(clone).html();
      entity.ui.find('textarea').text(entity.translation).parents('tr').addClass('translated');
    },

    /**
     * Create entity object
     */
    createEntity: function(e) {
      var entity = {
        original: e.original || null, /* Original string (may include HTML markup) */
        translation: e.translation || null, /* Translated string (may include HTML markup) */
        comment: e.comment || null, /* String comment */
        node: e.node || null, /* HTML Element holding string */
        ui: e.ui || null, /* HTML Element representing string in the main UI */
        _client: this,

        hover: function() {
          this.node.get(0).showToolbar();
          this.ui.toggleClass('hovered');
        },
        unhover: function() {
          this.node.get(0).hideToolbar();
          this.ui.toggleClass('hovered');
        }
      }

      this.client._entities.push(entity);
    },

    /**
     * Extract entities from the document, not prepared for working with Pontoon
     *
     * Create entity object from every non-empty text node
     * Exclude nodes from special tags, e.g.


<commit_before>var onPageLoad = require('../../shared/pageload');

$(function(){
    var profile;

    onPageLoad('user_profile');

    api.loginCheck(function(data) {
        if(data.res) {
            // Only works currently if user logged in, will work later
            profile = $(JST['User_Profile/User_Cover/user_profile']({
                username: data.user.name,
                userinfo: 'I like penguins', //Get stuff from server
                profile_picture: '/img/shutter.png',
                cover_photo: '/img/leopard.jpg'
            }));
            var profileWrap = $('.profile_wrapper');
            profileWrap.append(profile);
            console.log(data.user.name);
        }
    });
    // TAB PROFILE
    // Sends empty data to profile_tab.html, allows easy splitting of files
    var tabP = $(JST['User_Profile/User_Tabs/profile_tab']());
    var profTabWrap = $('.profile_tab');
    profTabWrap.append(tabP);
});
<commit_msg>Updated user profile iamge and cover photo<commit_after>var onPageLoad = require('../../shared/pageload');

$(function(){
    var profile;

    onPageLoad('user_profile');

    api.loginCheck(function(data) {
        if(data.res) {
            // Only works currently if user logged in, will work later
            profile = $(JST['User_Profile/User_Cover/user_profile']({
                username: data.user.name,
                userinfo: 'I like penguins', //Get stuff from server
                profile_picture: 'http://appnovaweb.files.wordpress.com/2013/07/myspacetom.jpg',
                cover_photo: '/img/elephant.jpg'
            }));
            var profileWrap = $('.profile_wrapper');
            profileWrap.append(profile);
            console.log(data.user.name);
        }
    });
    // TAB PROFILE
    // Sends empty data to profile_tab.html, allows easy splitting of files
    var tabP = $(JST['User_Profile/User_Tabs/profile_tab']());
    var profTabWrap = $('.profile_tab');
    profTabWrap.append(tabP);
});
<|endoftext|>


<commit_before>export default function(app) {
  var state = {}
  var view = app.view
  var actions = {}
  var events = {}
  var node
  var element

  for (var i = -1, plugins = app.plugins || []; i < plugins.length; i++) {
    var plugin = plugins[i] ? plugins[i](app) : app

    if (plugin.state != null) {
      state = merge(state, plugin.state)
    }

    init(actions, plugin.actions)

    Object.keys(plugin.events || []).map(function(key) {
      events[key] = (events[key] || []).concat(plugin.events[key])
    })
  }

  if (document.readyState[0] !== "l") {
    load()
  } else {
    addEventListener("DOMContentLoaded", load)
  }

  function init(namespace, children, lastName) {
    Object.keys(children || []).map(function(key) {
      var action = children[key]
      var name = lastName ? lastName + "." + key : key

      if (typeof action === "function") {
        namespace[key] = function(data) {
          var result = action(
            state,
            actions,
            emit("action", {
              name: name,
              data: data
            }).data,
            emit
          )

          if (result == null || typeof result.then === "function") {
            return result
          }

          render((state = merge(state, emit("update", result))), view)
        }
      } else {
        init(namespace[key] || (namespace[key] = {}), action, name)
      }
    })
  }

  function load() {
    render(state, view)
    emit("loaded")
  }

  function emit(name, data) {
    ;(events[name] || []).map(function(cb) {
      var result = cb(state, actions, data, emit)
      if (result != null) {
        data = result
      }
    })

    return data
  }

  function render(state, view) {
    element = patch(
      app.root || (app.root = document.body),
      element,
      node,
      (node = emit("render", view)(state, actions))
    )
  }

  function merge(a, b) {
    var obj = {}

    if (typeof b !== "object" || Array.isArray(b)) {
      return b
    }

    for (var i in a) {
      obj[i] = a[i]
    }
    for (var i in b) {
      obj[i] = b[i]
    }

    return obj
  }

  function createElementFrom(node, isSVG) {
    if (typeof node === "string") {
      var element = document.createTextNode(node)
    } else {
      var element = (isSVG = isSVG || node.tag === "svg")
        ? document.createElementNS("http://www.w3.org/2000/svg", node.tag)
        : document.createElement(node.tag)

      for (var i = 0; i < node.children.length; ) {
        element.appendChild(createElementFrom(node.children[i++], isSVG))
      }

      for (var i in node.data) {
        if (i === "oncreate") {
          node.data[i](element)
        } else {
          setElementData(element, i, node.data[i])
        }
      }
    }

    return element
  }

  function setElementData(element, name, value, oldValue) {
    if (name === "key") {
    } else if (name === "style") {
      for (var i in merge(oldValue, (value = value || {}))) {
        element.style[i] = value[i] || ""
      }
    } else {
      try {
        element[name] = value
      } catch (_) {}

      if (typeof value !== "function") {
        if (value) {
          element.setAttribute(name, value)
        } else {
          element.removeAttribute(name)
        }
      }
    }
  }

  function updateElementData(element, oldData, data) {
    for (var name in merge(oldData, data)) {
      var value = data[name]
      var oldValue = name === "value" || name === "checked"
        ? element[name]
        : oldData[name]

      if (name === "onupdate") {
        value(element)
      } else if (value !== oldValue) {
        setElementData(element, name, value, oldValue)
      }
    }
  }

  function getKeyFrom(node) {
    if (node && (node = node.data)) {
      return node.key
    }
  }

  function removeElement(parent, element, node) {
    ;((node.data && node.data.onremove) || removeChild)(element, removeChild)
    function removeChild() {
      parent.removeChild(element)
    }
  }

  function patch(parent, element, oldNode, node) {
    if (oldNode == null) {
      element = parent.insertBefore(createElementFrom(node), element)
    } else if (node.tag && node.tag === oldNode.tag) {
      updateElementData(element, oldNode.data, node.data)

      var len = node.children.length
      var oldLen = oldNode.children.length
      var reusableChildren = {}
      var oldElements = []
      var newKeys = {}

      for (var i = 0; i < oldLen; i++) {
        var oldElement = element.childNodes[i]
        oldElements[i] = oldElement

        var oldChild = oldNode.children[i]
        var oldKey = getKeyFrom(oldChild)

        if (null != oldKey) {
          reusableChildren[oldKey] = [oldElement, oldChild]
        }
      }

      var i = 0
      var j = 0

      while (j < len) {
        var oldElement = oldElements[i]
        var oldChild = oldNode.children[i]
        var newChild = node.children[j]

        var oldKey = getKeyFrom(oldChild)
        if (newKeys[oldKey]) {
          i++
          continue
        }

        var newKey = getKeyFrom(newChild)

        var reusableChild = reusableChildren[newKey] || []

        if (null == newKey) {
          if (null == oldKey) {
            patch(element, oldElement, oldChild, newChild)
            j++
          }
          i++
        } else {
          if (oldKey === newKey) {
            patch(element, reusableChild[0], reusableChild[1], newChild)
            i++
          } else if (reusableChild[0]) {
            element.insertBefore(reusableChild[0], oldElement)
            patch(element, reusableChild[0], reusableChild[1], newChild)
          } else {
            patch(element, oldElement, null, newChild)
          }

          j++
          newKeys[newKey] = newChild
        }
      }

      while (i < oldLen) {
        var oldChild = oldNode.children[i]
        var oldKey = getKeyFrom(oldChild)
        if (null == oldKey) {
          removeElement(element, oldElements[i], oldChild)
        }
        i++
      }

      for (var i in reusableChildren) {
        var reusableChild = reusableChildren[i]
        var reusableNode = reusableChild[1]
        if (!newKeys[reusableNode.data.key]) {
          removeElement(element, reusableChild[0], reusableNode)
        }
      }
    } else if (node !== oldNode) {
      var i = element
      parent.replaceChild((element = createElementFrom(node)), i)
    }

    return element
  }
}
<commit_msg>Don't crash if onupdate is not defined. Fix #215.<commit_after>export default function(app) {
  var state = {}
  var view = app.view
  var actions = {}
  var events = {}
  var node
  var element

  for (var i = -1, plugins = app.plugins || []; i < plugins.length; i++) {
    var plugin = plugins[i] ? plugins[i](app) : app

    if (plugin.state != null) {
      state = merge(state, plugin.state)
    }

    init(actions, plugin.actions)

    Object.keys(plugin.events || []).map(function(key) {
      events[key] = (events[key] || []).concat(plugin.events[key])
    })
  }

  if (document.readyState[0] !== "l") {
    load()
  } else {
    addEventListener("DOMContentLoaded", load)
  }

  function init(namespace, children, lastName) {
    Object.keys(children || []).map(function(key) {
      var action = children[key]
      var name = lastName ? lastName + "." + key : key

      if (typeof action === "function") {
        namespace[key] = function(data) {
          var result = action(
            state,
            actions,
            emit("action", {
              name: name,
              data: data
            }).data,
            emit
          )

          if (result == null || typeof result.then === "function") {
            return result
          }

          render((state = merge(state, emit("update", result))), view)
        }
      } else {
        init(namespace[key] || (namespace[key] = {}), action, name)
      }
    })
  }

  function load() {
    render(state, view)
    emit("loaded")
  }

  function emit(name, data) {
    ;(events[name] || []).map(function(cb) {
      var result = cb(state, actions, data, emit)
      if (result != null) {
        data = result
      }
    })

    return data
  }

  function render(state, view) {
    element = patch(
      app.root || (app.root = document.body),
      element,
      node,
      (node = emit("render", view)(state, actions))
    )
  }

  function merge(a, b) {
    var obj = {}

    if (typeof b !== "object" || Array.isArray(b)) {
      return b
    }

    for (var i in a) {
      obj[i] = a[i]
    }
    for (var i in b) {
      obj[i] = b[i]
    }

    return obj
  }

  function createElementFrom(node, isSVG) {
    if (typeof node === "string") {
      var element = document.createTextNode(node)
    } else {
      var element = (isSVG = isSVG || node.tag === "svg")
        ? document.createElementNS("http://www.w3.org/2000/svg", node.tag)
        : document.createElement(node.tag)

      for (var i = 0; i < node.children.length; ) {
        element.appendChild(createElementFrom(node.children[i++], isSVG))
      }

      for (var i in node.data) {
        if (i === "oncreate") {
          node.data[i](element)
        } else {
          setElementData(element, i, node.data[i])
        }
      }
    }

    return element
  }

  function setElementData(element, name, value, oldValue) {
    if (name === "key") {
    } else if (name === "style") {
      for (var i in merge(oldValue, (value = value || {}))) {
        element.style[i] = value[i] || ""
      }
    } else {
      try {
        element[name] = value
      } catch (_) {}

      if (typeof value !== "function") {
        if (value) {
          element.setAttribute(name, value)
        } else {
          element.removeAttribute(name)
        }
      }
    }
  }

  function updateElementData(element, oldData, data) {
    for (var name in merge(oldData, data)) {
      var value = data[name]
      var oldValue = name === "value" || name === "checked"
        ? element[name]
        : oldData[name]

      if (name === "onupdate" && value) {
        value(element)
      } else if (value !== oldValue) {
        setElementData(element, name, value, oldValue)
      }
    }
  }

  function getKeyFrom(node) {
    if (node && (node = node.data)) {
      return node.key
    }
  }

  function removeElement(parent, element, node) {
    ;((node.data && node.data.onremove) || removeChild)(element, removeChild)
    function removeChild() {
      parent.removeChild(element)
    }
  }

  function patch(parent, element, oldNode, node) {
    if (oldNode == null) {
      element = parent.insertBefore(createElementFrom(node), element)
    } else if (node.tag && node.tag === oldNode.tag) {
      updateElementData(element, oldNode.data, node.data)

      var len = node.children.length
      var oldLen = oldNode.children.length
      var reusableChildren = {}
      var oldElements = []
      var newKeys = {}

      for (var i = 0; i < oldLen; i++) {
        var oldElement = element.childNodes[i]
        oldElements[i] = oldElement

        var oldChild = oldNode.children[i]
        var oldKey = getKeyFrom(oldChild)

        if (null != oldKey) {
          reusableChildren[oldKey] = [oldElement, oldChild]
        }
      }

      var i = 0
      var j = 0

      while (j < len) {
        var oldElement = oldElements[i]
        var oldChild = oldNode.children[i]
        var newChild = node.children[j]

        var oldKey = getKeyFrom(oldChild)
        if (newKeys[oldKey]) {
          i++
          continue
        }

        var newKey = getKeyFrom(newChild)

        var reusableChild = reusableChildren[newKey] || []

        if (null == newKey) {
          if (null == oldKey) {
            patch(element, oldElement, oldChild, newChild)
            j++
          }
          i++
        } else {
          if (oldKey === newKey) {
            patch(element, reusableChild[0], reusableChild[1], newChild)
            i++
          } else if (reusableChild[0]) {
            element.insertBefore(reusableChild[0], oldElement)
            patch(element, reusableChild[0], reusableChild[1], newChild)
          } else {
            patch(element, oldElement, null, newChild)
          }

          j++
          newKeys[newKey] = newChild
        }
      }

      while (i < oldLen) {
        var oldChild = oldNode.children[i]
        var oldKey = getKeyFrom(oldChild)
        if (null == oldKey) {
          removeElement(element, oldElements[i], oldChild)
        }
        i++
      }

      for (var i in reusableChildren) {
        var reusableChild = reusableChildren[i]
        var reusableNode = reusableChild[1]
        if (!newKeys[reusableNode.data.key]) {
          removeElement(element, reusableChild[0], reusableNode)
        }
      }
    } else if (node !== oldNode) {
      var i = element
      parent.replaceChild((element = createElementFrom(node)), i)
    }

    return element
  }
}
<|endoftext|>


<commit_before>var config = require('config');
var mapModule = require('map');
var plugins = require('./leaflet_plugins');
var polyUtil = require('./polyline_encoded.js');
var routeboxer = require('./leaflet_routeboxer.js');
var leaflet_label = require('./leaflet_label/leaflet.label-src.js');
var session = require('session');

var center = config.geocode().center.split(',').map(parseFloat)
if (config.map_provider && config.map_provider() !== 'AmigoCloud') {
  L.mapbox.accessToken = config.mapbox_access_token();
}

module.exports = function(el) {
  var map, realtime, southWest, northEast, blurLayer;

  if (config.map_provider && config.map_provider() === 'AmigoCloud') {
    southWest = L.latLng(35.946877085397,-123.480610897013);
    northEast = L.latLng(40.763279543715,-118.789317362500);
    map = (new L.amigo.map(el, {
      amigoLogo: 'right',
      loadAmigoLayers: false,
      inertia: false,
      zoomAnimation: $('.hide-map').css('display') !== 'none',
      maxBounds: L.latLngBounds(southWest, northEast),
      minZoom: 8
    })).setView([center[1], center[0]], config.geocode().zoom);

    L.amigo.auth.setToken(config.support_data_token());

    blurLayer = L.tileLayer(
    'https://www.amigocloud.com/api/v1/users/'+
	'23/projects/3019/datasets/23835/tiles/{z}/{x}/{y}.png?' +
	'token=' + config.support_data_token(),
      {
        name: 'Uncovered Area'
      }
    );

    map.addAuthLayer({
      id: config.mapbox_map_id(),
      accessToken: config.mapbox_access_token(),
      name: 'Gray',
      provider: 'mapbox'
    });
    map.addBaseLayer(L.amigo.AmigoGray);
    map.layersControl.addBaseLayer(
      L.bingLayer(
        config.bing_key(),
	{
	  type: 'Road',
	  attribution: 'Bing Maps'
	}
      ),
      'Bing Road'
    );
    map.layersControl.addOverlay(blurLayer);
    blurLayer.addTo(map);

    module.exports.activeMap = map;

    map.realtimeControl = L.control.toggleRealTime().addTo(map);

    realtime = mapModule.realtime();

  } else {

    map = L.mapbox.map(el, config.mapbox_map_id(), {
      attributionControl: false,
      inertia: false,
      zoomAnimation: false
    }).setView([center[1], center[0]], config.geocode().zoom);
  }

  return map;
};

module.exports.getMap = function () {
  return this.activeMap;
};

module.exports.cleanRoute = function() {
    module.exports.activeRoute.removeLayer();
    module.exports.activeRoute = null;
};

module.exports.polyline_creadas = [];
module.exports.marker_creadas = [];
module.exports.makerpoint_creadas = [];

module.exports.getpolyline_creadas = function () {
  return this.polyline_creadas;
};

module.exports.getMarker_creadas = function () {
  return this.marker_creadas;
};

module.exports.cleanPolyline = function() {
    var polyline_creadas = this.getpolyline_creadas();
    var map = this.activeMap;
    for (i in polyline_creadas) {
        try {
                map.removeLayer(polyline_creadas[i]);

            } catch (e) {
                console.log("problema al eliminar " + e);
            }

  }
  this.polyline_creadas = [];

};

module.exports.cleanMarker = function() {
    var map = this.activeMap;
    for (i in this.marker_creadas) {
        try {
                map.removeLayer(this.marker_creadas[i]);

            } catch (e) {
                console.log("problema al eliminar " + e);
            }
    }

  this.marker_creadas = [];

};

module.exports.cleanMarkerpoint = function() {
    var map = this.activeMap;
    for (i in this.makerpoint_creadas) {
        try {
                map.removeLayer(this.makerpoint_creadas[i]);

            } catch (e) {
                console.log("problema al eliminar " + e);
            }
    }

  this.makerpoint_creadas = [];

};

module.exports.marker_map = function(from, to){
     var IconStart = L.icon({
        iconUrl: 'assets/images/graphics/start.svg',
        iconSize: [40, 55],
        iconAnchor: [20, 50],
        popupAnchor:  [0, -50]
    });
    var IconEnd = L.icon({
        iconUrl: 'assets/images/graphics/end.svg',
        iconSize: [40, 55],
        iconAnchor: [20, 50],
        popupAnchor:  [0, -50]
    });

    var markerform = new L.marker([from[0],from[1]], {icon: IconStart, draggable: true})
        .addTo(this.activeMap);
    var markerto = new L.marker([to[0],to[1]], {icon: IconEnd, draggable: true})
        .addTo(this.activeMap);
    var _this = this;

    markerform.on('dragend', function(e){
       var marker = e.target;
       var result = marker.getLatLng();
       _this.cleanPolyline();
       _this.cleanMarkerpoint();
       var plan = session.plan();

            plan.setAddress('from', result.lng + ',' + result.lat, function(err, rees) {
                plan.updateRoutes();
          });
    });

    markerto.on('dragend', function(e){
       var marker = e.target;
       var result = marker.getLatLng();
       _this.cleanPolyline();
       _this.cleanMarkerpoint();
       var plan = session.plan();
            plan.setAddress('to', result.lng + ',' + result.lat, function(err, rees) {
                plan.updateRoutes();
          });
    });

    this.marker_creadas.push(markerform);
    this.marker_creadas.push(markerto);
};

module.exports.marker_map_point = function(to, map){

    var name = to[2];

    var IconEnd = L.icon({
        iconUrl: 'assets/images/graphics/icono.png',
        iconSize: [20, 20],
        iconAnchor: [0, 0],
        popupAnchor:  [-3, -76]
    });
    var markers = [
      L.marker([to[0], to[1]], {icon: IconEnd}).bindLabel(name, { direction: 'auto' })
    ];

    var layer = L.layerGroup(markers).addTo(map).eachLayer(function(layer){layer.showLabel()});

     var myZoom = {
      start:  map.getZoom(),
      end: map.getZoom()
    };
    map.on('zoomstart', function(e) {myZoom.start = map.getZoom();});
    map.on('zoomend', function(e) {
        myZoom.end = map.getZoom();
        console.log("en zoom", myZoom.end );

    });

    this.makerpoint_creadas.push(layer);
    //this.polyline_creadas.push(circle);
};

module.exports.drawRouteAmigo = function(legs,mode) {
    var route = legs.legGeometry.points;
    var circle_from = [legs.from.lat, legs.from.lon, legs.from.name];
    var circle_to = [legs.to.lat, legs.to.lon, legs.to.name];
    var color = '#000';
    var weight = 5;
    var dasharray= '';

        if (mode=="CAR") {
            color = '#9E9E9E';
            dasharray= '6';
            weight = 3;

        }else if(mode=="BICYCLE") {
            color = '#FF0000';
            dasharray= '6';
            weight = 3;

        }else if(mode=="SUBWAY" || mode=="RAIL") {
            color = '#FF0000';
             weight = 8;
             this.marker_map_point(circle_from, this.activeMap);
             this.marker_map_point(circle_to, this.activeMap);

        }
        else if(mode == "WALK") {
            color = '#0BC8F4';
            dasharray= '6';
             weight = 3;
        }
        else if(mode=="BUS") {
            color = '#FEF0B5';
             weight = 8;
             this.marker_map_point(circle_from, this.activeMap);
             this.marker_map_point(circle_to, this.activeMap);
        }

       var color_options = {
            color: color,
            opacity: 1,
            weight: weight,
            dashArray: dasharray
        };

      route = new L.Polyline(L.PolylineUtil.decode(route, 5), color_options);
      this.polyline_creadas.push(route);
      var boxes = L.RouteBoxer.box(route, 5);
      //var bounds = new L.LatLngBounds([]);
      //var bounds = [];
      var boxpolys = new Array(boxes.length);
      /*
      for (var i = 0; i < boxes.length; i++) {
        //bounds.extend(boxes[i]);
        bounds.push(boxes[i]);
      }*/

      route.addTo(this.activeMap);
      //this.activeMap.fitBounds(bounds);
};

<commit_msg>change maps<commit_after>var config = require('config');
var mapModule = require('map');
var plugins = require('./leaflet_plugins');
var polyUtil = require('./polyline_encoded.js');
var routeboxer = require('./leaflet_routeboxer.js');
var leaflet_label = require('./leaflet_label/leaflet.label-src.js');
var session = require('session');

var center = config.geocode().center.split(',').map(parseFloat)
if (config.map_provider && config.map_provider() !== 'AmigoCloud') {
  L.mapbox.accessToken = config.mapbox_access_token();
}

module.exports = function(el) {
  var map, realtime, southWest, northEast, blurLayer;

  if (config.map_provider && config.map_provider() === 'AmigoCloud') {
    southWest = L.latLng(35.946877085397,-123.480610897013);
    northEast = L.latLng(40.763279543715,-118.789317362500);
    map = (new L.amigo.map(el, {
      amigoLogo: 'right',
      loadAmigoLayers: false,
      inertia: false,
      zoomAnimation: $('.hide-map').css('display') !== 'none',
      maxBounds: L.latLngBounds(southWest, northEast),
      minZoom: 8
    })).setView([center[1], center[0]], config.geocode().zoom);

    L.amigo.auth.setToken(config.support_data_token());

    blurLayer = L.tileLayer(
    'https://www.amigocloud.com/api/v1/users/'+
	'23/projects/3019/datasets/23835/tiles/{z}/{x}/{y}.png?' +
	'token=' + config.support_data_token(),
      {
        name: 'Uncovered Area'
      }
    );

    map.addAuthLayer({
      id: config.mapbox_map_id(),
      accessToken: config.mapbox_access_token(),
      name: 'Gray',
      provider: 'mapbox'
    });
    map.addBaseLayer(L.amigo.AmigoGray);
    map.layersControl.addBaseLayer(
      L.bingLayer(
        config.bing_key(),
	{
	  type: 'Road',
	  attribution: 'Bing Maps'
	}
      ),
      'Bing Road'
    );
    map.layersControl.addOverlay(blurLayer);
    blurLayer.addTo(map);

    module.exports.activeMap = map;

    map.realtimeControl = L.control.toggleRealTime().addTo(map);

    realtime = mapModule.realtime();

  } else {

    map = L.mapbox.map(el, config.mapbox_map_id(), {
      attributionControl: false,
      inertia: false,
      zoomAnimation: false
    }).setView([center[1], center[0]], config.geocode().zoom);
  }

  return map;
};

module.exports.getMap = function () {
  return this.activeMap;
};

module.exports.cleanRoute = function() {
    module.exports.activeRoute.removeLayer();
    module.exports.activeRoute = null;
};

module.exports.polyline_creadas = [];
module.exports.marker_creadas = [];
module.exports.makerpoint_creadas = [];

module.exports.getpolyline_creadas = function () {
  return this.polyline_creadas;
};

module.exports.getMarker_creadas = function () {
  return this.marker_creadas;
};

module.exports.cleanPolyline = function() {
    var polyline_creadas = this.getpolyline_creadas();
    var map = this.activeMap;
    for (i in polyline_creadas) {
        try {
                map.removeLayer(polyline_creadas[i]);

            } catch (e) {
                console.log("problema al eliminar " + e);
            }

  }
  this.polyline_creadas = [];

};

module.exports.cleanMarker = function() {
    var map = this.activeMap;
    for (i in this.marker_creadas) {
        try {
                map.removeLayer(this.marker_creadas[i]);

            } catch (e) {
                console.log("problema al eliminar " + e);
            }
    }

  this.marker_creadas = [];

};

module.exports.cleanMarkerpoint = function() {
    var map = this.activeMap;
    for (i in this.makerpoint_creadas) {
        try {
                map.removeLayer(this.makerpoint_creadas[i]);

            } catch (e) {
                console.log("problema al eliminar " + e);
            }
    }

  this.makerpoint_creadas = [];

};

module.exports.marker_map = function(from, to){
     var IconStart = L.icon({
        iconUrl: 'assets/images/graphics/start.svg',
        iconSize: [40, 55],
        iconAnchor: [20, 50],
        popupAnchor:  [0, -50]
    });
    var IconEnd = L.icon({
        iconUrl: 'assets/images/graphics/end.svg',
        iconSize: [40, 55],
        iconAnchor: [20, 50],
        popupAnchor:  [0, -50]
    });

    var markerform = new L.marker([from[0],from[1]], {icon: IconStart, draggable: true})
        .addTo(this.activeMap);
    var markerto = new L.marker([to[0],to[1]], {icon: IconEnd, draggable: true})
        .addTo(this.activeMap);
    var _this = this;

    markerform.on('dragend', function(e){
       var marker = e.target;
       var result = marker.getLatLng();
       _this.cleanPolyline();
       _this.cleanMarkerpoint();
       var plan = session.plan();

            plan.setAddress('from', result.lng + ',' + result.lat, function(err, rees) {
                plan.updateRoutes();
          });
    });

    markerto.on('dragend', function(e){
       var marker = e.target;
       var result = marker.getLatLng();
       _this.cleanPolyline();
       _this.cleanMarkerpoint();
       var plan = session.plan();
            plan.setAddress('to', result.lng + ',' + result.lat, function(err, rees) {
                plan.updateRoutes();
          });
    });

    this.marker_creadas.push(markerform);
    this.marker_creadas.push(markerto);
};

module.exports.marker_map_point = function(to, map){

    var name = to[2];

    var IconEnd = L.icon({
        iconUrl: 'assets/images/graphics/icono.png',
        iconSize: [20, 20],
        iconAnchor: [0, 0],
        popupAnchor:  [-3, -76]
    });
    var markers = [
      L.marker([to[0], to[1]], {icon: IconEnd}).bindLabel(name, { direction: 'auto', noHide: true })
    ];

    var layer = L.layerGroup(markers).addTo(map).eachLayer(function(layer){layer.showLabel()});

     var myZoom = {
      start:  map.getZoom(),
      end: map.getZoom()
    };
    map.on('zoomstart', function(e) {myZoom.start = map.getZoom();});
    map.on('zoomend', function(e) {
        myZoom.end = map.getZoom();
        console.log("en zoom", myZoom.end );

    });

    this.makerpoint_creadas.push(layer);
    //this.polyline_creadas.push(circle);
};

module.exports.drawRouteAmigo = function(legs,mode) {
    var route = legs.legGeometry.points;
    var circle_from = [legs.from.lat, legs.from.lon, legs.from.name];
    var circle_to = [legs.to.lat, legs.to.lon, legs.to.name];
    var color = '#000';
    var weight = 5;
    var dasharray= '';

        if (mode=="CAR") {
            color = '#9E9E9E';
            dasharray= '6';
            weight = 3;

        }else if(mode=="BICYCLE") {
            color = '#FF0000';
            dasharray= '6';
            weight = 3;

        }else if(mode=="SUBWAY" || mode=="RAIL") {
            color = '#FF0000';
             weight = 8;
             this.marker_map_point(circle_from, this.activeMap);
             this.marker_map_point(circle_to, this.activeMap);

        }
        else if(mode == "WALK") {
            color = '#0BC8F4';
            dasharray= '6';
             weight = 3;
        }
        else if(mode=="BUS") {
            color = '#FEF0B5';
             weight = 8;
             this.marker_map_point(circle_from, this.activeMap);
             this.marker_map_point(circle_to, this.activeMap);
        }

       var color_options = {
            color: color,
            opacity: 1,
            weight: weight,
            dashArray: dasharray
        };

      route = new L.Polyline(L.PolylineUtil.decode(route, 5), color_options);
      this.polyline_creadas.push(route);
      var boxes = L.RouteBoxer.box(route, 5);
      //var bounds = new L.LatLngBounds([]);
      //var bounds = [];
      var boxpolys = new Array(boxes.length);
      /*
      for (var i = 0; i < boxes.length; i++) {
        //bounds.extend(boxes[i]);
        bounds.push(boxes[i]);
      }*/

      route.addTo(this.activeMap);
      //this.activeMap.fitBounds(bounds);
};

<|endoftext|>


<commit_before>var SVG_NS = "http://www.w3.org/2000/svg"

export default function (app) {
  var view = app.view || function () {
    return ""
  }

  var model
  var actions = {}
  var hooks = {
    onError: [],
    onAction: [],
    onUpdate: [],
    onRender: []
  }
  var subscriptions = []

  var node
  var root
  var element
  var plugins = app.plugins || []

  for (var i = -1; i < plugins.length; i++) {
    var plugin = i < 0 ? app : plugins[i](app)
    var obj = plugin.model

    if (obj != null) {
      model = merge(model, obj)
    }

    if (obj = plugin.actions) {
      init(actions, obj)
    }

    if (obj = plugin.subscriptions) {
      subscriptions = subscriptions.concat(obj)
    }

    if (obj = plugin.hooks) {
      Object.keys(obj).map(function (key) {
        (hooks[key] ? hooks[key] : hooks[key] = []).push(obj[key])
      })
    }
  }

  load(function () {
    root = app.root || document.body

    render(model, view)

    subscriptions.map(function (cb) {
      cb(model, actions, error)
    })
  })

  function error(error) {
    if (hooks.onError.length === 0) {
      throw error
    }

    hooks.onError.map(function (cb) {
      cb(error)
    })
  }

  function init(container, group, lastName) {
    Object.keys(group).map(function (key) {
      var name = lastName ? lastName + "." + key : key
      var action = group[key]

      if (typeof action === "function") {
        container[key] = function (data) {
          hooks.onAction.map(function (cb) {
            cb(name, data)
          })

          var result = action(model, data, actions, error)

          if (result == null || typeof result.then === "function") {
            return result

          } else {
            hooks.onUpdate.map(function (cb) {
              cb(model, result, data)
            })

            model = merge(model, result)
            render(model, view)
          }
        }
      } else {
        init(container[key]
          ? container[key]
          : container[key] = {}, action, name)
      }
    })
  }

  function load(cb) {
    if (document.readyState[0] !== "l") {
      cb()
    } else {
      document.addEventListener("DOMContentLoaded", cb)
    }
  }

  function render(model, view) {
    hooks.onRender.map(function (cb) {
      view = cb(model, view)
    })

    element = patch(root, element, node, node = view(model, actions))
  }

  function merge(a, b) {
    var obj = {}

    if (typeof b !== "object" || Array.isArray(b)) {
      return b
    }

    for (var i in a) {
      obj[i] = a[i]
    }
    for (var i in b) {
      obj[i] = b[i]
    }

    return obj
  }

  function createElementFrom(node, isSVG) {
    if (typeof node === "string") {
      var element = document.createTextNode(node)

    } else {
      var element = (isSVG = isSVG || node.tag === "svg")
        ? document.createElementNS(SVG_NS, node.tag)
        : document.createElement(node.tag)

      for (var name in node.data) {
        if (name === "onCreate") {
          node.data[name](element)
        } else {
          setElementData(element, name, node.data[name])
        }
      }

      for (var i = 0; i < node.children.length; i++) {
        element.appendChild(createElementFrom(node.children[i], isSVG))
      }
    }

    return element
  }

  function setElementData(element, name, value, oldValue) {
    name = name.toLowerCase()

    if (name === "key") {
    } else if (!value) {
      element[name] = value
      element.removeAttribute(name)

    } else if (name === "style") {
      for (var i in oldValue) {
        if (!(i in value)) {
          element.style[i] = ""
        }
      }

      for (var i in value) {
        element.style[i] = value[i]
      }
    } else {
      element.setAttribute(name, value)

      if (element.namespaceURI !== SVG_NS) {
        if (element.type === "text") {
          var oldSelStart = element.selectionStart
          var oldSelEnd = element.selectionEnd
        }

        element[name] = value

        if (oldSelStart >= 0) {
          element.setSelectionRange(oldSelStart, oldSelEnd)
        }
      }
    }
  }

  function updateElementData(element, oldData, data) {
    for (var name in merge(oldData, data)) {
      var value = data[name]
      var oldValue = oldData[name]
      var realValue = element[name]

      if (name === "onUpdate") {
        value(element)

      } else if (value !== oldValue || realValue !== value) {
        setElementData(element, name, value, oldValue)
      }
    }
  }

  function getKeyFrom(node) {
    if (node && (node = node.data)) {
      return node.key
    }
  }

  function removeElement(parent, element, node) {
    if (node.data.onRemove) {
      node.data.onRemove(element)
    }
    parent.removeChild(element)
  }

  function patch(parent, element, oldNode, node) {
    if (oldNode == null) {
      element = parent.insertBefore(createElementFrom(node), element)

    } else if (node.tag && node.tag === oldNode.tag) {
      updateElementData(element, oldNode.data, node.data)

      var len = node.children.length
      var oldLen = oldNode.children.length
      var reusableChildren = {}
      var oldElements = []
      var newKeys = {}

      for (var i = 0; i < oldLen; i++) {
        var oldElement = element.childNodes[i]
        oldElements[i] = oldElement

        var oldChild = oldNode.children[i]
        var oldKey = getKeyFrom(oldChild)

        if (null != oldKey) {
          reusableChildren[oldKey] = [oldElement, oldChild]
        }
      }

      var i = 0
      var j = 0

      while (j < len) {
        var oldElement = oldElements[i]
        var oldChild = oldNode.children[i]
        var newChild = node.children[j]

        var oldKey = getKeyFrom(oldChild)
        if (newKeys[oldKey]) {
          i++
          continue
        }

        var newKey = getKeyFrom(newChild)

        var reusableChild = reusableChildren[newKey]
        var reusableElement = 0
        var reusableNode = 0

        if (reusableChild) {
          reusableElement = reusableChild[0]
          reusableNode = reusableChild[1]
        }

        if (null == oldKey && null == newKey) {
          patch(element, oldElement, oldChild, newChild)
          j++
          i++

        } else if (null == oldKey && null != newKey) {
          if (reusableElement) {
            element.insertBefore(reusableElement, oldElement)
            patch(element, reusableElement, reusableNode, newChild)
          } else {
            patch(element, oldElement, null, newChild)
          }

          j++
          newKeys[newKey] = newChild

        } else if (null != oldKey && null == newKey) {
          i++

        } else {
          if (oldKey === newKey) {
            patch(element, reusableElement, reusableNode, newChild)
            i++

          } else if (reusableElement) {
            element.insertBefore(reusableElement, oldElement)
            patch(element, reusableElement, reusableNode, newChild)

          } else {
            patch(element, oldElement, null, newChild)
          }

          j++
          newKeys[newKey] = newChild
        }
      }

      while (i < oldLen) {
        var oldChild = oldNode.children[i]
        var oldKey = getKeyFrom(oldChild)
        if (null == oldKey) {
          removeElement(element, oldElements[i], oldChild)
        }
        i++
      }

      for (var i in reusableChildren) {
        var reusableChild = reusableChildren[i]
        var reusableNode = reusableChild[1]
        if (!newKeys[reusableNode.data.key]) {
          removeElement(element, reusableChild[0], reusableNode)
        }
      }
    } else if (node !== oldNode) {
      var i = element
      parent.replaceChild(element = createElementFrom(node), i)
    }

    return element
  }
}
<commit_msg>Don't set events as attributes. Fix #175.<commit_after>var SVG_NS = "http://www.w3.org/2000/svg"

export default function (app) {
  var view = app.view || function () {
    return ""
  }

  var model
  var actions = {}
  var hooks = {
    onError: [],
    onAction: [],
    onUpdate: [],
    onRender: []
  }
  var subscriptions = []

  var node
  var root
  var element
  var plugins = app.plugins || []

  for (var i = -1; i < plugins.length; i++) {
    var plugin = i < 0 ? app : plugins[i](app)
    var obj = plugin.model

    if (obj != null) {
      model = merge(model, obj)
    }

    if (obj = plugin.actions) {
      init(actions, obj)
    }

    if (obj = plugin.subscriptions) {
      subscriptions = subscriptions.concat(obj)
    }

    if (obj = plugin.hooks) {
      Object.keys(obj).map(function (key) {
        (hooks[key] ? hooks[key] : hooks[key] = []).push(obj[key])
      })
    }
  }

  load(function () {
    root = app.root || document.body

    render(model, view)

    subscriptions.map(function (cb) {
      cb(model, actions, error)
    })
  })

  function error(error) {
    if (hooks.onError.length === 0) {
      throw error
    }

    hooks.onError.map(function (cb) {
      cb(error)
    })
  }

  function init(container, group, lastName) {
    Object.keys(group).map(function (key) {
      var name = lastName ? lastName + "." + key : key
      var action = group[key]

      if (typeof action === "function") {
        container[key] = function (data) {
          hooks.onAction.map(function (cb) {
            cb(name, data)
          })

          var result = action(model, data, actions, error)

          if (result == null || typeof result.then === "function") {
            return result

          } else {
            hooks.onUpdate.map(function (cb) {
              cb(model, result, data)
            })

            model = merge(model, result)
            render(model, view)
          }
        }
      } else {
        init(container[key]
          ? container[key]
          : container[key] = {}, action, name)
      }
    })
  }

  function load(cb) {
    if (document.readyState[0] !== "l") {
      cb()
    } else {
      document.addEventListener("DOMContentLoaded", cb)
    }
  }

  function render(model, view) {
    hooks.onRender.map(function (cb) {
      view = cb(model, view)
    })

    element = patch(root, element, node, node = view(model, actions))
  }

  function merge(a, b) {
    var obj = {}

    if (typeof b !== "object" || Array.isArray(b)) {
      return b
    }

    for (var i in a) {
      obj[i] = a[i]
    }
    for (var i in b) {
      obj[i] = b[i]
    }

    return obj
  }

  function createElementFrom(node, isSVG) {
    if (typeof node === "string") {
      var element = document.createTextNode(node)

    } else {
      var element = (isSVG = isSVG || node.tag === "svg")
        ? document.createElementNS(SVG_NS, node.tag)
        : document.createElement(node.tag)

      for (var name in node.data) {
        if (name === "onCreate") {
          node.data[name](element)
        } else {
          setElementData(element, name, node.data[name])
        }
      }

      for (var i = 0; i < node.children.length; i++) {
        element.appendChild(createElementFrom(node.children[i], isSVG))
      }
    }

    return element
  }

  function setElementData(element, name, value, oldValue) {
    name = name.toLowerCase()

    if (name === "key") {
    } else if (!value) {
      element[name] = value
      element.removeAttribute(name)

    } else if (name === "style") {
      for (var i in oldValue) {
        if (!(i in value)) {
          element.style[i] = ""
        }
      }

      for (var i in value) {
        element.style[i] = value[i]
      }
    } else {
      if (typeof value !== "function") {
        element.setAttribute(name, value)
      }

      if (element.namespaceURI !== SVG_NS) {
        if (element.type === "text") {
          var oldSelStart = element.selectionStart
          var oldSelEnd = element.selectionEnd
        }

        element[name] = value

        if (oldSelStart >= 0) {
          element.setSelectionRange(oldSelStart, oldSelEnd)
        }
      }
    }
  }

  function updateElementData(element, oldData, data) {
    for (var name in merge(oldData, data)) {
      var value = data[name]
      var oldValue = oldData[name]
      var realValue = element[name]

      if (name === "onUpdate") {
        value(element)

      } else if (value !== oldValue || realValue !== value) {
        setElementData(element, name, value, oldValue)
      }
    }
  }

  function getKeyFrom(node) {
    if (node && (node = node.data)) {
      return node.key
    }
  }

  function removeElement(parent, element, node) {
    if (node.data.onRemove) {
      node.data.onRemove(element)
    }
    parent.removeChild(element)
  }

  function patch(parent, element, oldNode, node) {
    if (oldNode == null) {
      element = parent.insertBefore(createElementFrom(node), element)

    } else if (node.tag && node.tag === oldNode.tag) {
      updateElementData(element, oldNode.data, node.data)

      var len = node.children.length
      var oldLen = oldNode.children.length
      var reusableChildren = {}
      var oldElements = []
      var newKeys = {}

      for (var i = 0; i < oldLen; i++) {
        var oldElement = element.childNodes[i]
        oldElements[i] = oldElement

        var oldChild = oldNode.children[i]
        var oldKey = getKeyFrom(oldChild)

        if (null != oldKey) {
          reusableChildren[oldKey] = [oldElement, oldChild]
        }
      }

      var i = 0
      var j = 0

      while (j < len) {
        var oldElement = oldElements[i]
        var oldChild = oldNode.children[i]
        var newChild = node.children[j]

        var oldKey = getKeyFrom(oldChild)
        if (newKeys[oldKey]) {
          i++
          continue
        }

        var newKey = getKeyFrom(newChild)

        var reusableChild = reusableChildren[newKey]
        var reusableElement = 0
        var reusableNode = 0

        if (reusableChild) {
          reusableElement = reusableChild[0]
          reusableNode = reusableChild[1]
        }

        if (null == oldKey && null == newKey) {
          patch(element, oldElement, oldChild, newChild)
          j++
          i++

        } else if (null == oldKey && null != newKey) {
          if (reusableElement) {
            element.insertBefore(reusableElement, oldElement)
            patch(element, reusableElement, reusableNode, newChild)
          } else {
            patch(element, oldElement, null, newChild)
          }

          j++
          newKeys[newKey] = newChild

        } else if (null != oldKey && null == newKey) {
          i++

        } else {
          if (oldKey === newKey) {
            patch(element, reusableElement, reusableNode, newChild)
            i++

          } else if (reusableElement) {
            element.insertBefore(reusableElement, oldElement)
            patch(element, reusableElement, reusableNode, newChild)

          } else {
            patch(element, oldElement, null, newChild)
          }

          j++
          newKeys[newKey] = newChild
        }
      }

      while (i < oldLen) {
        var oldChild = oldNode.children[i]
        var oldKey = getKeyFrom(oldChild)
        if (null == oldKey) {
          removeElement(element, oldElements[i], oldChild)
        }
        i++
      }

      for (var i in reusableChildren) {
        var reusableChild = reusableChildren[i]
        var reusableNode = reusableChild[1]
        if (!newKeys[reusableNode.data.key]) {
          removeElement(element, reusableChild[0], reusableNode)
        }
      }
    } else if (node !== oldNode) {
      var i = element
      parent.replaceChild(element = createElementFrom(node), i)
    }

    return element
  }
}
<|endoftext|>


<commit_before>define(['underscore', 'app', 'backbone', 'backbone.marionette', 'nusmods',
    'hbs!../templates/select', 'hbs!../templates/select_result','select2'],
  function(_, App, Backbone, Marionette, NUSMods, template, selectResultTemplate) {
    'use strict';

    var codes, titles, modsLength;
    var codesAndTitlesPromise = NUSMods.getCodesAndTitles().then(function (data) {
      codes = _.keys(data);
      titles = _.values(data);
      modsLength = codes.length;
    });

    return Marionette.ItemView.extend({
      className: 'form-group',
      template: template,

      events: {
        'select2-selecting': 'onSelect2Selecting'
      },

      ui: {
        'input': 'input'
      },

      onAdd: function (event) {
        event.stopPropagation();
        var button = $(event.currentTarget);
        App.request('addModule', button.data('code'));
        button
          .toggleClass('add remove')
          .prop('title', 'Remove from Timetable')
          .children().toggleClass('fa-plus fa-times');
      },

      onRemove: function (event) {
        event.stopPropagation();
        var button = $(event.currentTarget);
        App.request('removeModule', button.data('code'));
        button
          .toggleClass('add remove')
          .prop('title', 'Add to Timetable')
          .children().toggleClass('fa-plus fa-times');
      },

      onSelect2Open: function () {
        $('#select2-drop')
          .on('mouseup', '.add', this.onAdd)
          .on('mouseup', '.remove', this.onRemove);
      },

      onSelect2Selecting: function(event) {
        event.preventDefault();
        Backbone.history.navigate('modules/' + event.val, {trigger: true});
        this.ui.input.select2('close');
      },

      onShow: function () {
        _.bindAll(this, 'onAdd', 'onRemove', 'onSelect2Open');

        var PAGE_SIZE = 50;
        this.ui.input.select2({
          multiple: true,
          formatResult: function (object) {
            return selectResultTemplate(object);
          },
          query: function (options) {
            codesAndTitlesPromise.then(function () {
              var i,
                results = [],
                pushResult = function (i) {
                  return results.push({
                    id: codes[i],
                    selected: App.request('isModuleSelected', codes[i]),
                    text: codes[i] + ' ' + titles[i]
                  });
                };
              if (options.term) {
                var re = new RegExp(options.term, 'i');
                for (i = options.context || 0; i < modsLength; i++) {
                  if (codes[i].search(re) !== -1 || titles[i].search(re) !== -1) {
                    if (pushResult(i) === PAGE_SIZE) {
                      i++;
                      break;
                    }
                  }
                }
              } else {
                for (i = (options.page - 1) * PAGE_SIZE; i < options.page * PAGE_SIZE; i++) {
                  pushResult(i);
                }
              }
              options.callback({
                context: i,
                more: i < modsLength,
                results: results
              });
            });
          }
        });

        this.ui.input.one('select2-open', this.onSelect2Open);
      }
    });
  });
<commit_msg>Unify add and remove event handlers in select view<commit_after>define(['underscore', 'app', 'backbone', 'backbone.marionette', 'nusmods',
    'hbs!../templates/select', 'hbs!../templates/select_result','select2'],
  function(_, App, Backbone, Marionette, NUSMods, template, selectResultTemplate) {
    'use strict';

    var codes, titles, modsLength;
    var codesAndTitlesPromise = NUSMods.getCodesAndTitles().then(function (data) {
      codes = _.keys(data);
      titles = _.values(data);
      modsLength = codes.length;
    });

    return Marionette.ItemView.extend({
      className: 'form-group',
      template: template,

      events: {
        'select2-selecting': 'onSelect2Selecting'
      },

      ui: {
        'input': 'input'
      },

      onMouseup: function (event) {
        event.stopPropagation();
        var button = $(event.currentTarget);
        var add = button.hasClass('add');
        App.request((add ? 'add' : 'remove') + 'Module', button.data('code'));
        button
          .toggleClass('add remove')
          .prop('title', (add ? 'Add to' : 'Remove from') + 'Timetable')
          .children().toggleClass('fa-plus fa-times');
      },

      onSelect2Open: function () {
        $('#select2-drop').on('mouseup', '.btn', this.onMouseup);
      },

      onSelect2Selecting: function(event) {
        event.preventDefault();
        Backbone.history.navigate('modules/' + event.val, {trigger: true});
        this.ui.input.select2('close');
      },

      onShow: function () {
        _.bindAll(this, 'onMouseup', 'onSelect2Open');

        var PAGE_SIZE = 50;
        this.ui.input.select2({
          multiple: true,
          formatResult: function (object) {
            return selectResultTemplate(object);
          },
          query: function (options) {
            codesAndTitlesPromise.then(function () {
              var i,
                results = [],
                pushResult = function (i) {
                  return results.push({
                    id: codes[i],
                    selected: App.request('isModuleSelected', codes[i]),
                    text: codes[i] + ' ' + titles[i]
                  });
                };
              if (options.term) {
                var re = new RegExp(options.term, 'i');
                for (i = options.context || 0; i < modsLength; i++) {
                  if (codes[i].search(re) !== -1 || titles[i].search(re) !== -1) {
                    if (pushResult(i) === PAGE_SIZE) {
                      i++;
                      break;
                    }
                  }
                }
              } else {
                for (i = (options.page - 1) * PAGE_SIZE; i < options.page * PAGE_SIZE; i++) {
                  pushResult(i);
                }
              }
              options.callback({
                context: i,
                more: i < modsLength,
                results: results
              });
            });
          }
        });

        this.ui.input.one('select2-open', this.onSelect2Open);
      }
    });
  });
<|endoftext|>


<commit_before>export const API_MAX_PAGE_SIZE = 200;
export const API_ROOT = '/api/v2/';

export const EVENT_START_TASK = 'playbook_on_task_start';
export const EVENT_START_PLAY = 'playbook_on_play_start';
export const EVENT_START_PLAYBOOK = 'playbook_on_start';
export const EVENT_STATS_PLAY = 'playbook_on_stats';

export const HOST_STATUS_KEYS = ['dark', 'failures', 'changed', 'ok', 'skipped'];

export const JOB_STATUS_COMPLETE = ['successful', 'failed', 'unknown'];
export const JOB_STATUS_INCOMPLETE = ['canceled', 'error'];
export const JOB_STATUS_UNSUCCESSFUL = ['failed'].concat(JOB_STATUS_INCOMPLETE);
export const JOB_STATUS_FINISHED = JOB_STATUS_COMPLETE.concat(JOB_STATUS_INCOMPLETE);

export const OUTPUT_ANSI_COLORMAP = {
    0: '#000',
    1: '#A00',
    2: '#080',
    3: '#F0AD4E',
    4: '#00A',
    5: '#A0A',
    6: '#0AA',
    7: '#AAA',
    8: '#555',
    9: '#F55',
    10: '#5F5',
    11: '#FF5',
    12: '#55F',
    13: '#F5F',
    14: '#5FF',
    15: '#FFF'
};
export const OUTPUT_ELEMENT_CONTAINER = '.at-Stdout-container';
export const OUTPUT_ELEMENT_TBODY = '#atStdoutResultTable';
export const OUTPUT_ELEMENT_LAST = '#atStdoutMenuLast';
export const OUTPUT_MAX_BUFFER_LENGTH = 1000;
export const OUTPUT_MAX_LAG = 120;
export const OUTPUT_NO_COUNT_JOB_TYPES = ['ad_hoc_command', 'system_job', 'inventory_update'];
export const OUTPUT_ORDER_BY = 'counter';
export const OUTPUT_PAGE_CACHE = true;
export const OUTPUT_PAGE_LIMIT = 5;
export const OUTPUT_PAGE_SIZE = 50;
export const OUTPUT_SCROLL_DELAY = 100;
export const OUTPUT_SCROLL_THRESHOLD = 0.1;
export const OUTPUT_SEARCH_DOCLINK = 'https://docs.ansible.com/ansible-tower/3.3.0/html/userguide/search_sort.html';
export const OUTPUT_SEARCH_FIELDS = ['changed', 'created', 'failed', 'host_name', 'stdout', 'task', 'role', 'playbook', 'play', 'start_line', 'end_line'];
export const OUTPUT_SEARCH_KEY_EXAMPLES = ['host_name:localhost', 'task:set', 'created:>=2000-01-01', 'start_line:>=9000'];
export const OUTPUT_EVENT_LIMIT = OUTPUT_PAGE_LIMIT * OUTPUT_PAGE_SIZE;

export const WS_PREFIX = 'ws';
<commit_msg>point output search doc link to latest<commit_after>export const API_MAX_PAGE_SIZE = 200;
export const API_ROOT = '/api/v2/';

export const EVENT_START_TASK = 'playbook_on_task_start';
export const EVENT_START_PLAY = 'playbook_on_play_start';
export const EVENT_START_PLAYBOOK = 'playbook_on_start';
export const EVENT_STATS_PLAY = 'playbook_on_stats';

export const HOST_STATUS_KEYS = ['dark', 'failures', 'changed', 'ok', 'skipped'];

export const JOB_STATUS_COMPLETE = ['successful', 'failed', 'unknown'];
export const JOB_STATUS_INCOMPLETE = ['canceled', 'error'];
export const JOB_STATUS_UNSUCCESSFUL = ['failed'].concat(JOB_STATUS_INCOMPLETE);
export const JOB_STATUS_FINISHED = JOB_STATUS_COMPLETE.concat(JOB_STATUS_INCOMPLETE);

export const OUTPUT_ANSI_COLORMAP = {
    0: '#000',
    1: '#A00',
    2: '#080',
    3: '#F0AD4E',
    4: '#00A',
    5: '#A0A',
    6: '#0AA',
    7: '#AAA',
    8: '#555',
    9: '#F55',
    10: '#5F5',
    11: '#FF5',
    12: '#55F',
    13: '#F5F',
    14: '#5FF',
    15: '#FFF'
};
export const OUTPUT_ELEMENT_CONTAINER = '.at-Stdout-container';
export const OUTPUT_ELEMENT_TBODY = '#atStdoutResultTable';
export const OUTPUT_ELEMENT_LAST = '#atStdoutMenuLast';
export const OUTPUT_MAX_BUFFER_LENGTH = 1000;
export const OUTPUT_MAX_LAG = 120;
export const OUTPUT_NO_COUNT_JOB_TYPES = ['ad_hoc_command', 'system_job', 'inventory_update'];
export const OUTPUT_ORDER_BY = 'counter';
export const OUTPUT_PAGE_CACHE = true;
export const OUTPUT_PAGE_LIMIT = 5;
export const OUTPUT_PAGE_SIZE = 50;
export const OUTPUT_SCROLL_DELAY = 100;
export const OUTPUT_SCROLL_THRESHOLD = 0.1;
export const OUTPUT_SEARCH_DOCLINK = 'https://docs.ansible.com/ansible-tower/latest/html/userguide/search_sort.html';
export const OUTPUT_SEARCH_FIELDS = ['changed', 'created', 'failed', 'host_name', 'stdout', 'task', 'role', 'playbook', 'play', 'start_line', 'end_line'];
export const OUTPUT_SEARCH_KEY_EXAMPLES = ['host_name:localhost', 'task:set', 'created:>=2000-01-01', 'start_line:>=9000'];
export const OUTPUT_EVENT_LIMIT = OUTPUT_PAGE_LIMIT * OUTPUT_PAGE_SIZE;

export const WS_PREFIX = 'ws';
<|endoftext|>