1 /* See license.txt for terms of usage */
  2 
  3 var Firebug = Firebug || {};
  4 
  5 // ********************************************************************************************* //
  6 
  7 /**
  8  * Returns default configuration object for Firebug module loader (RequireJS). Custom
  9  * value can be passed through the argument.
 10  *
 11  * @param {Object} baseConfig Custom configuration values.
 12  */
 13 Firebug.getModuleLoaderConfig = function(baseConfig)
 14 {
 15     baseConfig = baseConfig || {};
 16 
 17     // Set configuration defaults.
 18     baseConfig.baseLoaderUrl = baseConfig.baseLoaderUrl || "resource://moduleLoader/";
 19     baseConfig.prefDomain = baseConfig.prefDomain || "extensions.firebug";
 20     baseConfig.baseUrl = baseConfig.baseUrl || "resource://";
 21     baseConfig.xhtml = true;  // createElementNS used
 22     baseConfig.arch = baseConfig.arch || "chrome://firebug/content/bti/inProcess";
 23 
 24     baseConfig.paths = baseConfig.paths || {
 25         "arch": baseConfig.arch,
 26         "firebug": "chrome://firebug/content"
 27     };
 28 
 29     var config = {};
 30     var keys = Object.keys(baseConfig);
 31     keys.forEach(function copy(key)
 32     {
 33         config[key] = baseConfig[key];
 34     });
 35 
 36     // This is the basic list of necessary modules. All the other modules will be
 37     // automatically loaded as dependencies.
 38     config.modules = [
 39         "firebug/trace/traceModule",
 40         "firebug/chrome/navigationHistory",
 41         "firebug/chrome/knownIssues",
 42         "firebug/js/sourceFile",
 43         "firebug/chrome/shortcuts",
 44         "firebug/firefox/start-button/startButtonOverlay",
 45         "firebug/firefox/external-editors/externalEditors",
 46         "firebug/chrome/panelActivation",
 47         //"firebug/console/memoryProfiler", xxxHonza: removed from 1.10 (issue 5599)
 48         "firebug/chrome/tableRep",
 49         "firebug/html/htmlPanel",
 50         "firebug/console/commandLinePopup",
 51         "firebug/accessible/a11y",
 52         "firebug/js/scriptPanel",
 53         "firebug/js/callstack",
 54         "firebug/console/consoleInjector",
 55         "firebug/net/spy",
 56         "firebug/js/tabCache",
 57         "firebug/chrome/activation",
 58         "firebug/css/stylePanel",
 59         "firebug/css/computedPanel",
 60         "firebug/cookies/cookieModule",
 61         "firebug/cookies/cookiePanel",
 62         "firebug/css/selectorPanel",
 63     ];
 64 
 65     return config;
 66 }
 67 
 68 // ********************************************************************************************* //
 69 // Firebug Extension Registration
 70 
 71 Firebug.extensions = {};
 72 
 73 /**
 74  * Registers a Firebug extension. The framework automatically loads 'main' extension
 75  * module (AMD).
 76  *
 77  * @param {String} extName        Unique name of the extension. This name is used to
 78  *      build chrome paths for extension resource: chrome://<ext-id>/content/main.js
 79  * @param {Object} extConfig    Configuration file
 80  */
 81 Firebug.registerExtension = function(extName, extConfig)
 82 {
 83     extConfig = extConfig || {};
 84 
 85     var tempConfig = this.getExtensionConfig(extName);
 86     if (tempConfig)
 87     {
 88         Components.utils.reportError("firebug.registerExtension; ERROR An extension " +
 89             "with the same ID already exists! - " + extName, tempConfig);
 90         return;
 91     }
 92 
 93     this.extensions[extName] = extConfig;
 94 
 95     var config = Firebug.getModuleLoaderConfig();
 96 
 97     // Do not use resource: protocol for extensions (it's not allowed for bootstrapped
 98     // extensions to specify the protocol in chrome.manifest and it would require
 99     // additional code in every extension (in bootstrap.js), use standard chrome: instead.
100     //config.paths[extName] = extName + "/content";
101     config.paths[extName] = "chrome://" + extName + "/content";
102 
103     // Load main.js module (the entry point of the extension) and support for tracing.
104     // All other extension modules should be loaded within "main" module.
105     Firebug.require(config, [
106         extName + "/main",
107         "firebug/lib/trace"
108     ],
109     function(Extension, FBTrace)
110     {
111         try
112         {
113             extConfig.app = Extension;
114 
115             // Extension intialization procedure should be within this method (in main.js).
116             if (Extension.initialize)
117                 Extension.initialize();
118 
119             // Refresh Firebug tab-bar to make sure that any new registered panels
120             // are displayed.
121             if (Firebug.chrome)
122                 Firebug.chrome.syncMainPanels();
123 
124             if (FBTrace.DBG_INITIALIZE)
125                 FBTrace.sysout("firebug.main; Extension '" + extName + " - modules loaded!");
126         }
127         catch (err)
128         {
129             Components.utils.reportError("firebug.main; Extension: " + extName +
130                 " EXCEPTION " + err, err);
131         }
132     });
133 }
134 
135 /**
136  * Unregisters and shutdowns specific extension. Registered extensions are unregistered
137  * automatically when Firebug shutdowns. Bootstrapped extensions should use this method
138  * to dynamically uninstall an extension.
139  *
140  * @param {Object} extName    ID of the extensions that should be unregistered.
141  */
142 Firebug.unregisterExtension = function(extName)
143 {
144     var extConfig = this.getExtensionConfig(extName);
145     if (!extConfig)
146         return;
147 
148     try
149     {
150         if (extConfig.app && extConfig.app.shutdown)
151             extConfig.app.shutdown();
152 
153         delete this.extensions[extName];
154     }
155     catch (err)
156     {
157         Components.utils.reportError("unregisterExtension: " + extName +
158             " EXCEPTION " + err, err);
159     }
160 }
161 
162 Firebug.getExtensionConfig = function(extName)
163 {
164     return this.extensions[extName];
165 }
166 
167 Firebug.iterateExtensions = function(callback)
168 {
169     for (var ext in this.extensions)
170         callback(ext, this.extensions[ext]);
171 }
172 
173 /**
174  * Unregisters and shutdowns all registered extensions. Called by the framework when
175  * Firebug shutdowns.
176  */
177 Firebug.unregisterExtensions = function()
178 {
179     var extensions = {};
180     for (var p in this.extensions)
181         extensions[p] = this.extensions[p];
182 
183     for (var extName in extensions)
184         this.unregisterExtension(extName);
185 
186     this.extensions = {};
187 }
188 
189 // ********************************************************************************************* //
190