<commit_before>angular.module('huntEdu')
.config(['$routeProvider', function($routeProvider) {
            $routeProvider.when('/', {
                templateUrl: 'templates/splash.html',
                controller: 'SplashCtrl'
            }).when('/applicantRegister', {
                templateUrl: 'templates/register/applicantRegister.html',
                controller: 'ApplicantRegisterCtrl'
            }).when('/employerRegister', {
   	        templateUrl: 'templates/register/employerRegister.html',
            	controller: 'EmployerRegisterCtrl'
            }).when('/jobPosting', {
		        templateUrl: 'templates/jobs/jobPosting.html',
        		controller: 'JobPostingCtrl'
            }).when('/searchResults', {
                templateUrl: 'templates/searchResults.html',
                controller: 'SearchResultsCtrl'
            }).when('/employerProfile', {
                templateUrl: 'templates/employerProfile.html',
                controller: 'EmployerProfileCtrl'
            }).when('/applicantProfile', {
                templateUrl: 'templates/applicantProfile.html',
                controller: 'ApplicantProfileCtrl'
            }).when('/jobListing/:id', {
                templateUrl: 'templates/jobs/jobListing.html',
                controller: 'JobListingCtrl',
                resolve: {
                    job: ['$route', 'SearchService', function($route, SearchService) {
                        var id = $route.current.params.id;
                        return SearchService.findJobById(id);
                    }]
                }
            }).when('/searchResults/:keyword', {
                templateUrl: 'templates/search/searchResults.html',
                controller: 'SearchResultsCtrl',
                resolve: {
                    jobs: ['$route', 'SearchService', function($route, SearchService) {
                        var keyword = $route.current.params.keyword;
                        return SearchService.search(keyword);
                    }]
                }
            }).when('/searchError', {
                templateUrl: 'templates/search/searchError.html',
            }).when('/thankyou', {
                templateUrl: 'templates/thankyou.html',
                controller: 'ThankyouCtrl'
            }).when('/updateApplicantProfile', {
                templateUrl: 'templates/updateApplicantProfile.html',
                controller: 'UpdateApplicantProfileCtrl',
            }).when('/updateEmployerProfile', {
                templateUrl: 'templates/updateEmployerProfile.html',
                controller: 'UpdateEmployerProfileCtrl',
            }).when('/newJob', {
                templateUrl: 'templates/jobs/jobListing.html',
                controller: 'NewJobCtrl',
                resolve: {
                    job: ['JobList',  function(JobList) {
                        return JobList.getNewJob();
                    }]
                }
            }).when('/home', {
                templateUrl: 'templates/home.html',
                controller: 'HomeCtrl',
                resolve: {
                    focusJobs: ['SearchService', function(SearchService){
                        return SearchService.getRecommendedFocusJobs();
                    }],

                    interestJobs: ['SearchService', function(SearchService) {
                        return SearchService.getRecommendedInterestJobs();
                    }]
                }
            }).otherwise({
                    redirectTo: '/'
            });
}]);

<commit_msg>no changes. it was just telling me i did something with a curly brace for some reason.<commit_after>angular.module('huntEdu')
.config(['$routeProvider', function($routeProvider) {
            $routeProvider.when('/', {
                templateUrl: 'templates/splash.html',
                controller: 'SplashCtrl'
            }).when('/applicantRegister', {
                templateUrl: 'templates/register/applicantRegister.html',
                controller: 'ApplicantRegisterCtrl'
            }).when('/employerRegister', {
   	        templateUrl: 'templates/register/employerRegister.html',
            	controller: 'EmployerRegisterCtrl'
            }).when('/jobPosting', {
		        templateUrl: 'templates/jobs/jobPosting.html',
        		controller: 'JobPostingCtrl'
            }).when('/searchResults', {
                templateUrl: 'templates/searchResults.html',
                controller: 'SearchResultsCtrl'
            }).when('/employerProfile', {
                templateUrl: 'templates/employerProfile.html',
                controller: 'EmployerProfileCtrl'
            }).when('/applicantProfile', {
                templateUrl: 'templates/applicantProfile.html',
                controller: 'ApplicantProfileCtrl'
            }).when('/jobListing/:id', {
                templateUrl: 'templates/jobs/jobListing.html',
                controller: 'JobListingCtrl',
                resolve: {
                    job: ['$route', 'SearchService', function($route, SearchService) {
                        var id = $route.current.params.id;
                        return SearchService.findJobById(id);
                    }]
                }
            }).when('/searchResults/:keyword', {
                templateUrl: 'templates/search/searchResults.html',
                controller: 'SearchResultsCtrl',
                resolve: {
                    jobs: ['$route', 'SearchService', function($route, SearchService) {
                        var keyword = $route.current.params.keyword;
                        return SearchService.search(keyword);
                    }]
                }
            }).when('/searchError', {
                templateUrl: 'templates/search/searchError.html',
            }).when('/thankyou', {
                templateUrl: 'templates/thankyou.html',
                controller: 'ThankyouCtrl'
            }).when('/updateApplicantProfile', {
                templateUrl: 'templates/updateApplicantProfile.html',
                controller: 'UpdateApplicantProfileCtrl',
            }).when('/updateEmployerProfile', {
                templateUrl: 'templates/updateEmployerProfile.html',
                controller: 'UpdateEmployerProfileCtrl',
            }).when('/newJob', {
                templateUrl: 'templates/jobs/jobListing.html',
                controller: 'NewJobCtrl',
                resolve: {
                    job: ['JobList',  function(JobList) {
                        return JobList.getNewJob();
                    }]
                }
            }).when('/home', {
                templateUrl: 'templates/home.html',
                controller: 'HomeCtrl',
                resolve: {
                    focusJobs: ['SearchService', function(SearchService){
                        return SearchService.getRecommendedFocusJobs();
                    }],

                    interestJobs: ['SearchService', function(SearchService) {
                        return SearchService.getRecommendedInterestJobs();
                    }]
                }
            }).otherwise({
                    redirectTo: '/'
            });
}]);

<|endoftext|>


<commit_before>module.exports = function(skill, info, bot, message) {
    var appRoot = process.cwd();
    var builtinPhrases = require('../builtins');

    var customPhrases = require('../custom-phrases.json');
    //var customPhrases;
    //console.log()
    //try {
    //    customPhrasesText = fs.readFileSync('../custom-phrases.json').toString();
    //} catch (err) {
    //    throw new Error('Uh oh, Bottie could not find the custom-phrases.json file, did you move it?');
    //}

    //try {
    //    customPhrases = JSON.parse(customPhrasesText);
    //} catch (err) {
    //    throw new Error('Uh oh, custom-phrases.json was not valid JSON! Fix it, please? :)');
    //}

//eachKey(customPhrases, Bottie.Teach);
//eachKey(builtinPhrases, Bottie.Teach);

    bot.reply(message,'These are my current commands: ' );

    bot.reply(message,'Built-in commands: ' );
    for (var key in builtinPhrases) {
        if (builtinPhrases.hasOwnProperty(key)) {
            bot.reply(message,'These are my current commands: ' );
            console.log(key + " -> " + builtinPhrases[key]);
        }
    }

    bot.reply(message,'Custom-added commands: ' );
    for (var key in customPhrases) {
        if (customPhrases.hasOwnProperty(key)) {
            bot.reply(message,'These are my current commands: ' );
            console.log(key + " -> " + customPhrases[key]);
        }
    }

};
<commit_msg>Update Help.js<commit_after>module.exports = function(skill, info, bot, message) {
    var appRoot = process.cwd();
    var builtinPhrases = require('../builtins');

    var customPhrases = require('../custom-phrases.json');
    //var customPhrases;
    //console.log()
    //try {
    //    customPhrasesText = fs.readFileSync('../custom-phrases.json').toString();
    //} catch (err) {
    //    throw new Error('Uh oh, Bottie could not find the custom-phrases.json file, did you move it?');
    //}

    //try {
    //    customPhrases = JSON.parse(customPhrasesText);
    //} catch (err) {
    //    throw new Error('Uh oh, custom-phrases.json was not valid JSON! Fix it, please? :)');
    //}

//eachKey(customPhrases, Bottie.Teach);
//eachKey(builtinPhrases, Bottie.Teach);

    bot.reply(message,'These are my current commands: ' );

    bot.reply(message,'Built-in commands: ' );
    for (var key in builtinPhrases) {
        if (builtinPhrases.hasOwnProperty(key)) {
            //bot.reply(message,'These are my current commands: ' );
            bot.reply(message, key + " -> " + builtinPhrases[key]);
            console.log(key + " -> " + builtinPhrases[key]);
        }
    }

    bot.reply(message,'Custom-added commands: ' );
    for (var key in customPhrases) {
        if (customPhrases.hasOwnProperty(key)) {
            //bot.reply(message,'These are my current commands: ' );
            bot.reply(message, key + " -> " + customPhrases[key]);
            console.log(key + " -> " + customPhrases[key]);
        }
    }

};
<|endoftext|>


<commit_before>/**
 * Implementation of {@link IEmmetEditor} interface for CodeMirror2
 * @param {Function} require
 * @param {Underscore} _
 */
