1 define(['libs/jquery', 'libs/underscore', 'fnpjs/logging/logging', 'fnpjs/actions'], function($, _, logging, actions) {
5 var Runner = function(app, modules) {
7 function getModuleInstance(moduleName) {
8 var module = moduleInstances[moduleName] = (moduleInstances[moduleName] || modules[moduleName](new Sandbox(moduleName)));
12 var bootstrappedData = {},
16 actionDefinitions = {},
21 _.each(_.keys(modules || {}), function(moduleName) {
22 if(_.contains(app.permissions[moduleName] || [], 'handleEvents')) {
23 eventListeners.push(moduleName);
29 var Sandbox = function(moduleName) {
33 this.getBootstrappedData = function() {
34 return bootstrappedData[moduleName];
37 this.publish = function(eventName) {
38 var eventArgs = Array.prototype.slice.call(arguments, 1);
39 _.each(eventListeners, function(listenerModuleName) {
40 var listener = moduleInstances[listenerModuleName];
42 listener.handleEvent(moduleName, eventName, eventArgs);
47 var permissions = app.permissions[moduleName];
49 this.getModule = _.contains(permissions, 'getModule') ? function(requestedModuleName) {
50 return getModuleInstance(requestedModuleName);
53 this.getDOM = _.contains(permissions, 'getDOM') ? function() {
54 return $(config.rootSelector);
57 this.getPlugins = function() {
61 this.getConfig = function() {
65 this.createAction = function(fqName, config) {
66 var definition = actionDefinitions[fqName];
68 throw new Error('Invalid action: ' + fqName);
70 return new actions.Action(fqName, definition, config, actionsAppObject);
73 this.registerKeyHandler = function(eventName, handler) {
74 $('body').on(eventName, function(e) {
79 this.registerActionsAppObject = function(_actionsAppObject) {
80 actionsAppObject = _actionsAppObject;
83 this.showContextMenu = function(menu, coors) {
84 if(currentContextMenu) {
85 currentContextMenu.close();
87 currentContextMenu = menu;
88 $(config.rootSelector).append(menu.dom);
89 menu.dom.css({top: coors.y, left: coors.x});
93 this.getTutorialItem = function(name) {
94 var tutorial = this.getConfig().tutorial;
95 var tutorialText, index;
96 tutorial.some(function(item, i) {
97 if(item.name === name) {
98 tutorialText = item.text;
105 return {index: index + 1, text: tutorialText};
109 this.setBootstrappedData = function(moduleName, data) {
110 bootstrappedData[moduleName] = data;
113 this.registerPlugin = function(plugin) {
114 plugins.push(plugin);
115 (plugin.actions || []).forEach(function(definition) {
116 var actionFqName = plugin.name + '.' + definition.name;
117 actionDefinitions[actionFqName] = definition;
121 this.start = function(_config) {
128 logging.setConfig(config.logging);
131 _.pairs(config.plugins || {}).forEach(function(pair) {
132 var pluginName = pair[0],
133 pluginConfig = pair[1];
135 plugins.some(function(plugin) {
136 if(plugin.name === pluginName) {
137 if(_.isFunction(plugin.config)) {
138 plugin.config(pluginConfig);
145 app.initModules.forEach(function(moduleName) {
146 getModuleInstance(moduleName).start();
149 $(config.rootSelector)[0].addEventListener('click', function(e) {
150 if(currentContextMenu && !currentContextMenu.dom[0].contains(e.target)) {
151 currentContextMenu.close();
152 currentContextMenu = null;