1 /* See license.txt for terms of usage */
  2 
  3 define([
  4     "firebug/lib/object",
  5     "firebug/firebug",
  6     "firebug/chrome/firefox",
  7     "firebug/lib/locale",
  8     "firebug/lib/domplate",
  9     "firebug/lib/url",
 10     "firebug/lib/dom",
 11 ],
 12 function(Obj, Firebug, Firefox, Locale, Domplate, Url, Dom) {
 13 
 14 // ************************************************************************************************
 15 // Constants
 16 
 17 const Cc = Components.classes;
 18 const Ci = Components.interfaces;
 19 
 20 const prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
 21 
 22 
 23 /**
 24  * @module Implements Panel activation logic. A Firebug panel can support activation in order
 25  * to avoid performance penalties in cases when panel's features are not necessary at the moment.
 26  * Such panel must be derived from {@link Firebug.ActivablePanel} and appropriate activable
 27  * module from {@link Firebug.ActivableModule}
 28  */
 29 Firebug.PanelActivation = Obj.extend(Firebug.Module,
 30 /** @lends Firebug.PanelActivation */
 31 {
 32     dispatchName: "panelActivation",
 33 
 34     // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 35 
 36     initialize: function()
 37     {
 38         prefs.addObserver(Firebug.Options.getPrefDomain(), this, false);
 39         Firebug.connection.addListener(this);
 40     },
 41 
 42     initializeUI: function()
 43     {
 44         // The "off" option is removed so make sure to convert previsous prev value
 45         // into "none" if necessary.
 46         if (Firebug.allPagesActivation == "off")
 47             Firebug.allPagesActivation = "none";
 48 
 49         // Update option menu item.
 50         this.updateAllPagesActivation();
 51     },
 52 
 53     shutdown: function()
 54     {
 55         prefs.removeObserver(Firebug.Options.getPrefDomain(), this, false);
 56         Firebug.connection.removeListener(this);
 57     },
 58 
 59     showPanel: function(browser, panel)
 60     {
 61         if (FBTrace.DBG_ACTIVATION)
 62             FBTrace.sysout("PanelActivation.showPanel; " + (panel ? panel.name : "null panel"));
 63 
 64         // Panel toolbar is not displayed for disabled panels.
 65         var chrome = Firebug.chrome;
 66         Dom.collapse(chrome.$("fbToolbar"), !panel);
 67     },
 68 
 69     // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 70 
 71     activatePanelTypes: function(panelTypes)
 72     {
 73         for (var i=0; i<panelTypes.length; i++)
 74         {
 75             var panelType = panelTypes[i];
 76             if (!this.isPanelActivable(panelType))
 77                 continue;
 78 
 79             if (this.isPanelEnabled(panelType))
 80                 panelType.prototype.onActivationChanged(true);
 81         }
 82     },
 83 
 84     deactivatePanelTypes: function(panelTypes)
 85     {
 86         for (var i=0; i<panelTypes.length; i++)
 87         {
 88             var panelType = panelTypes[i];
 89             if (!this.isPanelActivable(panelType))
 90                 continue;
 91 
 92             if (this.isPanelEnabled(panelType))
 93                 panelType.prototype.onActivationChanged(false);
 94         }
 95     },
 96 
 97     // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 98 
 99     isPanelActivable: function(panelType)
100     {
101         return panelType.prototype.activable ? true : false;
102     },
103 
104     isPanelEnabled: function(panelType)
105     {
106         if (typeof(panelType) == "string")
107             panelType = Firebug.getPanelType("script");
108 
109         if (!this.isPanelActivable(panelType))
110             return true;
111 
112         // Panel "class" object is used to decide whether a panel is disabled
113         // or not (i.e.: isEnabled is a static method of Firebug.Panel)
114         return panelType ? panelType.prototype.isEnabled() : false;
115     },
116 
117     // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
118     // Enable & disable methods.
119 
120     enablePanel: function(panelType)
121     {
122         this.setPanelState(panelType, true);
123     },
124 
125     disablePanel: function(panelType)
126     {
127         this.setPanelState(panelType, false);
128     },
129 
130     enableAllPanels: function()
131     {
132         for (var i = 0; i < Firebug.panelTypes.length; ++i)
133         {
134             var panelType = Firebug.panelTypes[i];
135             this.setPanelState(panelType, true);
136         }
137     },
138 
139     disableAllPanels: function()
140     {
141         for (var i = 0; i < Firebug.panelTypes.length; ++i)
142         {
143             var panelType = Firebug.panelTypes[i];
144             this.setPanelState(panelType, false);
145         }
146     },
147 
148     setPanelState: function(panelType, enable)
149     {
150         if (panelType && panelType.prototype.setEnabled)
151             panelType.prototype.setEnabled(enable);
152 
153         this.updateTab(panelType);
154     },
155 
156     updateTab: function(panelType)
157     {
158         var panelName = panelType.prototype.name;
159         var panelBar = Firebug.chrome.$("fbPanelBar1");
160         var tab = panelBar.updateTab(panelType);
161     },
162 
163     // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
164     // Observer activation changes (preference)
165 
166     /**
167      * Observer for activation preferences changes.
168      */
169     observe: function(subject, topic, data)
170     {
171         if (topic != "nsPref:changed")
172             return;
173 
174         if (data.indexOf(".enableSites") == -1)
175             return;
176 
177         var parts = data.split(".");
178         if (parts.length != 4)
179             return;
180 
181         try
182         {
183             var panelName = parts[2];
184             var enable = Firebug.Options.get(panelName + ".enableSites");
185 
186             var panelType = Firebug.getPanelType(panelName, enable);
187             if (panelType)
188                 this.onActivationChanged(panelType, enable);
189         }
190         catch (e)
191         {
192             if (FBTrace.DBG_ACTIVATION || FBTrace.DBG_ERRORS)
193                 FBTrace.sysout("PanelActivation.observe; EXCEPTION " + e, e);
194         }
195     },
196 
197     onActivationChanged: function(panelType, enable)
198     {
199         if (!enable)
200         {
201             // Iterate all contexts and destroy all instances of the specified panel.
202             var self = this;
203             Firebug.connection.eachContext(function(context) {
204                 context.destroyPanel(panelType, context.persistedState);
205             });
206         }
207 
208         panelType.prototype.onActivationChanged(enable);
209 
210         Firebug.chrome.$("fbPanelBar1").updateTab(panelType);
211         Firebug.chrome.syncPanel();
212     },
213 
214     // respond to event
215     onClearAnnotations: function()
216     {
217         Firebug.closeFirebug(true);  // and we turn off as it now cannot be enabled
218     },
219 
220     // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
221     // UI commands
222 
223     clearAnnotations: function()
224     {
225         Firebug.connection.clearAnnotations();
226     },
227 
228     toggleAll: function(state)
229     {
230         if (FBTrace.DBG_ACTIVATION)
231             FBTrace.sysout("Firebug.toggleAll("+state+") with allPagesActivation: " +
232                 Firebug.allPagesActivation);
233 
234         if (state == "on")
235         {
236             if (Firebug.allPagesActivation == state) // then we were armed
237                 Firebug.allPagesActivation = "none";
238             else
239                 this.allOn();
240         }
241         else
242         {
243             Firebug.allPagesActivation = "none";
244         }
245 
246         Firebug.Options.set("allPagesActivation", Firebug.allPagesActivation);
247         this.updateAllPagesActivation();
248     },
249 
250     updateOption: function(name, value)
251     {
252         if (name == "allPagesActivation")
253             this.updateAllPagesActivation();
254     },
255 
256     updateAllPagesActivation: function()
257     {
258         // don't show Off button if we are always on
259         var allOn = Firebug.allPagesActivation == "on";
260         Firebug.chrome.disableOff(allOn);
261 
262         Firebug.StartButton.resetTooltip();
263     },
264 
265     allOn: function()
266     {
267         Firebug.allPagesActivation = "on";  // In future we always create contexts,
268         Firebug.toggleBar(true);  // and we turn on for the current page
269     }
270 });
271 
272 // ************************************************************************************************
273 
274 /**
275  * @domplate This template renders default content for disabled panels.
276  */
277 with (Domplate) {
278 Firebug.DisabledPanelBox = domplate(Firebug.Rep,
279 /** @lends Firebug.DisabledPanelBox */
280 {
281     tag:
282         DIV({"class": "disabledPanelBox"},
283             H1({"class": "disabledPanelHead"},
284                 SPAN("$pageTitle")
285             ),
286             P({"class": "disabledPanelDescription", style: "margin-top: 15px;"},
287                 Locale.$STR("moduleManager.desc3"),
288                 SPAN(" "),
289                 SPAN({"class": "descImage descImage-$panelName"})
290             ),
291             A({"class": "objectLink", onclick: "$onEnable"},
292                 Locale.$STR("moduleManager.Enable")
293             )
294             /* need something here that pushes down any thing appended to the panel */
295         ),
296 
297     onEnable: function(event)
298     {
299         var view = event.target.ownerDocument.defaultView;
300         var isMainPanel = (view.name == "fbPanelBar1-browser");
301         var panelBar = Firebug.chrome.$(isMainPanel ? "fbPanelBar1" : "fbPanelBar2");
302 
303         var panelType = panelBar.selectedTab.panelType;
304         if (panelType.prototype.setEnabled)
305         {
306             panelType.prototype.setEnabled(true);
307             panelBar.updateTab(panelType);
308         }
309         else
310         {
311             if (FBTrace.DBG_ERRORS)
312                 FBTrace.sysout("panelActivation.onEnable; panel is not activable: " +
313                     Firebug.getPanelTitle(panelType));
314         }
315     },
316 
317     /**
318      * Show default content saying that this panel type (specified by name) is disabled.
319      * The parent node is specified in panel.html file.
320      */
321     show: function(browser, panelName)
322     {
323         if (!panelName)
324             return;
325 
326         var panel = Firebug.getPanelType(panelName);
327         var panelTitle = Firebug.getPanelTitle(panel);
328         var args = {
329             pageTitle: Locale.$STRF("moduleManager.title", [panelTitle]),
330             panelName: panelName
331         };
332 
333         var parentNode = this.getParentNode(browser);
334         this.tag.replace(args, parentNode, this);
335         parentNode.removeAttribute("collapsed");
336     },
337 
338     /**
339      * Hide currently displayed default content.
340      */
341     hide: function(browser)
342     {
343         var parentNode = this.getParentNode(browser);
344 
345         // xxxHonza: I am seeing null parentNode when Firebug initializes
346         // Could it be because the panel.html can sometimes take more time to load?
347         if (!parentNode)
348             return;
349 
350         Dom.clearNode(parentNode);
351         parentNode.setAttribute("collapsed", true);
352     },
353 
354     getParentNode: function(browser)
355     {
356         var doc = browser.contentDocument;
357         return doc.documentElement.querySelector(".disabledPanelNode");
358     },
359 })};
360 
361 // ************************************************************************************************
362 // Registration
363 
364 Firebug.registerModule(Firebug.PanelActivation);
365 
366 return Firebug.PanelActivation;
367 
368 // ************************************************************************************************
369 });
370