emmet.exec(function(require, _) {
	var ios = /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent);
	var mac = ios || /Mac/.test(navigator.platform);
	var keymap = {
		'Cmd-E': 'expand_abbreviation',
		'Tab': 'expand_abbreviation',
		'Cmd-D': 'match_pair_outward',
		'Shift-Cmd-D': 'match_pair_inward',
		'Shift-Cmd-A': 'wrap_with_abbreviation',
		'Ctrl-Alt-Right': 'next_edit_point',
		'Ctrl-Alt-Left': 'prev_edit_point',
		'Cmd-L': 'select_line',
		'Cmd-Shift-M': 'merge_lines',
		'Cmd-/': 'toggle_comment',
		'Cmd-J': 'split_join_tag',
		'Cmd-K': 'remove_tag',
		'Shift-Cmd-Y': 'evaluate_math_expression',

		'Ctrl-Up': 'increment_number_by_1',
		'Ctrl-Down': 'decrement_number_by_1',
		'Alt-Up': 'increment_number_by_01',
		'Alt-Down': 'decrement_number_by_01',
		'Ctrl-Alt-Up': 'increment_number_by_10',
		'Ctrl-Alt-Down': 'decrement_number_by_10',

		'Cmd-.': 'select_next_item',
		'Cmd-,': 'select_previous_item',
		'Cmd-B': 'reflect_css_value',

		'Enter': 'insert_formatted_line_break'
	};

	var modeMap = {
		'text/html': 'html',
		'application/xml': 'xml',
		'text/xsl': 'xsl',
		'text/css': 'css',
		'text/x-less': 'less'
	};

	if (!mac) {
		// replace Cmd modifier for non-Mac environment
		var pcKeymap = {};
		_.each(keymap, function(v, k) {
			pcKeymap[k.replace('Cmd', 'Ctrl')] = v;
		});

		keymap = pcKeymap;
	}

	// add “profile” property to CodeMirror defaults so in won’t be lost
	// then CM instance is instantiated with “profile” property
	CodeMirror.defaults.profile = 'html';

	var editorProxy = {
		context: null,

		getSelectionRange: function() {
			var caretPos = this.getCaretPos();
			return {
				start: caretPos,
				end: caretPos + this.getSelection().length
			};
		},

		createSelection: function(start, end) {
			if (start == end) {
				this.context.setCursor(this.context.posFromIndex(start));
			} else {
				this.context.setSelection(this.context.posFromIndex(start), this.context.posFromIndex(end));
			}
		},

		getCurrentLineRange: function() {
			var caret = this.context.getCursor(true);
			return {
				start: this.context.indexFromPos({line: caret.line, ch: 0}),
				end:   this.context.indexFromPos({line: caret.line, ch: this.context.getLine(caret.line).length})
			};
		},

		getCaretPos: function(){
			return this.context.indexFromPos(this.context.getCursor(true));
		},

		setCaretPos: function(pos){
			this.createSelection(pos, pos);
		},

		getCurrentLine: function() {
			return this.context.getLine( this.context.getCursor(true).line ) || '';
		},

		replaceContent: function(value, start, end, noIndent) {

			if (_.isUndefined(end))
				end = _.isUndefined(start) ? content.length : start;
			if (_.isUndefined(start)) start = 0;
			var utils = require('utils');

			// indent new value
			if (!noIndent) {
				value = utils.padString(value, utils.getLinePaddingFromPosition(this.getContent(), start));
			}

			// find new caret position
			var tabstopData = require('tabStops').extract(value, {
				escape: function(ch) {
					return ch;
				}
			});
			value = tabstopData.text;
			var firstTabStop = tabstopData.tabstops[0];

			if (firstTabStop) {
				firstTabStop.start += start;
				firstTabStop.end += start;
			} else {
				firstTabStop = {
					start: value.length + start,
					end: value.length + start
				};
			}

			// do a compound change to record all changes into single undo event
			var that = this;
			this.context.compoundChange(function() {
				that.context.replaceRange(value, that.context.posFromIndex(start), that.context.posFromIndex(end));
				that.createSelection(firstTabStop.start, firstTabStop.end);
			});
		},

		getContent: function(){
			return this.context.getValue();
		},

		getSyntax: function() {
			var syntax = this.context.getOption('mode');
			if (syntax in modeMap)
				syntax = modeMap[syntax];

			var caretPos = this.getCaretPos();

			if (!require('resources').hasSyntax(syntax))
				syntax = 'html';

			if (syntax == 'html') {
				// get the context tag
				var pair = require('html_matcher').getTags(this.getContent(), caretPos);
				if (pair && pair[0] && pair[0].type == 'tag' && pair[0].name.toLowerCase() == 'style') {
					// check that we're actually inside the tag
					if (pair[0].end <= caretPos && pair[1].start >= caretPos)
						syntax = 'css';
				}
			}

			return syntax;
		},

		/**
		 * Returns current output profile name (@see emmet#setupProfile)
		 * @return {String}
		 */
		getProfileName: function() {
			if (this.context.getOption('profile'))
				return this.context.getOption('profile');

			switch(this.getSyntax()) {
				 case 'xml':
				 case 'xsl':
				 	return 'xml';
				 case 'html':
				 	var profile = require('resources').getVariable('profile');
				 	if (!profile) { // no forced profile, guess from content
					 	// html or xhtml?
				 		profile = this.getContent().search(/<!DOCTYPE[^>]+XHTML/i) != -1 ? 'xhtml': 'html';
				 	}

				 	return profile;
			}

			return 'xhtml';
		},

		/**
		 * Ask user to enter something
		 * @param {String} title Dialog title
		 * @return {String} Entered data
		 * @since 0.65
		 */
		prompt: function(title) {
			return prompt(title);
		},

		/**
		 * Returns current selection
		 * @return {String}
		 * @since 0.65
		 */
		getSelection: function() {
			return this.context.getSelection() || '';
		},

		/**
		 * Returns current editor's file path
		 * @return {String}
		 * @since 0.65
		 */
		getFilePath: function() {
			return location.href;
		}
	};

	function setupContext(context) {
		editorProxy.context = context;
		var indentation = '\t';
		if (!context.getOption('indentWithTabs')) {
			indentation = require('utils').repeatString(' ', context.getOption('indentUnit'));
		}

		require('resources').setVariable('indentation', indentation);
	}

	function runEmmetCommand(name, editor) {
		setupContext(editor);
		try {
			if (require('actions').run(name, editorProxy))
				return true;
		} catch (e) {}

		throw CodeMirror.Pass;
	}

	// add keybindings to CodeMirror
	if (!CodeMirror.defaults.extraKeys)
		CodeMirror.defaults.extraKeys = {};

	_.each(keymap, function(commandName, keybinding) {

		// register Emmet command as predefined CodeMirror command
		// for latter use
		var cmCommand = 'emmet.' + commandName;
		if (!CodeMirror.commands[cmCommand]) {
			CodeMirror.commands[cmCommand] = function(editor) {
				return runEmmetCommand(commandName, editor);
			};
		}

		CodeMirror.defaults.extraKeys[keybinding] = cmCommand;
	});
});
<commit_msg>Updated CodeMirror2 plugin to solve OSX issues with some keyboard shortcuts<commit_after>/**
 * Implementation of {@link IEmmetEditor} interface for CodeMirror2
 * @param {Function} require
 * @param {Underscore} _
 */
emmet.exec(function(require, _) {
	var ios = /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent);
	var mac = ios || /Mac/.test(navigator.platform);
	var keymap = {
		'Cmd-E': 'expand_abbreviation',
		'Tab': 'expand_abbreviation',
		'Cmd-D': 'match_pair_outward',
		'Shift-Cmd-D': 'match_pair_inward',
		'Shift-Cmd-A': 'wrap_with_abbreviation',
		'Ctrl-Alt-Right': 'next_edit_point',
		'Ctrl-Alt-Left': 'prev_edit_point',
		'Cmd-L': 'select_line',
		'Cmd-Shift-M': 'merge_lines',
		'Cmd-/': 'toggle_comment',
		'Cmd-J': 'split_join_tag',
		'Cmd-K': 'remove_tag',
		'Shift-Cmd-Y': 'evaluate_math_expression',

		'Ctrl-Up': 'increment_number_by_1',
		'Ctrl-Down': 'decrement_number_by_1',
		'Alt-Up': 'increment_number_by_01',
		'Alt-Down': 'decrement_number_by_01',
		'Ctrl-Alt-Up': 'increment_number_by_10',
		'Ctrl-Alt-Down': 'decrement_number_by_10',

		'Cmd-.': 'select_next_item',
		'Cmd-,': 'select_previous_item',
		'Cmd-B': 'reflect_css_value',

		'Enter': 'insert_formatted_line_break'
	};

	var modeMap = {
		'text/html': 'html',
		'application/xml': 'xml',
		'text/xsl': 'xsl',
		'text/css': 'css',
		'text/x-less': 'less'
	};

	if (!mac) {
		// replace Cmd modifier for non-Mac environment
		var pcKeymap = {};
		_.each(keymap, function(v, k) {
			pcKeymap[k.replace('Cmd', 'Ctrl')] = v;
		});

		keymap = pcKeymap;
	}

	// add “profile” property to CodeMirror defaults so in won’t be lost
	// then CM instance is instantiated with “profile” property
	CodeMirror.defaults.profile = 'html';

	var editorProxy = {
		context: null,

		getSelectionRange: function() {
			var caretPos = this.getCaretPos();
			return {
				start: caretPos,
				end: caretPos + this.getSelection().length
			};
		},

		createSelection: function(start, end) {
			if (start == end) {
				this.context.setCursor(this.context.posFromIndex(start));
			} else {
				this.context.setSelection(this.context.posFromIndex(start), this.context.posFromIndex(end));
			}
		},

		getCurrentLineRange: function() {
			var caret = this.context.getCursor(true);
			return {
				start: this.context.indexFromPos({line: caret.line, ch: 0}),
				end:   this.context.indexFromPos({line: caret.line, ch: this.context.getLine(caret.line).length})
			};
		},

		getCaretPos: function(){
			return this.context.indexFromPos(this.context.getCursor(true));
		},

		setCaretPos: function(pos){
			this.createSelection(pos, pos);
		},

		getCurrentLine: function() {
			return this.context.getLine( this.context.getCursor(true).line ) || '';
		},

		replaceContent: function(value, start, end, noIndent) {

			if (_.isUndefined(end))
				end = _.isUndefined(start) ? content.length : start;
			if (_.isUndefined(start)) start = 0;
			var utils = require('utils');

			// indent new value
			if (!noIndent) {
				value = utils.padString(value, utils.getLinePaddingFromPosition(this.getContent(), start));
			}

			// find new caret position
			var tabstopData = require('tabStops').extract(value, {
				escape: function(ch) {
					return ch;
				}
			});
			value = tabstopData.text;
			var firstTabStop = tabstopData.tabstops[0];

			if (firstTabStop) {
				firstTabStop.start += start;
				firstTabStop.end += start;
			} else {
				firstTabStop = {
					start: value.length + start,
					end: value.length + start
				};
			}

			// do a compound change to record all changes into single undo event
			var that = this;
			this.context.compoundChange(function() {
				that.context.replaceRange(value, that.context.posFromIndex(start), that.context.posFromIndex(end));
				that.createSelection(firstTabStop.start, firstTabStop.end);
			});
		},

		getContent: function(){
			return this.context.getValue();
		},

		getSyntax: function() {
			var syntax = this.context.getOption('mode');
			if (syntax in modeMap)
				syntax = modeMap[syntax];

			var caretPos = this.getCaretPos();

			if (!require('resources').hasSyntax(syntax))
				syntax = 'html';

			if (syntax == 'html') {
				// get the context tag
				var pair = require('html_matcher').getTags(this.getContent(), caretPos);
				if (pair && pair[0] && pair[0].type == 'tag' && pair[0].name.toLowerCase() == 'style') {
					// check that we're actually inside the tag
					if (pair[0].end <= caretPos && pair[1].start >= caretPos)
						syntax = 'css';
				}
			}

			return syntax;
		},

		/**
		 * Returns current output profile name (@see emmet#setupProfile)
		 * @return {String}
		 */
		getProfileName: function() {
			if (this.context.getOption('profile'))
				return this.context.getOption('profile');

			switch(this.getSyntax()) {
				 case 'xml':
				 case 'xsl':
				 	return 'xml';
				 case 'html':
				 	var profile = require('resources').getVariable('profile');
				 	if (!profile) { // no forced profile, guess from content
					 	// html or xhtml?
				 		profile = this.getContent().search(/<!DOCTYPE[^>]+XHTML/i) != -1 ? 'xhtml': 'html';
				 	}

				 	return profile;
			}

			return 'xhtml';
		},

		/**
		 * Ask user to enter something
		 * @param {String} title Dialog title
		 * @return {String} Entered data
		 * @since 0.65
		 */
		prompt: function(title) {
			return prompt(title);
		},

		/**
		 * Returns current selection
		 * @return {String}
		 * @since 0.65
		 */
		getSelection: function() {
			return this.context.getSelection() || '';
		},

		/**
		 * Returns current editor's file path
		 * @return {String}
		 * @since 0.65
		 */
		getFilePath: function() {
			return location.href;
		}
	};

	function setupContext(context) {
		editorProxy.context = context;
		var indentation = '\t';
		if (!context.getOption('indentWithTabs')) {
			indentation = require('utils').repeatString(' ', context.getOption('indentUnit'));
		}

		require('resources').setVariable('indentation', indentation);
	}

	function runEmmetCommand(name, editor) {
		setupContext(editor);
		try {
			require('actions').run(name, editorProxy);
			// a bit weird fix for the following action (actually, for their
			// keybindings) to prevent CM2 from inserting block characters
			if (name == 'next_edit_point' || name == 'prev_edit_point') {
				editor.replaceSelection('');
			}
			return true;
		} catch (e) {}

		throw CodeMirror.Pass;
	}

	// add keybindings to CodeMirror
	if (!CodeMirror.defaults.extraKeys)
		CodeMirror.defaults.extraKeys = {};

	_.each(keymap, function(commandName, keybinding) {

		// register Emmet command as predefined CodeMirror command
		// for latter use
		var cmCommand = 'emmet.' + commandName;
		if (!CodeMirror.commands[cmCommand]) {
			CodeMirror.commands[cmCommand] = function(editor) {
				return runEmmetCommand(commandName, editor);
			};
		}

		CodeMirror.defaults.extraKeys[keybinding] = cmCommand;
	});
});
<|endoftext|>


