wip: detach2 ok
[fnpeditor.git] / src / fnpjs / runner.js
1 define(['libs/jquery', 'libs/underscore'], function($, _) {
2
3 'use strict';
4
5 var Runner = function(app, modules) {
6
7     function getModuleInstance(moduleName) {
8         var module = moduleInstances[moduleName] = (moduleInstances[moduleName] || modules[moduleName](new Sandbox(moduleName)));
9         return module;
10     }
11
12     var bootstrappedData = {},
13         options = {},
14         moduleInstances = {},
15         eventListeners = [];
16         
17     _.each(_.keys(modules || {}), function(moduleName) {
18         if(_.contains(app.permissions[moduleName] || [], 'handleEvents')) {
19             eventListeners.push(moduleName);
20         }
21     });
22
23     
24         
25     var Sandbox = function(moduleName) {
26         this.$ = $;
27         this._ = _;
28         
29         this.getBootstrappedData = function() {
30             return bootstrappedData[moduleName];
31         };
32         
33         this.getTemplate = function(templateName) {
34             return _.template($('[data-template-name="' + moduleName + '.' + templateName + '"]').html().trim());
35         };
36         
37         this.publish = function(eventName) {
38             var eventArgs = Array.prototype.slice.call(arguments, 1);
39             _.each(eventListeners, function(listenerModuleName) {
40                 var listener = moduleInstances[listenerModuleName];
41                 if(listener) {
42                     listener.handleEvent(moduleName, eventName, eventArgs);
43                 }
44             });
45         };
46         
47         var permissions = app.permissions[moduleName];
48         
49         this.getModule = _.contains(permissions, 'getModule') ? function(requestedModuleName) {
50             return getModuleInstance(requestedModuleName);
51         } : undefined;
52         
53         this.getDOM = _.contains(permissions, 'getDOM') ? function() {
54             return $(options.rootSelector);
55         } : undefined;
56         
57     };
58     
59     
60     this.setBootstrappedData = function(moduleName, data) {
61         bootstrappedData[moduleName] = data;
62     };
63     
64     this.start = function(_options) {
65         options = _.extend({
66             rootSelector: 'body'
67         }, _options);
68         app.initModules.forEach(function(moduleName) {
69             getModuleInstance(moduleName).start();
70         });
71     };
72 };
73
74 return {
75     Runner: Runner
76 };
77
78 });