1 /* See license.txt for terms of usage */
  2 
  3 // ********************************************************************************************* //
  4 // Constants
  5 
  6 var EXPORTED_SYMBOLS = ["FirebugLoader"];
  7 
  8 var Cc = Components.classes;
  9 var Ci = Components.interfaces;
 10 var Cu = Components.utils;
 11 
 12 Cu.import("resource://gre/modules/Services.jsm");
 13 Cu.import("resource://firebug/fbtrace.js");
 14 
 15 // ********************************************************************************************* //
 16 
 17 function loadSubscript(src, win)
 18 {
 19     return Services.scriptloader.loadSubScript(src, win);
 20 }
 21 
 22 // ********************************************************************************************* //
 23 
 24 var FirebugLoader =
 25 {
 26     bootstrapScopes: [],
 27 
 28     registerBootstrapScope: function(e)
 29     {
 30         if (this.bootstrapScopes.indexOf(e) != -1)
 31             return;
 32 
 33         this.bootstrapScopes.push(e);
 34 
 35         this.forEachWindow(function(win)
 36         {
 37             e.topWindowLoad(win);
 38 
 39             if (!win.Firebug.isInitialized)
 40                 return;
 41 
 42             e.firebugFrameLoad(win.Firebug);
 43         })
 44     },
 45 
 46     unregisterBootstrapScope: function(e)
 47     {
 48         var i = this.bootstrapScopes.indexOf(e);
 49         if (i >= 0)
 50             this.bootstrapScopes.splice(i, 1);
 51 
 52         if (e.topWindowUnload)
 53         {
 54             this.forEachWindow(function(win)
 55             {
 56                 e.topWindowUnload(win);
 57             })
 58         }
 59 
 60         if (e.firebugFrameUnload)
 61         {
 62             this.forEachWindow(function(win)
 63             {
 64                 e.firebugFrameUnload(win.Firebug);
 65             })
 66         }
 67     },
 68 
 69     // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 70 
 71     startup: function()
 72     {
 73         // allow already started bootstrapped firebug extensions to register themselves
 74         var XPIProviderBP = Cu.import("resource://gre/modules/XPIProvider.jsm", {});
 75         var bootstrapScopes = XPIProviderBP.XPIProvider.bootstrapScopes;
 76 
 77         for each(var scope in bootstrapScopes)
 78         {
 79             try
 80             {
 81                 if (scope.firebugStartup)
 82                     scope.firebugStartup(this);
 83             }
 84             catch(e)
 85             {
 86                 Cu.reportError(e);
 87             }
 88         }
 89     },
 90 
 91     shutdown: function()
 92     {
 93         this.forEachWindow(function(win)
 94         {
 95             FirebugLoader.unloadFromWindow(win);
 96         })
 97     },
 98 
 99     // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
100 
101     unloadFromWindow: function(win)
102     {
103         var fbug = win.Firebug
104         this.dispatchToScopes("topWindowUnload", [win]);
105 
106         if (fbug.shutdown)
107         {
108             fbug.closeFirebug();
109             fbug.shutdown();
110         }
111 
112         function getRoots(el)
113         {
114             return Array.slice(el.querySelectorAll("[firebugRootNode]"));
115         }
116 
117         [getRoots(win.document), getRoots(win.gNavToolbox.palette),
118             fbug.browserOverlay.nodesToRemove].forEach(function(list)
119         {
120             for each(var el in list)
121                 if (el && el.parentNode)
122                     el.parentNode.removeChild(el);
123         });
124 
125         win.Firebug.browserOverlay.unloadContextMenuOverlay(win);
126 
127         delete win.Firebug;
128         delete win.FBTrace;
129         delete win.FBL;
130     },
131 
132     loadIntoWindow: function(win, reason)
133     {
134         // This is the place where the global Firebug object is created. This object represents
135         // the entire application and all consequently created namespaces and variables should be
136         // injected into it.
137         // In the future, there should *not* be any other globals except of the Firebug object.
138         // xxxHonza: properties from this object are copied into the new Firebug obect that is
139         // created within "firebug/firebug" module (a hack).
140         win.Firebug = {};
141 
142         var requireScope = {};
143         Cu.import("resource://firebug/mini-require.js", requireScope);
144         var require = requireScope.require;
145 
146         var config = {
147             baseUrl: "resource://",
148             paths: {"firebug": "chrome://firebug/content"}
149         };
150 
151         require(config, [
152             "firebug/firefox/browserOverlay"
153         ],
154         function(BrowserOverlay)
155         {
156             var overlay = win.Firebug.browserOverlay = new BrowserOverlay(win);
157             overlay.initialize(reason);
158         });
159 
160         if (FBTrace.DBG_MODULES)
161             FBTrace.sysout("Basic loader dependencies: " + require.Loader.getDepDesc());
162 
163         // Firebug extensions should initialize here.
164         this.dispatchToScopes("topWindowLoad", [win]);
165     },
166 
167     dispatchToScopes: function(name, arguments)
168     {
169         for each (var e in this.bootstrapScopes)
170         {
171             try
172             {
173                 if (name in e)
174                     e[name].apply(e, arguments);
175             }
176             catch(e)
177             {
178                 Cu.reportError(e);
179             }
180         }
181     },
182 
183     forEachWindow: function(func)
184     {
185         var enumerator = Services.wm.getEnumerator("navigator:browser");
186         while (enumerator.hasMoreElements())
187         {
188             try
189             {
190                 var win = enumerator.getNext();
191                 if (win.Firebug)
192                     func(win);
193             }
194             catch(e)
195             {
196                 Cu.reportError(e);
197             }
198         }
199     }
200 }
201 
202 // ********************************************************************************************* //
203