<commit_before>import won from "../../won-es6.js";
import Immutable from "immutable";
import { parseConnection } from "./parse-connection.js";
import { markUriAsRead, markConnUriAsClosed } from "../../won-localstorage.js";

import { markNeedAsRead } from "./reduce-needs.js";

export function storeConnectionsData(state, connectionsToStore) {
  if (connectionsToStore && connectionsToStore.size > 0) {
    connectionsToStore.forEach(connection => {
      state = addConnectionFull(state, connection);
    });
  }
  return state;
}

/**
 * Add's the connection to the needs connections.
 *
 * @param state
 * @param connection
 * @param newConnection
 * @return {*}
 */
export function addConnectionFull(state, connection) {
  let parsedConnection = parseConnection(connection);

  if (parsedConnection) {
    // console.log("parsedConnection: ", parsedConnection.toJS(), "immutable
    // ", parsedConnection);

    const needUri = parsedConnection.get("belongsToUri");
    let connections = state.getIn([needUri, "connections"]);

    if (connections) {
      const connectionUri = parsedConnection.getIn(["data", "uri"]);

      if (parsedConnection.getIn(["data", "unread"])) {
        //If there is a new message for the connection we will set the connection to newConnection
        state = state.setIn(
          [needUri, "lastUpdateDate"],
          parsedConnection.getIn(["data", "lastUpdateDate"])
        );
        state = state.setIn([needUri, "unread"], true);
      }

      if (parsedConnection.getIn(["data", "state"]) === won.WON.Closed) {
        markConnUriAsClosed(connectionUri);
      }

      return state.mergeDeepIn(
        [needUri, "connections", connectionUri],
        parsedConnection.get("data")
      );
    } else {
      console.error(
        "Couldnt add valid connection - missing need data in state",
        needUri,
        "parsedConnection: ",
        parsedConnection.toJS()
      );
    }
  } else {
    // console.log("No connection parsed, add no connection to this state:
    // ", state);
  }
  return state;
}

export function markConnectionAsRead(state, connectionUri, needUri) {
  const need = state.get(needUri);
  const connection = need && need.getIn(["connections", connectionUri]);

  markUriAsRead(connectionUri);

  if (!connection) {
    console.error(
      "no connection with connectionUri: <",
      connectionUri,
      "> found within needUri: <",
      needUri,
      ">"
    );
    return state;
  }

  state = state.setIn([needUri, "connections", connectionUri, "unread"], false);

  if (
    state.getIn([needUri, "connections"]).filter(conn => conn.get("unread"))
      .size == 0
  ) {
    state = markNeedAsRead(state, needUri);
  }

  return state;
}

export function setConnectionLoadingMessages(
  state,
  connectionUri,
  isLoadingMessages
) {
  const need = connectionUri && selectNeedByConnectionUri(state, connectionUri);
  const needUri = need && need.get("uri");
  const connection = need && need.getIn(["connections", connectionUri]);

  if (!connection) {
    console.error(
      "no connection with connectionUri: <",
      connectionUri,
      "> found within needUri: <",
      needUri,
      ">"
    );
    return state;
  }

  return state.setIn(
    [needUri, "connections", connectionUri, "isLoadingMessages"],
    isLoadingMessages
  );
}

export function setConnectionLoadingAgreementData(
  state,
  connectionUri,
  isLoadingAgreementData
) {
  const need = connectionUri && selectNeedByConnectionUri(state, connectionUri);
  const needUri = need && need.get("uri");
  const connection = need && need.getIn(["connections", connectionUri]);

  if (!connection) {
    console.error(
      "no connection with connectionUri: <",
      connectionUri,
      "> found within needUri: <",
      needUri,
      ">"
    );
    return state;
  }

  return state.setIn(
    [needUri, "connections", connectionUri, "isLoadingAgreementData"],
    isLoadingAgreementData
  );
}

export function setConnectionLoadingPetriNetData(
  state,
  connectionUri,
  isLoadingPetriNetData
) {
  const need = connectionUri && selectNeedByConnectionUri(state, connectionUri);
  const needUri = need && need.get("uri");
  const connection = need && need.getIn(["connections", connectionUri]);

  if (!connection) {
    console.error(
      "no connection with connectionUri: <",
      connectionUri,
      "> found within needUri: <",
      needUri,
      ">"
    );
    return state;
  }

  return state
    .setIn(
      [needUri, "connections", connectionUri, "petriNetData", "isDirty"],
      isLoadingPetriNetData //Assuming that there is currently a load of petriNetData in progress we flag it dirty just in case
    )
    .setIn(
      [needUri, "connections", connectionUri, "isLoadingPetriNetData"],
      isLoadingPetriNetData
    );
}

export function setPetriNetDataDirty(
  state,
  connectionUri,
  isPetriNetDataDirty
) {
  const need = connectionUri && selectNeedByConnectionUri(state, connectionUri);
  const needUri = need && need.get("uri");
  const connection = need && need.getIn(["connections", connectionUri]);

  if (!connection) {
    console.error(
      "no connection with connectionUri: <",
      connectionUri,
      "> found within needUri: <",
      needUri,
      ">"
    );
    return state;
  }

  return state.setIn(
    [needUri, "connections", connectionUri, "petriNetData", "isDirty"],
    isPetriNetDataDirty
  );
}

export function markConnectionAsRated(state, connectionUri) {
  let need = connectionUri && selectNeedByConnectionUri(state, connectionUri);
  let connection = need && need.getIn(["connections", connectionUri]);

  if (!connection) {
    console.error(
      "no connection with connectionUri: <",
      connectionUri,
      "> found within needUri: <",
      need && need.get("uri"),
      ">"
    );
    return state;
  }

  return state.setIn(
    [need.get("uri"), "connections", connectionUri, "isRated"],
    true
  );
}

/**
 * Get the need for a given connectionUri
 *
 * @param state
 *            to retrieve data from
 * @param connectionUri
 *            to find corresponding need for
 */
export function selectNeedByConnectionUri(allNeedsInState, connectionUri) {
  return allNeedsInState
    .filter(need => need.getIn(["connections", connectionUri]))
    .first();
}

export function changeConnectionState(state, connectionUri, newState) {
  const need = selectNeedByConnectionUri(state, connectionUri);

  if (!need) {
    console.error("no need found for connectionUri", connectionUri);
    return state;
  }

  const needUri = need.get("uri");

  if (newState === won.WON.Closed) {
    markConnUriAsClosed(connectionUri);
  }

  return state
    .setIn([needUri, "connections", connectionUri, "state"], newState)
    .setIn([needUri, "connections", connectionUri, "unread"], true);
}

export function changeConnectionStateByFun(state, connectionUri, fun) {
  const need = selectNeedByConnectionUri(state, connectionUri);

  if (!need) {
    console.error("no need found for connectionUri", connectionUri);
    return state;
  }

  const needUri = need.get("uri");
  const connectionState = state.getIn([
    needUri,
    "connections",
    connectionUri,
    "state",
  ]);

  return changeConnectionState(state, connectionUri, fun(connectionState));
}

export function updatePetriNetStateData(state, connectionUri, petriNetData) {
  const need = selectNeedByConnectionUri(state, connectionUri);

  if (!need || !petriNetData) {
    console.error(
      "no need found for connectionUri",
      connectionUri,
      " or no petriNetData present"
    );
    return state;
  }

  const needUri = need.get("uri");

  return state
    .setIn(
      [needUri, "connections", connectionUri, "petriNetData", "data"],
      petriNetData
    )
    .setIn(
      [needUri, "connections", connectionUri, "petriNetData", "isLoaded"],
      true
    )
    .setIn(
      [needUri, "connections", connectionUri, "petriNetData", "isDirty"],
      false
    )
    .setIn(
      [needUri, "connections", connectionUri, "isLoadingPetriNetData"],
      false
    );
}

export function updateAgreementStateData(state, connectionUri, agreementData) {
  const need = selectNeedByConnectionUri(state, connectionUri);

  if (!need || !agreementData) {
    console.error(
      "no need found for connectionUri",
      connectionUri,
      " or no agreementData present"
    );
    return state;
  }

  const needUri = need.get("uri");

  return state
    .setIn(
      [needUri, "connections", connectionUri, "agreementData"],
      agreementData
    )
    .setIn(
      [needUri, "connections", connectionUri, "agreementData", "isLoaded"],
      true
    )
    .setIn(
      [needUri, "connections", connectionUri, "isLoadingAgreementData"],
      false
    );
}

export function setShowAgreementData(state, connectionUri, showAgreementData) {
  const need = selectNeedByConnectionUri(state, connectionUri);

  if (!need) {
    console.error("no need found for connectionUri", connectionUri);
    return state;
  }

  const needUri = need.get("uri");

  return state.setIn(
    [needUri, "connections", connectionUri, "showAgreementData"],
    showAgreementData
  );
}

export function setShowPetriNetData(state, connectionUri, showPetriNetData) {
  const need = selectNeedByConnectionUri(state, connectionUri);

  if (!need) {
    console.error("no need found for connectionUri", connectionUri);
    return state;
  }

  const needUri = need.get("uri");

  return state.setIn(
    [needUri, "connections", connectionUri, "showPetriNetData"],
    showPetriNetData
  );
}

export function setMultiSelectType(
  state,
  connectionUri,
  multiSelectType = undefined
) {
  const need = selectNeedByConnectionUri(state, connectionUri);

  if (!need) {
    console.error("no need found for connectionUri", connectionUri);
    return state;
  }

  const needUri = need.get("uri");

  let messages = state.getIn([
    needUri,
    "connections",
    connectionUri,
    "messages",
  ]);

  if (!multiSelectType) {
    messages = messages.map(msg => {
      msg = msg.setIn(["viewState", "isSelected"], false);
      return msg;
    });
    state = state.setIn(
      [needUri, "connections", connectionUri, "messages"],
      messages
    );
    state = state.setIn(
      [needUri, "connections", connectionUri, "multiSelectType"],
      undefined
    );
  } else {
    state = state.setIn(
      [needUri, "connections", connectionUri, "multiSelectType"],
      multiSelectType
    );
  }

  return state;
}

export function addActiveConnectionsToNeedInLoading(state, needUri, connUris) {
  needUri &&
    connUris &&
    connUris.size > 0 &&
    console.log("addActiveConnectionsToNeedInLoading: ", connUris);
  let newState = state;
  needUri &&
    connUris &&
    connUris.forEach(connUri => {
      newState = addActiveConnectionToNeed(newState, needUri, connUri);
    });
  return newState;
}

