don't ask on unload unless document is dirty
[fnpeditor.git] / src / fnpjs / runner.js
index 0da2916..0dd52e5 100644 (file)
@@ -1,4 +1,4 @@
-define(['libs/jquery', 'libs/underscore'], function($, _) {
+define(['libs/jquery', 'libs/underscore', 'fnpjs/logging/logging', 'fnpjs/actions'], function($, _, logging, actions) {
 
 'use strict';
 
@@ -10,9 +10,13 @@ var Runner = function(app, modules) {
     }
 
     var bootstrappedData = {},
-        options = {},
         moduleInstances = {},
-        eventListeners = [];
+        eventListeners = [],
+        plugins = [],
+        actionDefinitions = {},
+        config,
+        actionsAppObject,
+        currentContextMenu;
         
     _.each(_.keys(modules || {}), function(moduleName) {
         if(_.contains(app.permissions[moduleName] || [], 'handleEvents')) {
@@ -30,10 +34,6 @@ var Runner = function(app, modules) {
             return bootstrappedData[moduleName];
         };
         
-        this.getTemplate = function(templateName) {
-            return _.template($('[data-template-name="' + moduleName + '.' + templateName + '"]').html().trim());
-        };
-        
         this.publish = function(eventName) {
             var eventArgs = Array.prototype.slice.call(arguments, 1);
             _.each(eventListeners, function(listenerModuleName) {
@@ -51,23 +51,92 @@ var Runner = function(app, modules) {
         } : undefined;
         
         this.getDOM = _.contains(permissions, 'getDOM') ? function() {
-            return $(options.rootSelector);
+            return $(config.rootSelector);
         } : undefined;
-        
+
+        this.getPlugins = function() {
+            return plugins;
+        };
+
+        this.getConfig = function() {
+            return config;
+        };
+
+        this.createAction = function(fqName, config) {
+            var definition = actionDefinitions[fqName];
+            if(!definition) {
+                throw new Error('Invalid action: ' + fqName);
+            }
+            return new actions.Action(fqName, definition, config, actionsAppObject);
+        };
+
+        this.registerKeyHandler = function(eventName, handler) {
+            $('body').on(eventName, function(e) {
+                handler(e);
+            });
+        };
+
+        this.registerActionsAppObject = function(_actionsAppObject) {
+            actionsAppObject = _actionsAppObject;
+        };
+
+        this.showContextMenu = function(menu, coors) {
+            if(currentContextMenu) {
+                currentContextMenu.close();
+            }
+            currentContextMenu = menu;
+            $(config.rootSelector).append(menu.dom);
+            menu.dom.css({top: coors.y, left: coors.x});
+            menu.show();
+        };
     };
-    
-    
+      
     this.setBootstrappedData = function(moduleName, data) {
         bootstrappedData[moduleName] = data;
     };
+
+    this.registerPlugin = function(plugin) {
+        plugins.push(plugin);
+        (plugin.actions || []).forEach(function(definition) {
+            var actionFqName = plugin.name + '.' + definition.name;
+            actionDefinitions[actionFqName] = definition;
+        });
+    };
     
-    this.start = function(_options) {
-        options = _.extend({
+    this.start = function(_config) {
+        config = _.extend({
             rootSelector: 'body'
-        }, _options);
+        }, _config);
+
+
+        if(config.logging) {
+            logging.setConfig(config.logging);
+        }
+
+        _.pairs(config.plugins || {}).forEach(function(pair) {
+            var pluginName = pair[0],
+                pluginConfig = pair[1];
+
+            plugins.some(function(plugin) {
+                if(plugin.name === pluginName) {
+                    if(_.isFunction(plugin.config)) {
+                        plugin.config(pluginConfig);
+                    }
+                    return true; //break
+                }
+            });
+        });
+
         app.initModules.forEach(function(moduleName) {
             getModuleInstance(moduleName).start();
         });
+
+        $(config.rootSelector)[0].addEventListener('click', function(e) {
+            if(currentContextMenu && !currentContextMenu.dom[0].contains(e.target)) {
+                currentContextMenu.close();
+                currentContextMenu = null;
+            }
+        }, true);
     };
 };