Bug 1359855 - Fix the developer toggle in customize widgets. r=jdescottes
Now that devtools-browser is lazily evaluated, we have to create the widget early in devtools-startup.
MozReview-Commit-ID: JanbAPalYE1
--- a/devtools/client/devtools-startup.js
+++ b/devtools/client/devtools-startup.js
@@ -26,16 +26,20 @@ const kDebuggerPrefs = [
"devtools.debugger.remote-enabled",
"devtools.chrome.enabled"
];
const { XPCOMUtils } = Cu.import("resource://gre/modules/XPCOMUtils.jsm", {});
XPCOMUtils.defineLazyModuleGetter(this, "Services",
"resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "AppConstants",
"resource://gre/modules/AppConstants.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "CustomizableUI",
+ "resource:///modules/CustomizableUI.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "CustomizableWidgets",
+ "resource:///modules/CustomizableWidgets.jsm");
XPCOMUtils.defineLazyGetter(this, "Bundle", function () {
const kUrl = "chrome://devtools/locale/key-shortcuts.properties";
return Services.strings.createBundle(kUrl);
});
XPCOMUtils.defineLazyGetter(this, "KeyShortcuts", function () {
const isMac = AppConstants.platform == "macosx";
@@ -203,19 +207,96 @@ DevToolsStartup.prototype = {
this.hookKeyShortcuts(window);
// All the other hooks are only necessary if the tools aren't loaded yet.
if (this.initialized) {
return;
}
this.hookWebDeveloperMenu(window);
+ this.hookDeveloperToggle(window);
},
/**
+ * Dynamically register a wrench icon in the customization menu.
+ * You can use this button by right clicking on Firefox toolbar
+ * and dragging it from the customization panel to the toolbar.
+ * (i.e. this isn't displayed by default to users!)
+ *
+ * _But_, the "Web Developer" entry in the hamburger menu (the menu with
+ * 3 horizontal lines), is using this "developer-button" view to populate
+ * its menu. So we have to register this button for the menu to work.
+ *
+ * Also, this menu duplicates its own entries from the "Web Developer"
+ * menu in the system menu, under "Tools" main menu item. The system
+ * menu is being hooked by "hookWebDeveloperMenu" which ends up calling
+ * devtools/client/framework/browser-menu to create the items for real,
+ * initDevTools, from onViewShowing is also calling browser-menu.
+ */
+ hookDeveloperToggle(window) {
+ let id = "developer-button";
+ let widget = CustomizableUI.getWidget(id);
+ if (widget && widget.provider == CustomizableUI.PROVIDER_API) {
+ return;
+ }
+ let item = {
+ id: id,
+ type: "view",
+ viewId: "PanelUI-developer",
+ shortcutId: "key_toggleToolbox",
+ tooltiptext: "developer-button.tooltiptext2",
+ defaultArea: AppConstants.MOZ_DEV_EDITION ?
+ CustomizableUI.AREA_NAVBAR :
+ CustomizableUI.AREA_PANEL,
+ onViewShowing: (event) => {
+ // Ensure creating the menuitems in the system menu before trying to copy them.
+ this.initDevTools();
+
+ // Populate the subview with whatever menuitems are in the developer
+ // menu. We skip menu elements, because the menu panel has no way
+ // of dealing with those right now.
+ let doc = event.target.ownerDocument;
+
+ let menu = doc.getElementById("menuWebDeveloperPopup");
+
+ let itemsToDisplay = [...menu.children];
+ // Hardcode the addition of the "work offline" menuitem at the bottom:
+ itemsToDisplay.push({localName: "menuseparator", getAttribute: () => {}});
+ itemsToDisplay.push(doc.getElementById("goOfflineMenuitem"));
+
+ let developerItems = doc.getElementById("PanelUI-developerItems");
+ // Import private helpers from CustomizableWidgets
+ let { clearSubview, fillSubviewFromMenuItems } =
+ Cu.import("resource:///modules/CustomizableWidgets.jsm", {});
+ clearSubview(developerItems);
+ fillSubviewFromMenuItems(itemsToDisplay, developerItems);
+ },
+ onInit(anchor) {
+ // Since onBeforeCreated already bails out when initialized, we can call
+ // it right away.
+ this.onBeforeCreated(anchor.ownerDocument);
+ },
+ onBeforeCreated(doc) {
+ // Bug 1223127, CUI should make this easier to do.
+ if (doc.getElementById("PanelUI-developerItems")) {
+ return;
+ }
+ let view = doc.createElement("panelview");
+ view.id = "PanelUI-developerItems";
+ let panel = doc.createElement("vbox");
+ panel.setAttribute("class", "panel-subview-body");
+ view.appendChild(panel);
+ doc.getElementById("PanelUI-multiView").appendChild(view);
+ }
+ };
+ CustomizableUI.createWidget(item);
+ CustomizableWidgets.push(item);
+ },
+
+ /*
* We listen to the "Web Developer" system menu, which is under "Tools" main item.
* This menu item is hardcoded empty in Firefox UI. We listen for its opening to
* populate it lazily. Loading main DevTools module is going to populate it.
*/
hookWebDeveloperMenu(window) {
let menu = window.document.getElementById("webDeveloperMenu");
menu.addEventListener("popupshowing", () => this.initDevTools(), { once: true });
},
--- a/devtools/client/framework/devtools-browser.js
+++ b/devtools/client/framework/devtools-browser.js
@@ -7,17 +7,17 @@
/**
* This is the main module loaded in Firefox desktop that handles browser
* windows and coordinates devtools around each window.
*
* This module is loaded lazily by devtools-clhandler.js, once the first
* browser window is ready (i.e. fired browser-delayed-startup-finished event)
**/
-const {Cc, Ci, Cu} = require("chrome");
+const {Cc, Ci} = require("chrome");
const Services = require("Services");
const defer = require("devtools/shared/defer");
const {gDevTools} = require("./devtools");
// Load target and toolbox lazily as they need gDevTools to be fully initialized
loader.lazyRequireGetter(this, "TargetFactory", "devtools/client/framework/target", true);
loader.lazyRequireGetter(this, "Toolbox", "devtools/client/framework/toolbox", true);
loader.lazyRequireGetter(this, "DebuggerServer", "devtools/server/main", true);
@@ -414,76 +414,16 @@ var gDevToolsBrowser = exports.gDevTools
});
} else {
let msg = L10N.getStr("toolbox.noContentProcessForTab.message");
Services.prompt.alert(null, "", msg);
}
},
/**
- * Install Developer widget
- */
- installDeveloperWidget() {
- let id = "developer-button";
- let widget = CustomizableUI.getWidget(id);
- if (widget && widget.provider == CustomizableUI.PROVIDER_API) {
- return;
- }
- let item = {
- id: id,
- type: "view",
- viewId: "PanelUI-developer",
- shortcutId: "key_devToolboxMenuItem",
- tooltiptext: "developer-button.tooltiptext2",
- defaultArea: AppConstants.MOZ_DEV_EDITION ?
- CustomizableUI.AREA_NAVBAR :
- CustomizableUI.AREA_PANEL,
- onViewShowing(event) {
- // Populate the subview with whatever menuitems are in the developer
- // menu. We skip menu elements, because the menu panel has no way
- // of dealing with those right now.
- let doc = event.target.ownerDocument;
-
- let menu = doc.getElementById("menuWebDeveloperPopup");
-
- let itemsToDisplay = [...menu.children];
- // Hardcode the addition of the "work offline" menuitem at the bottom:
- itemsToDisplay.push({localName: "menuseparator", getAttribute: () => {}});
- itemsToDisplay.push(doc.getElementById("goOfflineMenuitem"));
-
- let developerItems = doc.getElementById("PanelUI-developerItems");
- // Import private helpers from CustomizableWidgets
- let { clearSubview, fillSubviewFromMenuItems } =
- Cu.import("resource:///modules/CustomizableWidgets.jsm", {});
- clearSubview(developerItems);
- fillSubviewFromMenuItems(itemsToDisplay, developerItems);
- },
- onInit(anchor) {
- // Since onBeforeCreated already bails out when initialized, we can call
- // it right away.
- this.onBeforeCreated(anchor.ownerDocument);
- },
- onBeforeCreated(doc) {
- // Bug 1223127, CUI should make this easier to do.
- if (doc.getElementById("PanelUI-developerItems")) {
- return;
- }
- let view = doc.createElement("panelview");
- view.id = "PanelUI-developerItems";
- let panel = doc.createElement("vbox");
- panel.setAttribute("class", "panel-subview-body");
- view.appendChild(panel);
- doc.getElementById("PanelUI-multiView").appendChild(view);
- }
- };
- CustomizableUI.createWidget(item);
- CustomizableWidgets.push(item);
- },
-
- /**
* Install WebIDE widget
*/
// Used by itself
installWebIDEWidget() {
if (this.isWebIDEWidgetInstalled()) {
return;
}
@@ -546,20 +486,16 @@ var gDevToolsBrowser = exports.gDevTools
_registerBrowserWindow(win) {
if (gDevToolsBrowser._trackedBrowserWindows.has(win)) {
return;
}
gDevToolsBrowser._trackedBrowserWindows.add(win);
BrowserMenus.addMenus(win.document);
- // Register the Developer widget in the Hamburger menu or navbar
- // only once menus are registered as it depends on it.
- gDevToolsBrowser.installDeveloperWidget();
-
this.updateCommandAvailability(win);
this.updateDevtoolsThemeAttribute(win);
this.ensurePrefObserver();
win.addEventListener("unload", this);
let tabContainer = win.gBrowser.tabContainer;
tabContainer.addEventListener("TabSelect", this);
tabContainer.addEventListener("TabOpen", this);