export function addActiveConnectionToNeed(state, needUri, connUri) {
  const storedNeed = state.get(needUri);
  const isConnectionPresent =
    storedNeed && !!storedNeed.getIn(["connections", connUri]);

  if (storedNeed && !isConnectionPresent) {
    const connection = Immutable.fromJS({
      uri: connUri,
      state: undefined,
      messages: Immutable.Map(),
      agreementData: undefined,
      remoteNeedUri: undefined,
      remoteConnectionUri: undefined,
      creationDate: undefined,
      lastUpdateDate: undefined,
      unread: undefined,
      isRated: false,
      isLoadingMessages: false,
      isLoading: true,
      showAgreementData: false,
    });

    return state.mergeDeepIn([needUri, "connections", connUri], connection);
  }

  return state;
}
<commit_msg>Add Facet Handling for every addedConnection (as soon as reduce-connection is called, we update both needs depending on the facet (persona <-> need connection, heldBy/holds update) so we do not have to reretrieve the needs)<commit_after>import won from "../../won-es6.js";
import Immutable from "immutable";
import { parseConnection } from "./parse-connection.js";
import { markUriAsRead, markConnUriAsClosed } from "../../won-localstorage.js";

import { markNeedAsRead } from "./reduce-needs.js";

export function storeConnectionsData(state, connectionsToStore) {
  if (connectionsToStore && connectionsToStore.size > 0) {
    connectionsToStore.forEach(connection => {
      state = addConnectionFull(state, connection);
    });
  }
  return state;
}

/**
 * Add's the connection to the needs connections.
 *
 * @param state
 * @param connection
 * @param newConnection
 * @return {*}
 */
export function addConnectionFull(state, connection) {
  let parsedConnection = parseConnection(connection);

  if (parsedConnection) {
    // console.log("parsedConnection: ", parsedConnection.toJS(), "immutable", parsedConnection);

    const needUri = parsedConnection.get("belongsToUri");
    let connections = state.getIn([needUri, "connections"]);

    if (connections) {
      const connectionUri = parsedConnection.getIn(["data", "uri"]);

      const facet = parsedConnection.getIn(["data", "facet"]);

      if (facet === "holderFacet") {
        const holdsUri = parsedConnection.getIn(["data", "remoteNeedUri"]);
        console.log(
          "Handling a holderFacet-connection within need: ",
          needUri,
          " setting holds to holdsUri: ",
          holdsUri
        );

        if (holdsUri) {
          const currentHolds = state.getIn([needUri, "holds"]);
          if (currentHolds && !currentHolds.includes(holdsUri)) {
            state = state.updateIn([needUri, "holds"], holdsList =>
              holdsList.push(holdsUri)
            );
          }

          //ToDo: Not sure if we should add this to the remoteNeed here
          const currentHoldsNeed = state.get("holdsUri");
          if (currentHoldsNeed) {
            state = state.setIn([holdsUri, "heldBy"], needUri);
          }
        }
      } else if (facet === "holdableFacet") {
        //holdableFacet Connection from need to persona -> need to add heldBy remoteNeedUri to the need
        const heldByUri = parsedConnection.getIn(["data", "remoteNeedUri"]);
        console.log(
          "Handling a holdableFacet-connection within need: ",
          needUri,
          " setting heldBy to heldByUri: ",
          heldByUri
        );

        if (heldByUri) {
          state = state.setIn([needUri, "heldBy"], heldByUri);
        }

        //ToDo: Not sure if we should add this to the remoteNeed here
        const currentHolds = state.getIn([heldByUri, "holds"]);
        if (currentHolds && !currentHolds.includes(needUri)) {
          state = state.updateIn([heldByUri, "holds"], holdsList =>
            holdsList.push(needUri)
          );
        }
      } else if (facet !== "chatFacet") {
        console.warn("Unknown Facet(", facet, ") do not add Connection");
        return state;
      }

      if (parsedConnection.getIn(["data", "unread"])) {
        //If there is a new message for the connection we will set the connection to newConnection
        state = state.setIn(
          [needUri, "lastUpdateDate"],
          parsedConnection.getIn(["data", "lastUpdateDate"])
        );
        state = state.setIn([needUri, "unread"], true);
      }

      if (parsedConnection.getIn(["data", "state"]) === won.WON.Closed) {
        markConnUriAsClosed(connectionUri);
      }

      return state.mergeDeepIn(
        [needUri, "connections", connectionUri],
        parsedConnection.get("data")
      );
    } else {
      console.error(
        "Couldnt add valid connection - missing need data in state",
        needUri,
        "parsedConnection: ",
        parsedConnection.toJS()
      );
    }
  } else {
    // console.log("No connection parsed, add no connection to this state:
    // ", state);
  }
  return state;
}

export function markConnectionAsRead(state, connectionUri, needUri) {
  const need = state.get(needUri);
  const connection = need && need.getIn(["connections", connectionUri]);

  markUriAsRead(connectionUri);

  if (!connection) {
    console.error(
      "no connection with connectionUri: <",
      connectionUri,
      "> found within needUri: <",
      needUri,
      ">"
    );
    return state;
  }

  state = state.setIn([needUri, "connections", connectionUri, "unread"], false);

  if (
    state.getIn([needUri, "connections"]).filter(conn => conn.get("unread"))
      .size == 0
  ) {
    state = markNeedAsRead(state, needUri);
  }

  return state;
}

export function setConnectionLoadingMessages(
  state,
  connectionUri,
  isLoadingMessages
) {
  const need = connectionUri && selectNeedByConnectionUri(state, connectionUri);
  const needUri = need && need.get("uri");
  const connection = need && need.getIn(["connections", connectionUri]);

  if (!connection) {
    console.error(
      "no connection with connectionUri: <",
      connectionUri,
      "> found within needUri: <",
      needUri,
      ">"
    );
    return state;
  }

  return state.setIn(
    [needUri, "connections", connectionUri, "isLoadingMessages"],
    isLoadingMessages
  );
}

export function setConnectionLoadingAgreementData(
  state,
  connectionUri,
  isLoadingAgreementData
) {
  const need = connectionUri && selectNeedByConnectionUri(state, connectionUri);
  const needUri = need && need.get("uri");
  const connection = need && need.getIn(["connections", connectionUri]);

  if (!connection) {
    console.error(
      "no connection with connectionUri: <",
      connectionUri,
      "> found within needUri: <",
      needUri,
      ">"
    );
    return state;
  }

  return state.setIn(
    [needUri, "connections", connectionUri, "isLoadingAgreementData"],
    isLoadingAgreementData
  );
}

export function setConnectionLoadingPetriNetData(
  state,
  connectionUri,
  isLoadingPetriNetData
) {
  const need = connectionUri && selectNeedByConnectionUri(state, connectionUri);
  const needUri = need && need.get("uri");
  const connection = need && need.getIn(["connections", connectionUri]);

  if (!connection) {
    console.error(
      "no connection with connectionUri: <",
      connectionUri,
      "> found within needUri: <",
      needUri,
      ">"
    );
    return state;
  }

  return state
    .setIn(
      [needUri, "connections", connectionUri, "petriNetData", "isDirty"],
      isLoadingPetriNetData //Assuming that there is currently a load of petriNetData in progress we flag it dirty just in case
    )
    .setIn(
      [needUri, "connections", connectionUri, "isLoadingPetriNetData"],
      isLoadingPetriNetData
    );
}

export function setPetriNetDataDirty(
  state,
  connectionUri,
  isPetriNetDataDirty
) {
  const need = connectionUri && selectNeedByConnectionUri(state, connectionUri);
  const needUri = need && need.get("uri");
  const connection = need && need.getIn(["connections", connectionUri]);

  if (!connection) {
    console.error(
      "no connection with connectionUri: <",
      connectionUri,
      "> found within needUri: <",
      needUri,
      ">"
    );
    return state;
  }

  return state.setIn(
    [needUri, "connections", connectionUri, "petriNetData", "isDirty"],
    isPetriNetDataDirty
  );
}

export function markConnectionAsRated(state, connectionUri) {
  let need = connectionUri && selectNeedByConnectionUri(state, connectionUri);
  let connection = need && need.getIn(["connections", connectionUri]);

  if (!connection) {
    console.error(
      "no connection with connectionUri: <",
      connectionUri,
      "> found within needUri: <",
      need && need.get("uri"),
      ">"
    );
    return state;
  }

  return state.setIn(
    [need.get("uri"), "connections", connectionUri, "isRated"],
    true
  );
}

/**
 * Get the need for a given connectionUri
 *
 * @param state
 *            to retrieve data from
 * @param connectionUri
 *            to find corresponding need for
 */
export function selectNeedByConnectionUri(allNeedsInState, connectionUri) {
  return allNeedsInState
    .filter(need => need.getIn(["connections", connectionUri]))
    .first();
}

export function changeConnectionState(state, connectionUri, newState) {
  const need = selectNeedByConnectionUri(state, connectionUri);

  if (!need) {
    console.error("no need found for connectionUri", connectionUri);
    return state;
  }

  const needUri = need.get("uri");

  if (newState === won.WON.Closed) {
    markConnUriAsClosed(connectionUri);
  }

  return state
    .setIn([needUri, "connections", connectionUri, "state"], newState)
    .setIn([needUri, "connections", connectionUri, "unread"], true);
}

export function changeConnectionStateByFun(state, connectionUri, fun) {
  const need = selectNeedByConnectionUri(state, connectionUri);

  if (!need) {
    console.error("no need found for connectionUri", connectionUri);
    return state;
  }

  const needUri = need.get("uri");
  const connectionState = state.getIn([
    needUri,
    "connections",
    connectionUri,
    "state",
  ]);

  return changeConnectionState(state, connectionUri, fun(connectionState));
}

export function updatePetriNetStateData(state, connectionUri, petriNetData) {
  const need = selectNeedByConnectionUri(state, connectionUri);

  if (!need || !petriNetData) {
    console.error(
      "no need found for connectionUri",
      connectionUri,
      " or no petriNetData present"
    );
    return state;
  }

  const needUri = need.get("uri");

  return state
    .setIn(
      [needUri, "connections", connectionUri, "petriNetData", "data"],
      petriNetData
    )
    .setIn(
      [needUri, "connections", connectionUri, "petriNetData", "isLoaded"],
      true
    )
    .setIn(
      [needUri, "connections", connectionUri, "petriNetData", "isDirty"],
      false
    )
    .setIn(
      [needUri, "connections", connectionUri, "isLoadingPetriNetData"],
      false
    );
}

export function updateAgreementStateData(state, connectionUri, agreementData) {
  const need = selectNeedByConnectionUri(state, connectionUri);

  if (!need || !agreementData) {
    console.error(
      "no need found for connectionUri",
      connectionUri,
      " or no agreementData present"
    );
    return state;
  }

  const needUri = need.get("uri");

  return state
    .setIn(
      [needUri, "connections", connectionUri, "agreementData"],
      agreementData
    )
    .setIn(
      [needUri, "connections", connectionUri, "agreementData", "isLoaded"],
      true
    )
    .setIn(
      [needUri, "connections", connectionUri, "isLoadingAgreementData"],
      false
    );
}

export function setShowAgreementData(state, connectionUri, showAgreementData) {
  const need = selectNeedByConnectionUri(state, connectionUri);

  if (!need) {
    console.error("no need found for connectionUri", connectionUri);
    return state;
  }

  const needUri = need.get("uri");

  return state.setIn(
    [needUri, "connections", connectionUri, "showAgreementData"],
    showAgreementData
  );
}

export function setShowPetriNetData(state, connectionUri, showPetriNetData) {
  const need = selectNeedByConnectionUri(state, connectionUri);

  if (!need) {
    console.error("no need found for connectionUri", connectionUri);
    return state;
  }

  const needUri = need.get("uri");

  return state.setIn(
    [needUri, "connections", connectionUri, "showPetriNetData"],
    showPetriNetData
  );
}

export function setMultiSelectType(
  state,
  connectionUri,
  multiSelectType = undefined
) {
  const need = selectNeedByConnectionUri(state, connectionUri);

  if (!need) {
    console.error("no need found for connectionUri", connectionUri);
    return state;
  }

  const needUri = need.get("uri");

  let messages = state.getIn([
    needUri,
    "connections",
    connectionUri,
    "messages",
  ]);

  if (!multiSelectType) {
    messages = messages.map(msg => {
      msg = msg.setIn(["viewState", "isSelected"], false);
      return msg;
    });
    state = state.setIn(
      [needUri, "connections", connectionUri, "messages"],
      messages
    );
    state = state.setIn(
      [needUri, "connections", connectionUri, "multiSelectType"],
      undefined
    );
  } else {
    state = state.setIn(
      [needUri, "connections", connectionUri, "multiSelectType"],
      multiSelectType
    );
  }

  return state;
}

export function addActiveConnectionsToNeedInLoading(state, needUri, connUris) {
  needUri &&
    connUris &&
    connUris.size > 0 &&
    console.log("addActiveConnectionsToNeedInLoading: ", connUris);
  let newState = state;
  needUri &&
    connUris &&
    connUris.forEach(connUri => {
      newState = addActiveConnectionToNeed(newState, needUri, connUri);
    });
  return newState;
}

export function addActiveConnectionToNeed(state, needUri, connUri) {
  const storedNeed = state.get(needUri);
  const isConnectionPresent =
    storedNeed && !!storedNeed.getIn(["connections", connUri]);

  if (storedNeed && !isConnectionPresent) {
    const connection = Immutable.fromJS({
      uri: connUri,
      state: undefined,
      messages: Immutable.Map(),
      agreementData: undefined,
      remoteNeedUri: undefined,
      remoteConnectionUri: undefined,
      creationDate: undefined,
      lastUpdateDate: undefined,
      unread: undefined,
      isRated: false,
      isLoadingMessages: false,
      isLoading: true,
      showAgreementData: false,
    });

    return state.mergeDeepIn([needUri, "connections", connUri], connection);
  }

  return state;
}
<|endoftext|>


<commit_before>/*!
 * EventEmitter v4.2.0 - git.io/ee
 * Oliver Caldwell
 * MIT license
 * @preserve
 */
!function(){"use strict";function t(){}function n(t,n){for(var e=t.length;e--;)if(t[e].listener===n)return e;return-1}var e=t.prototype;e._getEvents=function(){return this._events||(this._events={})},e.getListeners=function(n){var r,e,t=this._getEvents();if("object"==typeof n){r={};for(e in t)t.hasOwnProperty(e)&&n.test(e)&&(r[e]=t[e])}else r=t[n]||(t[n]=[]);return r},e.flattenListeners=function(t){var e,n=[];for(e=0;e<t.length;e+=1)n.push(t[e].listener);return n},e.getListenersAsObject=function(n){var e,t=this.getListeners(n);return t instanceof Array&&(e={},e[n]=t),e||t},e.addListener=function(i,e){var t,r=this.getListenersAsObject(i),s="object"==typeof e;for(t in r)r.hasOwnProperty(t)&&-1===n(r[t],e)&&r[t].push(s?e:{listener:e,once:!1});return this},e.on=e.addListener,e.addOnceListener=function(e,t){return this.addListener(e,{listener:t,once:!0})},e.once=e.addOnceListener,e.defineEvent=function(e){return this.getListeners(e),this},e.defineEvents=function(t){for(var e=0;e<t.length;e+=1)this.defineEvent(t[e]);return this},e.removeListener=function(i,s){var r,e,t=this.getListenersAsObject(i);for(e in t)t.hasOwnProperty(e)&&(r=n(t[e],s),-1!==r&&t[e].splice(r,1));return this},e.off=e.removeListener,e.addListeners=function(e,t){return this.manipulateListeners(!1,e,t)},e.removeListeners=function(e,t){return this.manipulateListeners(!0,e,t)},e.manipulateListeners=function(r,t,i){var e,n,s=r?this.removeListener:this.addListener,o=r?this.removeListeners:this.addListeners;if("object"!=typeof t||t instanceof RegExp)for(e=i.length;e--;)s.call(this,t,i[e]);else for(e in t)t.hasOwnProperty(e)&&(n=t[e])&&("function"==typeof n?s.call(this,e,n):o.call(this,e,n));return this},e.removeEvent=function(n){var e,r=typeof n,t=this._getEvents();if("string"===r)delete t[n];else if("object"===r)for(e in t)t.hasOwnProperty(e)&&n.test(e)&&delete t[e];else delete this._events;return this},e.emitEvent=function(i,o){var r,n,e,s,t=this.getListenersAsObject(i);for(e in t)if(t.hasOwnProperty(e))for(n=t[e].length;n--;)r=t[e][n],s=r.listener.apply(this,o||[]),(s===this._getOnceReturnValue()||r.once===!0)&&this.removeListener(i,t[e][n].listener);return this},e.trigger=e.emitEvent,e.emit=function(e){var t=Array.prototype.slice.call(arguments,1);return this.emitEvent(e,t)},e.setOnceReturnValue=function(e){return this._onceReturnValue=e,this},e._getOnceReturnValue=function(){return this.hasOwnProperty("_onceReturnValue")?this._onceReturnValue:!0},"function"==typeof define&&define.amd?define(function(){return t}):"undefined"!=typeof module&&module.exports?module.exports=t:this.EventEmitter=t}.call(this);<commit_msg>Yet another build.<commit_after>/*!
 * EventEmitter v4.2.0 - git.io/ee
 * Oliver Caldwell
 * MIT license
 * @preserve
 */
!function(){"use strict";function t(){}function n(t,n){for(var e=t.length;e--;)if(t[e].listener===n)return e;return-1}var e=t.prototype;e.getListeners=function(n){var r,e,t=this._getEvents();if("object"==typeof n){r={};for(e in t)t.hasOwnProperty(e)&&n.test(e)&&(r[e]=t[e])}else r=t[n]||(t[n]=[]);return r},e.flattenListeners=function(t){var e,n=[];for(e=0;e<t.length;e+=1)n.push(t[e].listener);return n},e.getListenersAsObject=function(n){var e,t=this.getListeners(n);return t instanceof Array&&(e={},e[n]=t),e||t},e.addListener=function(i,e){var t,r=this.getListenersAsObject(i),s="object"==typeof e;for(t in r)r.hasOwnProperty(t)&&-1===n(r[t],e)&&r[t].push(s?e:{listener:e,once:!1});return this},e.on=e.addListener,e.addOnceListener=function(e,t){return this.addListener(e,{listener:t,once:!0})},e.once=e.addOnceListener,e.defineEvent=function(e){return this.getListeners(e),this},e.defineEvents=function(t){for(var e=0;e<t.length;e+=1)this.defineEvent(t[e]);return this},e.removeListener=function(i,s){var r,e,t=this.getListenersAsObject(i);for(e in t)t.hasOwnProperty(e)&&(r=n(t[e],s),-1!==r&&t[e].splice(r,1));return this},e.off=e.removeListener,e.addListeners=function(e,t){return this.manipulateListeners(!1,e,t)},e.removeListeners=function(e,t){return this.manipulateListeners(!0,e,t)},e.manipulateListeners=function(r,t,i){var e,n,s=r?this.removeListener:this.addListener,o=r?this.removeListeners:this.addListeners;if("object"!=typeof t||t instanceof RegExp)for(e=i.length;e--;)s.call(this,t,i[e]);else for(e in t)t.hasOwnProperty(e)&&(n=t[e])&&("function"==typeof n?s.call(this,e,n):o.call(this,e,n));return this},e.removeEvent=function(n){var e,r=typeof n,t=this._getEvents();if("string"===r)delete t[n];else if("object"===r)for(e in t)t.hasOwnProperty(e)&&n.test(e)&&delete t[e];else delete this._events;return this},e.emitEvent=function(i,o){var r,n,e,s,t=this.getListenersAsObject(i);for(e in t)if(t.hasOwnProperty(e))for(n=t[e].length;n--;)r=t[e][n],s=r.listener.apply(this,o||[]),(s===this._getOnceReturnValue()||r.once===!0)&&this.removeListener(i,t[e][n].listener);return this},e.trigger=e.emitEvent,e.emit=function(e){var t=Array.prototype.slice.call(arguments,1);return this.emitEvent(e,t)},e.setOnceReturnValue=function(e){return this._onceReturnValue=e,this},e._getOnceReturnValue=function(){return this.hasOwnProperty("_onceReturnValue")?this._onceReturnValue:!0},e._getEvents=function(){return this._events||(this._events={})},"function"==typeof define&&define.amd?define(function(){return t}):"undefined"!=typeof module&&module.exports?module.exports=t:this.EventEmitter=t}.call(this);<|endoftext|>


<commit_before>// Import the APIs we need.

var pageMod = require("page-mod");
var Request = require("request").Request;
var notifications = require("notifications");
var self = require("self");
var tabs = require("tabs");
var ss = require("simple-storage");
var workers = [];
var contextMenu = require("context-menu");
var priv = require("private-browsing");
var windows = require("sdk/windows").browserWindows;

// require chrome allows us to use XPCOM objects...
const {Cc, Ci, Cu, Cr} = require("chrome");

var historyService = Cc["@mozilla.org/browser/history;1"].getService(Ci.mozIAsyncHistory);

// this function takes in a string (and optional charset, paseURI) and creates an nsURI object, which is required by historyService.addURI...
function makeURI(aURL, aOriginCharset, aBaseURI) {
	var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
	return ioService.newURI(aURL, aOriginCharset, aBaseURI);
}

function detachWorker(worker, workerArray) {
	var index = workerArray.indexOf(worker);
	if(index != -1) {
		workerArray.splice(index, 1);
	}
}
var localStorage = ss.storage;

// these aliases are just for simplicity, so that the code here looks just like background code
// for all of the other browsers...
localStorage.getItem = function(key) {
	return ss.storage[key];
};
localStorage.setItem = function(key, value) {
	ss.storage[key] = value;
};
localStorage.removeItem = function(key) {
	delete ss.storage[key];
};

pageMod.PageMod({
  include: ["*.babelext.com"],
  contentScriptWhen: 'ready',
  contentScriptFile: [self.data.url('BabelExt.js'), self.data.url('extension.js')],
  onAttach: function(worker) {
	tabs.on('activate', function(tab) {
		// run some code when a tab is activated...
	});

	workers.push(worker);
	worker.on('detach', function () {
		detachWorker(this, workers);
		// console.log('worker detached, total now: ' + workers.length);
    });

	worker.on('message', function(data) {
		var request = data;
		switch(request.requestType) {
			case 'xmlhttpRequest':
				var responseObj = {
					callbackID: request.callbackID,
					name: request.requestType
				};
				if (request.method == 'POST') {
					Request({
						url: request.url,
						onComplete: function(response) {
							responseObj.response = {
								responseText: response.text,
								status: response.status
							};
							worker.postMessage(responseObj);
						},
						headers: request.headers,
						content: request.data
					}).post();
				} else {
					Request({
						url: request.url,
						onComplete: function(response) {
							responseObj.response = {
								responseText: response.text,
								status: response.status
							};
							worker.postMessage(responseObj);
						},
						headers: request.headers,
						content: request.data
					}).get();
				}
				break;
			case 'createTab':
				var focus = (request.background !== true);
				tabs.open({url: request.url, inBackground: !focus });
				worker.postMessage({status: "success"});
				break;
			case 'createNotification':
				if (!request.icon) {
					// if no icon specified, make a single pixel empty gif so we don't get a broken image link.
					request.icon = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==';
				}
				notifications.notify({
					title: request.title,
					text: request.text,
					iconURL: request.icon
				});
				break;
			case 'localStorage':
				switch (request.operation) {
					case 'getItem':
						worker.postMessage({
							name: 'localStorage',
							callbackID: request.callbackID,
							status: true,
							key: request.itemName,
							value: localStorage.getItem(request.itemName)
						});
						break;
					case 'removeItem':
						localStorage.removeItem(request.itemName);
						worker.postMessage({
							name: 'localStorage',
							callbackID: request.callbackID,
							status: true,
							value: null
						});
						break;
					case 'setItem':
						localStorage.setItem(request.itemName, request.itemValue);
						worker.postMessage({
							name: 'localStorage',
							callbackID: request.callbackID,
							status: true,
							key: request.itemName,
							value: request.itemValue
						});
						break;
				}
				break;
			case 'addURLToHistory':
				var isPrivate = priv.isPrivate(windows.activeWindow);
				if (isPrivate) {
					// do not add to history if in private browsing mode!
					return false;
				}
				var uri = makeURI(request.url);
				historyService.updatePlaces({
					uri: uri,
					visits: [{
						transitionType: Ci.nsINavHistoryService.TRANSITION_LINK,
						visitDate: Date.now() * 1000
					}]
				});
				break;
			case 'contextMenus.create':
				contextMenu.Item({
					label: request.obj.title,
					context: contextMenu.PageContext(),
					data: request.obj.onclick,
					contentScript: 'self.on("click", function (node, data) {' +
									'self.postMessage(data);' +
									'});',
					onMessage: function(onclick) {
						worker.postMessage({
							name: 'contextMenus.click',
							callbackID: onclick
						});
					}

				});
				break;
			default:
				worker.postMessage({status: "unrecognized request type"});
				break;
		}

	});
  }
});
<commit_msg>namespace changes for new firefox SDK and support for contextMenu.remove.<commit_after>// Import the APIs we need.

var pageMod = require("sdk/page-mod");
var Request = require("sdk/request").Request;
var notifications = require("sdk/notifications");
var self = require("sdk/self");
var tabs = require("sdk/tabs");
var ss = require("sdk/simple-storage");
var workers = [];
var contextMenu = require("sdk/context-menu");
var priv = require("sdk/private-browsing");
var windows = require("sdk/windows").browserWindows;

// require chrome allows us to use XPCOM objects...
const {Cc, Ci, Cu, Cr} = require("chrome");

var historyService = Cc["@mozilla.org/browser/history;1"].getService(Ci.mozIAsyncHistory);

// this function takes in a string (and optional charset, paseURI) and creates an nsURI object, which is required by historyService.addURI...
function makeURI(aURL, aOriginCharset, aBaseURI) {
	var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
	return ioService.newURI(aURL, aOriginCharset, aBaseURI);
}

function detachWorker(worker, workerArray) {
	var index = workerArray.indexOf(worker);
	if(index != -1) {
		workerArray.splice(index, 1);
	}
}
var localStorage = ss.storage;

// these aliases are just for simplicity, so that the code here looks just like background code
// for all of the other browsers...
localStorage.getItem = function(key) {
	return ss.storage[key];
};
localStorage.setItem = function(key, value) {
	ss.storage[key] = value;
};
localStorage.removeItem = function(key) {
	delete ss.storage[key];
};

pageMod.PageMod({
  include: ["*.babelext.com"],
  contentScriptWhen: 'ready',
  contentScriptFile: [self.data.url('BabelExt.js'), self.data.url('extension.js')],
  onAttach: function(worker) {
	tabs.on('activate', function(tab) {
		// run some code when a tab is activated...
	});

	workers.push(worker);
	worker.on('detach', function () {
		detachWorker(this, workers);
		// console.log('worker detached, total now: ' + workers.length);
    });

	worker.on('message', function(data) {
		var request = data;
		switch(request.requestType) {
			case 'xmlhttpRequest':
				var responseObj = {
					callbackID: request.callbackID,
					name: request.requestType
				};
				if (request.method == 'POST') {
					Request({
						url: request.url,
						onComplete: function(response) {
							responseObj.response = {
								responseText: response.text,
								status: response.status
							};
							worker.postMessage(responseObj);
						},
						headers: request.headers,
						content: request.data
					}).post();
				} else {
					Request({
						url: request.url,
						onComplete: function(response) {
							responseObj.response = {
								responseText: response.text,
								status: response.status
							};
							worker.postMessage(responseObj);
						},
						headers: request.headers,
						content: request.data
					}).get();
				}
				break;
			case 'createTab':
				var focus = (request.background !== true);
				tabs.open({url: request.url, inBackground: !focus });
				worker.postMessage({status: "success"});
				break;
			case 'createNotification':
				if (!request.icon) {
					// if no icon specified, make a single pixel empty gif so we don't get a broken image link.
					request.icon = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==';
				}
				notifications.notify({
					title: request.title,
					text: request.text,
					iconURL: request.icon
				});
				break;
			case 'localStorage':
				switch (request.operation) {
					case 'getItem':
						worker.postMessage({
							name: 'localStorage',
							callbackID: request.callbackID,
							status: true,
							key: request.itemName,
							value: localStorage.getItem(request.itemName)
						});
						break;
					case 'removeItem':
						localStorage.removeItem(request.itemName);
						worker.postMessage({
							name: 'localStorage',
							callbackID: request.callbackID,
							status: true,
							value: null
						});
						break;
					case 'setItem':
						localStorage.setItem(request.itemName, request.itemValue);
						worker.postMessage({
							name: 'localStorage',
							callbackID: request.callbackID,
							status: true,
							key: request.itemName,
							value: request.itemValue
						});
						break;
				}
				break;
			case 'addURLToHistory':
				var isPrivate = priv.isPrivate(windows.activeWindow);
				if (isPrivate) {
					// do not add to history if in private browsing mode!
					return false;
				}
				var uri = makeURI(request.url);
				historyService.updatePlaces({
					uri: uri,
					visits: [{
						transitionType: Ci.nsINavHistoryService.TRANSITION_LINK,
						visitDate: Date.now() * 1000
					}]
				});
				break;
			case 'contextMenus.create':
				contextMenu.Item({
					label: request.obj.title,
					context: contextMenu.PageContext(),
					data: request.obj.onclick,
					contentScript: 'self.on("click", function (node, data) {' +
									'self.postMessage(data);' +
									'});',
					onMessage: function(onclick) {
						worker.postMessage({
							name: 'contextMenus.click',
							callbackID: onclick
						});
					}

				});
				break;
			case 'contextMenus.remove':
				// Run through the current context items and destroy the one with a matching name
				contextItems = contextMenu.contentContextMenu.items;
				var len = contextItems.length;
				for(var i =0; i < len; ++i){
					if(request.obj.title == contextItems[i].label){
						contextMenu.contentContextMenu.destroy(contextItems[i]);
						break;
					}
				}

				break;
			default:
				worker.postMessage({status: "unrecognized request type"});
				break;
		}

	});
  }
});
<|endoftext|>


<commit_before>// ==========================================================================
//                          DG.GraphController
//
//  Author:   William Finzer
//
//  Copyright (c) 2014 by The Concord Consortium, Inc. All rights reserved.
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
// ==========================================================================

sc_require('components/graph_map_common/data_display_controller');

/** @class

    DG.GraphController provides controller functionality, particular gear menu items,
 for graphs.

 @extends SC.DataDisplayController
 */
DG.GraphController = DG.DataDisplayController.extend(
    /** @scope DG.GraphController.prototype */
    (function () {

      function getCollectionClientFromDragData(iContext, iDragData) {
        var collectionID = iDragData.collection && iDragData.collection.get('id');
        return iContext && !SC.none(collectionID) && iContext.getCollectionByID(collectionID);
      }

      return {
        graphModel: function () {
          return this.get('dataDisplayModel');
        }.property('dataDisplayModel'),
        xAxisView: null,
        yAxisView: null,
        y2AxisView: null,
        plotView: null,
        axisMultiTarget: null,

        createComponentStorage: function () {
          var storage = sc_super(),
              dataConfiguration = this.getPath('graphModel.dataConfiguration'),
              plotModels = this.getPath('graphModel.plots');

          var storeAxis = function (iDim) {
            var tAxis = this.getPath('graphModel.' + iDim + 'Axis');
            if (tAxis)
              storage[iDim + 'AxisClass'] = String(tAxis.constructor);
            if (tAxis && tAxis.get('isNumeric')) {
              storage[iDim + 'LowerBound'] = tAxis.get('lowerBound');
              storage[iDim + 'UpperBound'] = tAxis.get('upperBound');
            }
          }.bind(this);

          storage.isTransparent = this.getPath('graphModel.isTransparent');

          this.storeDimension(dataConfiguration, storage, 'x');
          this.storeDimension(dataConfiguration, storage, 'y');
          this.storeDimension(dataConfiguration, storage, 'y2');

          storeAxis('x');
          storeAxis('y');
          storeAxis('y2');

          if (plotModels) {
            storage.plotModels = [];
            plotModels.forEach(function (iPlot) {
              storage.plotModels.push({
                plotModelStorage: iPlot.createStorage(),
                plotClass: String(iPlot.constructor)
              });
            });
          }

          return storage;
        },

        restoreComponentStorage: function (iStorage, iDocumentID) {
          var graphModel = this.get('dataDisplayModel');

          sc_super();

          if (SC.none(iStorage._links_))
            return; // We don't support the older format 0096 and before. Just bring up the default graph
                    // that we already have.

          graphModel.restoreStorage(iStorage);

          // There may be some animations that have been set up. We have to stop them so that changes
          // we make below (e.g. to axis bounds) will stick.
          graphModel.stopAnimation();

          // Older versions had a single plotModelStorage, so we make ourselves backward compatible
          if (iStorage.plotModelStorage) {
            var plotModel = graphModel.get('plot');
            if (plotModel)
              plotModel.restoreStorage(iStorage.plotModelStorage);
          }
          // Newer versions always store an array of plot models even if there is only one.
          else if (iStorage.plotModels) {
            var tPlots = graphModel.get('plots');
            tPlots.forEach(function (iPlot, iIndex) {
              iPlot.restoreStorage(iStorage.plotModels[iIndex].plotModelStorage);
            });
          }

          // Configure the axes
          var xAxis = graphModel.get('xAxis'),
              yAxis = graphModel.get('yAxis');
          if (xAxis && xAxis.get('isNumeric') &&
              isFinite(iStorage.xLowerBound) && isFinite(iStorage.xUpperBound)) {
            xAxis.setLowerAndUpperBounds(iStorage.xLowerBound, iStorage.xUpperBound);
          }
          if (yAxis && yAxis.get('isNumeric') &&
              isFinite(iStorage.yLowerBound) && isFinite(iStorage.yUpperBound)) {
            yAxis.setLowerAndUpperBounds(iStorage.yLowerBound, iStorage.yUpperBound);
          }
        },

        viewDidChange: function () {
          var componentView = this.get('view'),
              graphView = componentView && componentView.get('contentView');
          if (graphView) {
            this.set('xAxisView', graphView.get('xAxisView'));
            this.set('yAxisView', graphView.get('yAxisView'));
            this.set('y2AxisView', graphView.get('y2AxisView'));
            this.set('plotView', graphView.get('plotBackgroundView'));
            this.set('legendView', graphView.get('legendView'));
            this.set('axisMultiTarget', graphView.get('yAxisMultiTarget'));
            graphView.set('controller', this);
          }
        }.observes('view'),

        makePngImage: function () {
          var componentView = this.get('view');
          var graphView = componentView && componentView.get('contentView');
          var svgElements = graphView.$('svg');
          var width = graphView.getPath('frame.width');
          var height = graphView.getPath('frame.height');
          this.convertToImage(svgElements, 0, 0, width, height);
        },

        rescaleAxes: function () {
          this.graphModel.rescaleAxes();
        },

        plotFunction: function () {
          this.graphModel.get('plot').togglePlotFunction();
        },

        /**
         * A case plot can't be rescaled, but it can do a mixUp.
         */
        rescaleFunction: function () {
          var tPlot = this.getPath('graphModel.plot');
          if (tPlot && tPlot.mixUp)
            tPlot.mixUp();
          else if (this.getPath('graphModel.hasNumericAxis') && tPlot && tPlot.rescaleAxesFromData)
            tPlot.rescaleAxesFromData(true /* allowAxisRescale */, true /* Animate action */,
                true /* log it */, true /* user action */);
        },

        /**
         * If the given drag data has a data context different than our own, we must reset the
         * graph model. (I.e. until such time as we are able to handle multiple contexts on one graph.)
         * @param iDragData
         */
        handlePossibleForeignDataContext: function (iDragData) {
          var tDragContext = iDragData.context;

          if (!SC.none(tDragContext) && (tDragContext !== this.get('dataContext'))) {
            this.get('graphModel').reset();
            this.set('dataContext', tDragContext);
            var tConfig = this.getPath('graphModel.dataConfiguration');
            tConfig.set('dataContext', tDragContext);
            tConfig.invalidateCaches();
          }
        },

      /**
       An axis view has received a drop of an attribute. Our job is the tell the graph
       model which attribute and collection client to change so that we move into the
       desired configuration of attributes.
       Note that we need the '*' in the observes because the views are swapped out when the
       graph gets reconfigured.
       */
      axisViewDidAcceptDrop: function (iAxis, iKey, iDragData) {
        if (SC.none(iDragData)) // The over-notification caused by the * in the observes
          return;       // means we get here at times there isn't any drag data.

        DG.UndoHistory.execute(DG.Command.create({
          name: 'axis.attributeChange',
          undoString: 'DG.Undo.axisAttributeChange',
          redoString: 'DG.Redo.axisAttributeChange',
          _beforeStorage: null,
          _afterStorage: null,
          _componentId: this.getPath('model.id'),
          _controller: function() {
            return DG.currDocumentController().componentControllersMap[this._componentId];
          },
          execute: function() {
            var controller = this._controller();
            this._beforeStorage = controller.createComponentStorage();

            controller.handlePossibleForeignDataContext( iDragData);

            var tDataContext = controller.get('dataContext'),
                tCollectionClient = getCollectionClientFromDragData(tDataContext, iDragData);

            iAxis.dragData = null;

            controller.get('graphModel').changeAttributeForAxis(
                tDataContext,
                {
                  collection: tCollectionClient,
                  attributes: [iDragData.attribute]
                },
                iAxis.get('orientation')
            );

            this.log = 'plotAxisAttributeChange: { orientation: %@, attribute: %@ }'.fmt(iAxis.get('orientation'), iDragData.attribute.get('name'));
          },
          undo: function() {
            var controller = this._controller();
            this._afterStorage = controller.createComponentStorage();
            controller.restoreComponentStorage(this._beforeStorage);
          },
          redo: function() {
            this._controller().restoreComponentStorage(this._afterStorage);
            this._afterStorage = null;
          }
        }));
      }.observes('*xAxisView.dragData', '*yAxisView.dragData'),

        /**
         The add attribute target has received a drop of an attribute. We respond by adding an
         attribute to whatever is already on the y-axis.
         */
        multiTargetDidAcceptDrop: function (iAxisMultiTarget, iKey, iDragData) {
          if (SC.none(iDragData)) // The over-notification caused by the * in the observes
            return;       // means we get here at times there isn't any drag data.

          DG.UndoHistory.execute(DG.Command.create({
            name: 'axis.attributeChangeMultiTarget',
            undoString: 'DG.Undo.axisAttributeAdded',
            redoString: 'DG.Redo.axisAttributeAdded',
            _beforeStorage: null,
            _afterStorage: null,
            _componentId: this.getPath('model.id'),
            _controller: function() {
              return DG.currDocumentController().componentControllersMap[this._componentId];
            },
            execute: function() {
              var controller = this._controller();
              this._beforeStorage = controller.createComponentStorage();

              controller.handlePossibleForeignDataContext( iDragData);

              var tDataContext = controller.get('dataContext'),
                tCollectionClient = getCollectionClientFromDragData(tDataContext, iDragData);

              iAxisMultiTarget.dragData = null;

              controller.get('graphModel').addAttributeToAxis(
                tDataContext,
                {
                  collection: tCollectionClient,
                  attributes: [iDragData.attribute]
                });

              this.log = 'Attribute dragged and dropped: %@, %@'.fmt('vertical', iDragData.attribute.get('name'));
            },
            undo: function() {
              var controller = this._controller();
              this._afterStorage = controller.createComponentStorage();
              controller.restoreComponentStorage(this._beforeStorage);
            },
            redo: function() {
              this._controller().restoreComponentStorage(this._afterStorage);
              this._afterStorage = null;
            }
          }));
        }.observes('*axisMultiTarget.dragData'),

        /**
         The Y2 axis has received a drop of an attribute. We respond by creating a new scatterplot that
         uses the existing x-axis and the Y2 axis.
         */
        y2AxisDidAcceptDrop: function (iY2Axis, iKey, iDragData) {
          if (SC.none(iDragData)) // The over-notification caused by the * in the observes
            return;       // means we get here at times there isn't any drag data.

          DG.UndoHistory.execute(DG.Command.create({
            name: 'axis.attributeChangeY2',
            undoString: 'DG.Undo.axisAttributeChangeY2',
            redoString: 'DG.Redo.axisAttributeChangeY2',
            _beforeStorage: null,
            _afterStorage: null,
            _componentId: this.getPath('model.id'),
            _controller: function() {
              return DG.currDocumentController().componentControllersMap[this._componentId];
            },
            execute: function() {
              var controller = this._controller();
              this._beforeStorage = controller.createComponentStorage();

              controller.handlePossibleForeignDataContext( iDragData);

              var tDataContext = controller.get('dataContext'),
                tCollectionClient = getCollectionClientFromDragData(tDataContext, iDragData);

              iY2Axis.dragData = null;

              controller.get('graphModel').changeAttributeForY2Axis(
                tDataContext,
                {
                  collection: tCollectionClient,
                  attributes: [iDragData.attribute]
                });

              this.log = 'changeAttributeOnSecondYAxis: { attribute: %@ }'.fmt(iDragData.attribute.get('name'));
            },
            undo: function() {
              var controller = this._controller();
              this._afterStorage = controller.createComponentStorage();
              controller.restoreComponentStorage(this._beforeStorage);
            },
            redo: function() {
              this._controller().restoreComponentStorage(this._afterStorage);
              this._afterStorage = null;
            }
          }));
        }.observes('*y2AxisView.dragData'),

        /**
         Our base class can handle this except for the situation in which this is the first attribute being dropped,
         in which case we want to override the default behavior and simulate drop on the x-axis, which is probably
         what the user intended, but missed.
         */
        plotOrLegendViewDidAcceptDrop: function( iView, iKey, iDragData) {
          var tDataConfig = this.getPath('graphModel.dataConfiguration');
          if( !tDataConfig.get('xAttributeID') &&
              !tDataConfig.get('yAttributeID') &&
              !tDataConfig.get('legendAttributeID')) {
            iView.dragData = null;  // So we don't come back around
            this.axisViewDidAcceptDrop( this.get('xAxisView'), iKey, iDragData);
          }
          else
            sc_super();
        }.observes('*plotView.dragData', '*legendView.dragData'),

        styleControls: function () {
          var this_ = this,
              tResult = sc_super();
          tResult.push( SC.CheckboxView.create({
            title: 'DG.Inspector.graphTransparency',
            value: this_.getPath('graphModel.isTransparent'),
            classNames: 'graph-transparent-check'.w(),
            localize: true,
            valueDidChange: function () {
              this_.get('graphModel').toggleProperty('isTransparent');
            }.observes('value')
          }));
          return tResult;
        }.property()
      };

    }()) // function closure
);

<commit_msg>Transparency checkbox for graphs now has a defined height<commit_after>// ==========================================================================
//                          DG.GraphController
//
//  Author:   William Finzer
//
//  Copyright (c) 2014 by The Concord Consortium, Inc. All rights reserved.
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
// ==========================================================================

sc_require('components/graph_map_common/data_display_controller');

/** @class

    DG.GraphController provides controller functionality, particular gear menu items,
 for graphs.

 @extends SC.DataDisplayController
 */
DG.GraphController = DG.DataDisplayController.extend(
    /** @scope DG.GraphController.prototype */
    (function () {

      function getCollectionClientFromDragData(iContext, iDragData) {
        var collectionID = iDragData.collection && iDragData.collection.get('id');
        return iContext && !SC.none(collectionID) && iContext.getCollectionByID(collectionID);
      }

      return {
        graphModel: function () {
          return this.get('dataDisplayModel');
        }.property('dataDisplayModel'),
        xAxisView: null,
        yAxisView: null,
        y2AxisView: null,
        plotView: null,
        axisMultiTarget: null,

        createComponentStorage: function () {
          var storage = sc_super(),
              dataConfiguration = this.getPath('graphModel.dataConfiguration'),
              plotModels = this.getPath('graphModel.plots');

          var storeAxis = function (iDim) {
            var tAxis = this.getPath('graphModel.' + iDim + 'Axis');
            if (tAxis)
              storage[iDim + 'AxisClass'] = String(tAxis.constructor);
            if (tAxis && tAxis.get('isNumeric')) {
              storage[iDim + 'LowerBound'] = tAxis.get('lowerBound');
              storage[iDim + 'UpperBound'] = tAxis.get('upperBound');
            }
          }.bind(this);

          storage.isTransparent = this.getPath('graphModel.isTransparent');

          this.storeDimension(dataConfiguration, storage, 'x');
          this.storeDimension(dataConfiguration, storage, 'y');
          this.storeDimension(dataConfiguration, storage, 'y2');

          storeAxis('x');
          storeAxis('y');
          storeAxis('y2');

          if (plotModels) {
            storage.plotModels = [];
            plotModels.forEach(function (iPlot) {
              storage.plotModels.push({
                plotModelStorage: iPlot.createStorage(),
                plotClass: String(iPlot.constructor)
              });
            });
          }

          return storage;
        },

        restoreComponentStorage: function (iStorage, iDocumentID) {
          var graphModel = this.get('dataDisplayModel');

          sc_super();

          if (SC.none(iStorage._links_))
            return; // We don't support the older format 0096 and before. Just bring up the default graph
                    // that we already have.

          graphModel.restoreStorage(iStorage);

          // There may be some animations that have been set up. We have to stop them so that changes
          // we make below (e.g. to axis bounds) will stick.
          graphModel.stopAnimation();

          // Older versions had a single plotModelStorage, so we make ourselves backward compatible
          if (iStorage.plotModelStorage) {
            var plotModel = graphModel.get('plot');
            if (plotModel)
              plotModel.restoreStorage(iStorage.plotModelStorage);
          }
          // Newer versions always store an array of plot models even if there is only one.
          else if (iStorage.plotModels) {
            var tPlots = graphModel.get('plots');
            tPlots.forEach(function (iPlot, iIndex) {
              iPlot.restoreStorage(iStorage.plotModels[iIndex].plotModelStorage);
            });
          }

          // Configure the axes
          var xAxis = graphModel.get('xAxis'),
              yAxis = graphModel.get('yAxis');
          if (xAxis && xAxis.get('isNumeric') &&
              isFinite(iStorage.xLowerBound) && isFinite(iStorage.xUpperBound)) {
            xAxis.setLowerAndUpperBounds(iStorage.xLowerBound, iStorage.xUpperBound);
          }
          if (yAxis && yAxis.get('isNumeric') &&
              isFinite(iStorage.yLowerBound) && isFinite(iStorage.yUpperBound)) {
            yAxis.setLowerAndUpperBounds(iStorage.yLowerBound, iStorage.yUpperBound);
          }
        },

        viewDidChange: function () {
          var componentView = this.get('view'),
              graphView = componentView && componentView.get('contentView');
          if (graphView) {
            this.set('xAxisView', graphView.get('xAxisView'));
            this.set('yAxisView', graphView.get('yAxisView'));
            this.set('y2AxisView', graphView.get('y2AxisView'));
            this.set('plotView', graphView.get('plotBackgroundView'));
            this.set('legendView', graphView.get('legendView'));
            this.set('axisMultiTarget', graphView.get('yAxisMultiTarget'));
            graphView.set('controller', this);
          }
        }.observes('view'),

        makePngImage: function () {
          var componentView = this.get('view');
          var graphView = componentView && componentView.get('contentView');
          var svgElements = graphView.$('svg');
          var width = graphView.getPath('frame.width');
          var height = graphView.getPath('frame.height');
          this.convertToImage(svgElements, 0, 0, width, height);
        },

        rescaleAxes: function () {
          this.graphModel.rescaleAxes();
        },

        plotFunction: function () {
          this.graphModel.get('plot').togglePlotFunction();
        },

        /**
         * A case plot can't be rescaled, but it can do a mixUp.
         */
        rescaleFunction: function () {
          var tPlot = this.getPath('graphModel.plot');
          if (tPlot && tPlot.mixUp)
            tPlot.mixUp();
          else if (this.getPath('graphModel.hasNumericAxis') && tPlot && tPlot.rescaleAxesFromData)
            tPlot.rescaleAxesFromData(true /* allowAxisRescale */, true /* Animate action */,
                true /* log it */, true /* user action */);
        },

        /**
         * If the given drag data has a data context different than our own, we must reset the
         * graph model. (I.e. until such time as we are able to handle multiple contexts on one graph.)
         * @param iDragData
         */
        handlePossibleForeignDataContext: function (iDragData) {
          var tDragContext = iDragData.context;

          if (!SC.none(tDragContext) && (tDragContext !== this.get('dataContext'))) {
            this.get('graphModel').reset();
            this.set('dataContext', tDragContext);
            var tConfig = this.getPath('graphModel.dataConfiguration');
            tConfig.set('dataContext', tDragContext);
            tConfig.invalidateCaches();
          }
        },

      /**
       An axis view has received a drop of an attribute. Our job is the tell the graph
       model which attribute and collection client to change so that we move into the
       desired configuration of attributes.
       Note that we need the '*' in the observes because the views are swapped out when the
       graph gets reconfigured.
       */
      axisViewDidAcceptDrop: function (iAxis, iKey, iDragData) {
        if (SC.none(iDragData)) // The over-notification caused by the * in the observes
          return;       // means we get here at times there isn't any drag data.

        DG.UndoHistory.execute(DG.Command.create({
          name: 'axis.attributeChange',
          undoString: 'DG.Undo.axisAttributeChange',
          redoString: 'DG.Redo.axisAttributeChange',
          _beforeStorage: null,
          _afterStorage: null,
          _componentId: this.getPath('model.id'),
          _controller: function() {
            return DG.currDocumentController().componentControllersMap[this._componentId];
          },
          execute: function() {
            var controller = this._controller();
            this._beforeStorage = controller.createComponentStorage();

            controller.handlePossibleForeignDataContext( iDragData);

            var tDataContext = controller.get('dataContext'),
                tCollectionClient = getCollectionClientFromDragData(tDataContext, iDragData);

            iAxis.dragData = null;

            controller.get('graphModel').changeAttributeForAxis(
                tDataContext,
                {
                  collection: tCollectionClient,
                  attributes: [iDragData.attribute]
                },
                iAxis.get('orientation')
            );

            this.log = 'plotAxisAttributeChange: { orientation: %@, attribute: %@ }'.fmt(iAxis.get('orientation'), iDragData.attribute.get('name'));
          },
          undo: function() {
            var controller = this._controller();
            this._afterStorage = controller.createComponentStorage();
            controller.restoreComponentStorage(this._beforeStorage);
          },
          redo: function() {
            this._controller().restoreComponentStorage(this._afterStorage);
            this._afterStorage = null;
          }
        }));
      }.observes('*xAxisView.dragData', '*yAxisView.dragData'),

        /**
         The add attribute target has received a drop of an attribute. We respond by adding an
         attribute to whatever is already on the y-axis.
         */
        multiTargetDidAcceptDrop: function (iAxisMultiTarget, iKey, iDragData) {
          if (SC.none(iDragData)) // The over-notification caused by the * in the observes
            return;       // means we get here at times there isn't any drag data.

          DG.UndoHistory.execute(DG.Command.create({
            name: 'axis.attributeChangeMultiTarget',
            undoString: 'DG.Undo.axisAttributeAdded',
            redoString: 'DG.Redo.axisAttributeAdded',
            _beforeStorage: null,
            _afterStorage: null,
            _componentId: this.getPath('model.id'),
            _controller: function() {
              return DG.currDocumentController().componentControllersMap[this._componentId];
            },
            execute: function() {
              var controller = this._controller();
              this._beforeStorage = controller.createComponentStorage();

              controller.handlePossibleForeignDataContext( iDragData);

              var tDataContext = controller.get('dataContext'),
                tCollectionClient = getCollectionClientFromDragData(tDataContext, iDragData);

              iAxisMultiTarget.dragData = null;

              controller.get('graphModel').addAttributeToAxis(
                tDataContext,
                {
                  collection: tCollectionClient,
                  attributes: [iDragData.attribute]
                });

              this.log = 'Attribute dragged and dropped: %@, %@'.fmt('vertical', iDragData.attribute.get('name'));
            },
            undo: function() {
              var controller = this._controller();
              this._afterStorage = controller.createComponentStorage();
              controller.restoreComponentStorage(this._beforeStorage);
            },
            redo: function() {
              this._controller().restoreComponentStorage(this._afterStorage);
              this._afterStorage = null;
            }
          }));
        }.observes('*axisMultiTarget.dragData'),

        /**
         The Y2 axis has received a drop of an attribute. We respond by creating a new scatterplot that
         uses the existing x-axis and the Y2 axis.
         */
        y2AxisDidAcceptDrop: function (iY2Axis, iKey, iDragData) {
          if (SC.none(iDragData)) // The over-notification caused by the * in the observes
            return;       // means we get here at times there isn't any drag data.

          DG.UndoHistory.execute(DG.Command.create({
            name: 'axis.attributeChangeY2',
            undoString: 'DG.Undo.axisAttributeChangeY2',
            redoString: 'DG.Redo.axisAttributeChangeY2',
            _beforeStorage: null,
            _afterStorage: null,
            _componentId: this.getPath('model.id'),
            _controller: function() {
              return DG.currDocumentController().componentControllersMap[this._componentId];
            },
            execute: function() {
              var controller = this._controller();
              this._beforeStorage = controller.createComponentStorage();

              controller.handlePossibleForeignDataContext( iDragData);

              var tDataContext = controller.get('dataContext'),
                tCollectionClient = getCollectionClientFromDragData(tDataContext, iDragData);

              iY2Axis.dragData = null;

              controller.get('graphModel').changeAttributeForY2Axis(
                tDataContext,
                {
                  collection: tCollectionClient,
                  attributes: [iDragData.attribute]
                });

              this.log = 'changeAttributeOnSecondYAxis: { attribute: %@ }'.fmt(iDragData.attribute.get('name'));
            },
            undo: function() {
              var controller = this._controller();
              this._afterStorage = controller.createComponentStorage();
              controller.restoreComponentStorage(this._beforeStorage);
            },
            redo: function() {
              this._controller().restoreComponentStorage(this._afterStorage);
              this._afterStorage = null;
            }
          }));
        }.observes('*y2AxisView.dragData'),

        /**
         Our base class can handle this except for the situation in which this is the first attribute being dropped,
         in which case we want to override the default behavior and simulate drop on the x-axis, which is probably
         what the user intended, but missed.
         */
        plotOrLegendViewDidAcceptDrop: function( iView, iKey, iDragData) {
          var tDataConfig = this.getPath('graphModel.dataConfiguration');
          if( !tDataConfig.get('xAttributeID') &&
              !tDataConfig.get('yAttributeID') &&
              !tDataConfig.get('legendAttributeID')) {
            iView.dragData = null;  // So we don't come back around
            this.axisViewDidAcceptDrop( this.get('xAxisView'), iKey, iDragData);
          }
          else
            sc_super();
        }.observes('*plotView.dragData', '*legendView.dragData'),

        styleControls: function () {
          var this_ = this,
              tResult = sc_super();
          tResult.push( SC.CheckboxView.create({
            layout: {height: 25 },
            title: 'DG.Inspector.graphTransparency',
            value: this_.getPath('graphModel.isTransparent'),
            classNames: 'graph-transparent-check'.w(),
            localize: true,
            valueDidChange: function () {
              this_.get('graphModel').toggleProperty('isTransparent');
            }.observes('value')
          }));
          return tResult;
        }.property()
      };

    }()) // function closure
);

<|endoftext|>