Bug 1359855 - Prevent loading any DevTools module until users interact with any devtool entrypoint. r=jdescottes

MozReview-Commit-ID: 4rORySoFRQY

--HG--
extra : rebase_source : c7b41b0adc65d7b6e2273fb577f6738fe9e010c7
This commit is contained in:
Alexandre Poirot 2017-07-18 11:05:47 +02:00
parent fea81eb80e
commit be18a2c0f1
9 changed files with 397 additions and 258 deletions

View File

@ -30,8 +30,11 @@ loader.lazyRequireGetter(this, "CommandState", "devtools/shared/gcli/command-sta
loader.lazyImporter(this, "ResponsiveUIManager", "resource://devtools/client/responsivedesign/responsivedesign.jsm");
loader.lazyImporter(this, "ScratchpadManager", "resource://devtools/client/scratchpad/scratchpad-manager.jsm");
const {LocalizationHelper} = require("devtools/shared/l10n");
const L10N = new LocalizationHelper("devtools/client/locales/startup.properties");
const {MultiLocalizationHelper} = require("devtools/shared/l10n");
const L10N = new MultiLocalizationHelper(
"devtools/client/locales/startup.properties",
"devtools/client/locales/key-shortcuts.properties"
);
var Tools = {};
exports.Tools = Tools;
@ -62,9 +65,7 @@ Tools.options = {
Tools.inspector = {
id: "inspector",
accesskey: l10n("inspector.accesskey"),
key: l10n("inspector.commandkey"),
ordinal: 1,
modifiers: osString == "Darwin" ? "accel,alt" : "accel,shift",
icon: "chrome://devtools/skin/images/tool-inspector.svg",
invertIconForDarkTheme: true,
url: "chrome://devtools/content/inspector/inspector.xhtml",
@ -72,7 +73,8 @@ Tools.inspector = {
panelLabel: l10n("inspector.panelLabel"),
get tooltip() {
return l10n("inspector.tooltip2",
(osString == "Darwin" ? "Cmd+Opt+" : "Ctrl+Shift+") + this.key);
(osString == "Darwin" ? "Cmd+Opt+" : "Ctrl+Shift+") +
l10n("inspector.commandkey"));
},
inMenu: true,
commands: [
@ -95,9 +97,7 @@ Tools.inspector = {
};
Tools.webConsole = {
id: "webconsole",
key: l10n("cmd.commandkey"),
accesskey: l10n("webConsoleCmd.accesskey"),
modifiers: Services.appinfo.OS == "Darwin" ? "accel,alt" : "accel,shift",
ordinal: 2,
oldWebConsoleURL: "chrome://devtools/content/webconsole/webconsole.xul",
newWebConsoleURL: "chrome://devtools/content/webconsole/webconsole.xhtml",
@ -108,7 +108,8 @@ Tools.webConsole = {
panelLabel: l10n("ToolboxWebConsole.panelLabel"),
get tooltip() {
return l10n("ToolboxWebconsole.tooltip2",
(osString == "Darwin" ? "Cmd+Opt+" : "Ctrl+Shift+") + this.key);
(osString == "Darwin" ? "Cmd+Opt+" : "Ctrl+Shift+") +
l10n("webconsole.commandkey"));
},
inMenu: true,
commands: "devtools/client/webconsole/console-commands",
@ -146,9 +147,7 @@ Services.prefs.addObserver(
Tools.jsdebugger = {
id: "jsdebugger",
key: l10n("debuggerMenu.commandkey"),
accesskey: l10n("debuggerMenu.accesskey"),
modifiers: osString == "Darwin" ? "accel,alt" : "accel,shift",
ordinal: 3,
icon: "chrome://devtools/skin/images/tool-debugger.svg",
invertIconForDarkTheme: true,
@ -158,7 +157,8 @@ Tools.jsdebugger = {
panelLabel: l10n("ToolboxDebugger.panelLabel"),
get tooltip() {
return l10n("ToolboxDebugger.tooltip2",
(osString == "Darwin" ? "Cmd+Opt+" : "Ctrl+Shift+") + this.key);
(osString == "Darwin" ? "Cmd+Opt+" : "Ctrl+Shift+") +
l10n("debugger.commandkey"));
},
inMenu: true,
commands: "devtools/client/debugger/debugger-commands",
@ -194,11 +194,9 @@ Services.prefs.addObserver(
Tools.styleEditor = {
id: "styleeditor",
key: l10n("open.commandkey"),
ordinal: 4,
visibilityswitch: "devtools.styleeditor.enabled",
accesskey: l10n("open.accesskey"),
modifiers: "shift",
icon: "chrome://devtools/skin/images/tool-styleeditor.svg",
invertIconForDarkTheme: true,
url: "chrome://devtools/content/styleeditor/styleeditor.xul",
@ -206,7 +204,7 @@ Tools.styleEditor = {
panelLabel: l10n("ToolboxStyleEditor.panelLabel"),
get tooltip() {
return l10n("ToolboxStyleEditor.tooltip3",
"Shift+" + functionkey(this.key));
"Shift+" + functionkey(l10n("styleeditor.commandkey")));
},
inMenu: true,
commands: "devtools/client/styleeditor/styleeditor-commands",
@ -273,11 +271,10 @@ Tools.performance = {
label: l10n("performance.label"),
panelLabel: l10n("performance.panelLabel"),
get tooltip() {
return l10n("performance.tooltip", "Shift+" + functionkey(this.key));
return l10n("performance.tooltip", "Shift+" +
functionkey(l10n("performance.commandkey")));
},
accesskey: l10n("performance.accesskey"),
key: l10n("performance.commandkey"),
modifiers: "shift",
inMenu: true,
isTargetSupported: function (target) {
@ -313,9 +310,7 @@ Tools.memory = {
Tools.netMonitor = {
id: "netmonitor",
accesskey: l10n("netmonitor.accesskey"),
key: l10n("netmonitor.commandkey2"),
ordinal: 9,
modifiers: osString == "Darwin" ? "accel,alt" : "accel,shift",
visibilityswitch: "devtools.netmonitor.enabled",
icon: "chrome://devtools/skin/images/tool-network.svg",
invertIconForDarkTheme: true,
@ -324,7 +319,8 @@ Tools.netMonitor = {
panelLabel: l10n("netmonitor.panelLabel"),
get tooltip() {
return l10n("netmonitor.tooltip2",
(osString == "Darwin" ? "Cmd+Opt+" : "Ctrl+Shift+") + this.key);
(osString == "Darwin" ? "Cmd+Opt+" : "Ctrl+Shift+") +
l10n("netmonitor.commandkey"));
},
inMenu: true,
@ -339,10 +335,8 @@ Tools.netMonitor = {
Tools.storage = {
id: "storage",
key: l10n("storage.commandkey"),
ordinal: 10,
accesskey: l10n("storage.accesskey"),
modifiers: "shift",
visibilityswitch: "devtools.storage.enabled",
icon: "chrome://devtools/skin/images/tool-storage.svg",
invertIconForDarkTheme: true,
@ -351,7 +345,8 @@ Tools.storage = {
menuLabel: l10n("storage.menuLabel"),
panelLabel: l10n("storage.panelLabel"),
get tooltip() {
return l10n("storage.tooltip3", "Shift+" + functionkey(this.key));
return l10n("storage.tooltip3", "Shift+" +
functionkey(l10n("storage.commandkey")));
},
inMenu: true,
@ -410,9 +405,7 @@ Tools.scratchpad = {
Tools.dom = {
id: "dom",
accesskey: l10n("dom.accesskey"),
key: l10n("dom.commandkey"),
ordinal: 13,
modifiers: osString == "Darwin" ? "accel,alt" : "accel,shift",
visibilityswitch: "devtools.dom.enabled",
icon: "chrome://devtools/skin/images/tool-dom.svg",
invertIconForDarkTheme: true,
@ -421,7 +414,8 @@ Tools.dom = {
panelLabel: l10n("dom.panelLabel"),
get tooltip() {
return l10n("dom.tooltip",
(osString == "Darwin" ? "Cmd+Opt+" : "Ctrl+Shift+") + this.key);
(osString == "Darwin" ? "Cmd+Opt+" : "Ctrl+Shift+") +
l10n("dom.commandkey"));
},
inMenu: true,

View File

@ -4,11 +4,19 @@
/**
* This XPCOM component is loaded very early.
* It handles command line arguments like -jsconsole, but also ensures starting
* Be careful to lazy load dependencies as much as possible.
*
* It manages all the possible entry points for DevTools:
* - Handles command line arguments like -jsconsole,
* - Register all key shortcuts,
* - Listen for "Web Developer" system menu opening, under "Tools",
* - Inject the wrench icon in toolbar customization, which is used
* by the "Web Developer" list displayed in the hamburger menu,
* - Register the JSON Viewer protocol handler.
*
* Only once any of these entry point is fired, this module ensures starting
* core modules like 'devtools-browser.js' that hooks the browser windows
* and ensure setting up tools.
*
* Be careful to lazy load dependencies as much as possible.
**/
"use strict";
@ -19,7 +27,131 @@ const kDebuggerPrefs = [
"devtools.chrome.enabled"
];
const { XPCOMUtils } = Cu.import("resource://gre/modules/XPCOMUtils.jsm", {});
XPCOMUtils.defineLazyModuleGetter(this, "Services", "resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Services",
"resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "AppConstants",
"resource://gre/modules/AppConstants.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";
// Common modifier shared by most key shortcuts
const modifiers = isMac ? "accel,alt" : "accel,shift";
// List of all key shortcuts triggering installation UI
// `id` should match tool's id from client/definitions.js
return [
// The following keys are also registered in /client/menus.js
// And should be synced.
// Both are toggling the toolbox on the last selected panel
// or the default one.
{
id: "toggleToolbox",
shortcut: Bundle.GetStringFromName("toggleToolbox.commandkey"),
modifiers
},
// All locales are using F12
{
id: "toggleToolboxF12",
shortcut: Bundle.GetStringFromName("toggleToolboxF12.commandkey"),
modifiers: "" // F12 is the only one without modifiers
},
// Toggle the visibility of the Developer Toolbar (=gcli)
{
id: "toggleToolbar",
shortcut: Bundle.GetStringFromName("toggleToolbar.commandkey"),
modifiers: "shift"
},
// Open WebIDE window
{
id: "webide",
shortcut: Bundle.GetStringFromName("webide.commandkey"),
modifiers: "shift"
},
// Open the Browser Toolbox
{
id: "browserToolbox",
shortcut: Bundle.GetStringFromName("browserToolbox.commandkey"),
modifiers: "accel,alt,shift"
},
// Open the Browser Console
{
id: "browserConsole",
shortcut: Bundle.GetStringFromName("browserConsole.commandkey"),
modifiers: "accel,shift"
},
// Toggle the Responsive Design Mode
{
id: "responsiveDesignMode",
shortcut: Bundle.GetStringFromName("responsiveDesignMode.commandkey"),
modifiers
},
// Open ScratchPad window
{
id: "scratchpad",
shortcut: Bundle.GetStringFromName("scratchpad.commandkey"),
modifiers: "shift"
},
// The following keys are also registered in /client/definitions.js
// and should be synced.
// Key for opening the Inspector
{
toolId: "inspector",
shortcut: Bundle.GetStringFromName("inspector.commandkey"),
modifiers
},
// Key for opening the Web Console
{
toolId: "webconsole",
shortcut: Bundle.GetStringFromName("webconsole.commandkey"),
modifiers
},
// Key for opening the Debugger
{
toolId: "jsdebugger",
shortcut: Bundle.GetStringFromName("debugger.commandkey"),
modifiers
},
// Key for opening the Network Monitor
{
toolId: "netmonitor",
shortcut: Bundle.GetStringFromName("netmonitor.commandkey"),
modifiers
},
// Key for opening the Style Editor
{
toolId: "styleeditor",
shortcut: Bundle.GetStringFromName("styleeditor.commandkey"),
modifiers: "shift"
},
// Key for opening the Performance Panel
{
toolId: "performance",
shortcut: Bundle.GetStringFromName("performance.commandkey"),
modifiers: "shift"
},
// Key for opening the Storage Panel
{
toolId: "storage",
shortcut: Bundle.GetStringFromName("storage.commandkey"),
modifiers: "shift"
},
// Key for opening the DOM Panel
{
toolId: "dom",
shortcut: Bundle.GetStringFromName("dom.commandkey"),
modifiers
},
];
});
function DevToolsStartup() {}
@ -48,24 +180,104 @@ DevToolsStartup.prototype = {
this.handleDebuggerServerFlag(cmdLine, debuggerServerFlag);
}
let onStartup = window => {
Services.obs.removeObserver(onStartup,
"browser-delayed-startup-finished");
// Ensure loading core module once firefox is ready
this.initDevTools();
let onWindowReady = window => {
this.hookWindow(window);
if (devtoolsFlag) {
this.handleDevToolsFlag(window);
// This listener is called for all Firefox windows, but we want to execute
// that command only once
devtoolsFlag = false;
}
};
Services.obs.addObserver(onStartup, "browser-delayed-startup-finished");
Services.obs.addObserver(onWindowReady, "browser-delayed-startup-finished");
},
/**
* Register listeners to all possible entry points for Developer Tools.
* But instead of implementing the actual actions, defer to DevTools codebase.
* In most cases, it only needs to call this.initDevTools which handles the rest.
* We do that to prevent loading any DevTools module until the user intent to use them.
*/
hookWindow(window) {
this.hookKeyShortcuts(window);
// All the other hooks are only necessary if the tools aren't loaded yet.
if (this.initialized) {
return;
}
this.hookWebDeveloperMenu(window);
},
/**
* 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 });
},
hookKeyShortcuts(window) {
let doc = window.document;
let keyset = doc.createElement("keyset");
keyset.setAttribute("id", "devtoolsKeyset");
for (let key of KeyShortcuts) {
let xulKey = this.createKey(doc, key, () => this.onKey(window, key));
keyset.appendChild(xulKey);
}
// Appending a <key> element is not always enough. The <keyset> needs
// to be detached and reattached to make sure the <key> is taken into
// account (see bug 832984).
let mainKeyset = doc.getElementById("mainKeyset");
mainKeyset.parentNode.insertBefore(keyset, mainKeyset);
},
onKey(window, key) {
let require = this.initDevTools();
let { gDevToolsBrowser } = require("devtools/client/framework/devtools-browser");
gDevToolsBrowser.onKeyShortcut(window, key);
},
// Create a <xul:key> DOM Element
createKey(doc, { id, toolId, shortcut, modifiers: mod }, oncommand) {
let k = doc.createElement("key");
k.id = "key_" + (id || toolId);
if (shortcut.startsWith("VK_")) {
k.setAttribute("keycode", shortcut);
} else {
k.setAttribute("key", shortcut);
}
if (mod) {
k.setAttribute("modifiers", mod);
}
// Bug 371900: command event is fired only if "oncommand" attribute is set.
k.setAttribute("oncommand", ";");
k.addEventListener("command", oncommand);
return k;
},
/**
* Boolean flag to check if DevTools have been already initialized or not.
* By initialized, we mean that its main modules are loaded.
*/
initialized: false,
initDevTools: function () {
let { loader } = Cu.import("resource://devtools/shared/Loader.jsm", {});
this.initialized = true;
let { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
// Ensure loading main devtools module that hooks up into browser UI
// and initialize all devtools machinery.
loader.require("devtools/client/framework/devtools-browser");
require("devtools/client/framework/devtools-browser");
return require;
},
handleConsoleFlag: function (cmdLine) {
@ -89,7 +301,7 @@ DevToolsStartup.prototype = {
// Open the toolbox on the selected tab once the browser starts up.
handleDevToolsFlag: function (window) {
const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
const require = this.initDevTools();
const {gDevTools} = require("devtools/client/framework/devtools");
const {TargetFactory} = require("devtools/client/framework/target");
let target = TargetFactory.forTab(window.gBrowser.selectedTab);

View File

@ -5,9 +5,9 @@
"use strict";
/**
* This module inject dynamically menu items and key shortcuts into browser UI.
* This module inject dynamically menu items into browser UI.
*
* Menu and shortcut definitions are fetched from:
* Menu definitions are fetched from:
* - devtools/client/menus for top level entires
* - devtools/client/definitions for tool-specifics entries
*/
@ -26,54 +26,11 @@ function l10n(key) {
return MENUS_L10N.getStr(key);
}
/**
* Create a xul:key element
*
* @param {XULDocument} doc
* The document to which keys are to be added.
* @param {String} id
* key's id, automatically prefixed with "key_".
* @param {String} shortcut
* The key shortcut value.
* @param {String} keytext
* If `shortcut` refers to a function key, refers to the localized
* string to describe a non-character shortcut.
* @param {String} modifiers
* Space separated list of modifier names.
* @param {Function} oncommand
* The function to call when the shortcut is pressed.
*
* @return XULKeyElement
*/
function createKey({ doc, id, shortcut, keytext, modifiers, oncommand }) {
let k = doc.createElement("key");
k.id = "key_" + id;
if (shortcut.startsWith("VK_")) {
k.setAttribute("keycode", shortcut);
if (keytext) {
k.setAttribute("keytext", keytext);
}
} else {
k.setAttribute("key", shortcut);
}
if (modifiers) {
k.setAttribute("modifiers", modifiers);
}
// Bug 371900: command event is fired only if "oncommand" attribute is set.
k.setAttribute("oncommand", ";");
k.addEventListener("command", oncommand);
return k;
}
/**
* Create a xul:menuitem element
*
* @param {XULDocument} doc
* The document to which keys are to be added.
* The document to which menus are to be added.
* @param {String} id
* Element id.
* @param {String} label
@ -100,29 +57,6 @@ function createMenuItem({ doc, id, label, accesskey, isCheckbox }) {
return menuitem;
}
/**
* Add a <key> to <keyset id="devtoolsKeyset">.
* Appending a <key> element is not always enough. The <keyset> needs
* to be detached and reattached to make sure the <key> is taken into
* account (see bug 832984).
*
* @param {XULDocument} doc
* The document to which keys are to be added
* @param {XULElement} or {DocumentFragment} keys
* Keys to add
*/
function attachKeybindingsToBrowser(doc, keys) {
let devtoolsKeyset = doc.getElementById("devtoolsKeyset");
if (!devtoolsKeyset) {
devtoolsKeyset = doc.createElement("keyset");
devtoolsKeyset.setAttribute("id", "devtoolsKeyset");
}
devtoolsKeyset.appendChild(keys);
let mainKeyset = doc.getElementById("mainKeyset");
mainKeyset.parentNode.insertBefore(devtoolsKeyset, mainKeyset);
}
/**
* Add a menu entry for a tool definition
*
@ -145,31 +79,18 @@ function createToolMenuElements(toolDefinition, doc) {
gDevToolsBrowser.selectToolCommand(window.gBrowser, id);
}.bind(null, id);
let key = null;
if (toolDefinition.key) {
key = createKey({
doc,
id,
shortcut: toolDefinition.key,
modifiers: toolDefinition.modifiers,
oncommand: oncommand
});
}
let menuitem = createMenuItem({
doc,
id: "menuitem_" + id,
label: toolDefinition.menuLabel || toolDefinition.label,
accesskey: toolDefinition.accesskey
});
if (key) {
// Refer to the key in order to display the key shortcut at menu ends
menuitem.setAttribute("key", key.id);
}
// Refer to the key in order to display the key shortcut at menu ends
// This <key> element is being created by devtools/client/devtools-startup.js
menuitem.setAttribute("key", "key_" + id);
menuitem.addEventListener("command", oncommand);
return {
key,
menuitem
};
}
@ -186,11 +107,7 @@ function createToolMenuElements(toolDefinition, doc) {
* The tool definition after which the tool menu item is to be added.
*/
function insertToolMenuElements(doc, toolDefinition, prevDef) {
let { key, menuitem } = createToolMenuElements(toolDefinition, doc);
if (key) {
attachKeybindingsToBrowser(doc, key);
}
let { menuitem } = createToolMenuElements(toolDefinition, doc);
let ref;
if (prevDef) {
@ -254,8 +171,6 @@ function addAllToolsToMenu(doc) {
fragMenuItems.appendChild(elements.menuitem);
}
attachKeybindingsToBrowser(doc, fragKeys);
let mps = doc.getElementById("menu_devtools_separator");
if (mps) {
mps.parentNode.insertBefore(fragMenuItems, mps);
@ -263,13 +178,12 @@ function addAllToolsToMenu(doc) {
}
/**
* Add global menus and shortcuts that are not panel specific.
* Add global menus that are not panel specific.
*
* @param {XULDocument} doc
* The document to which keys and menus are to be added.
* The document to which menus are to be added.
*/
function addTopLevelItems(doc) {
let keys = doc.createDocumentFragment();
let menuItems = doc.createDocumentFragment();
let { menuitems } = require("../menus");
@ -292,51 +206,19 @@ function addTopLevelItems(doc) {
menuitem.addEventListener("command", item.oncommand);
menuItems.appendChild(menuitem);
if (item.key && l10nKey) {
// Create a <key>
let shortcut = l10n(l10nKey + ".key");
let key = createKey({
doc,
id: item.key.id,
shortcut: shortcut,
keytext: shortcut.startsWith("VK_") ? l10n(l10nKey + ".keytext") : null,
modifiers: item.key.modifiers,
oncommand: item.oncommand
});
// Refer to the key in order to display the key shortcut at menu ends
menuitem.setAttribute("key", key.id);
keys.appendChild(key);
}
if (item.additionalKeys) {
// Create additional <key>
for (let key of item.additionalKeys) {
let shortcut = l10n(key.l10nKey + ".key");
let node = createKey({
doc,
id: key.id,
shortcut: shortcut,
keytext: shortcut.startsWith("VK_") ? l10n(key.l10nKey + ".keytext") : null,
modifiers: key.modifiers,
oncommand: item.oncommand
});
keys.appendChild(node);
}
if (item.keyId) {
menuitem.setAttribute("key", "key_" + item.keyId);
}
}
}
// Cache all nodes before insertion to be able to remove them on unload
let nodes = [];
for (let node of keys.children) {
nodes.push(node);
}
for (let node of menuItems.children) {
nodes.push(node);
}
FragmentsCache.set(doc, nodes);
attachKeybindingsToBrowser(doc, keys);
let menu = doc.getElementById("menuWebDeveloperPopup");
menu.appendChild(menuItems);
@ -349,10 +231,10 @@ function addTopLevelItems(doc) {
}
/**
* Remove global menus and shortcuts that are not panel specific.
* Remove global menus that are not panel specific.
*
* @param {XULDocument} doc
* The document to which keys and menus are to be added.
* The document to which menus are to be added.
*/
function removeTopLevelItems(doc) {
let nodes = FragmentsCache.get(doc);
@ -366,10 +248,10 @@ function removeTopLevelItems(doc) {
}
/**
* Add menus and shortcuts to a browser document
* Add menus to a browser document
*
* @param {XULDocument} doc
* The document to which keys and menus are to be added.
* The document to which menus are to be added.
*/
exports.addMenus = function (doc) {
addTopLevelItems(doc);
@ -378,10 +260,10 @@ exports.addMenus = function (doc) {
};
/**
* Remove menus and shortcuts from a browser document
* Remove menus from a browser document
*
* @param {XULDocument} doc
* The document to which keys and menus are to be removed.
* The document to which menus are to be removed.
*/
exports.removeMenus = function (doc) {
// We only remove top level entries. Per-tool entries are removed while

View File

@ -25,6 +25,9 @@ loader.lazyRequireGetter(this, "DebuggerClient", "devtools/shared/client/main",
loader.lazyRequireGetter(this, "BrowserMenus", "devtools/client/framework/browser-menus");
loader.lazyRequireGetter(this, "appendStyleSheet", "devtools/client/shared/stylesheet-utils", true);
loader.lazyRequireGetter(this, "DeveloperToolbar", "devtools/client/shared/developer-toolbar", true);
loader.lazyImporter(this, "BrowserToolboxProcess", "resource://devtools/client/framework/ToolboxProcess.jsm");
loader.lazyImporter(this, "ResponsiveUIManager", "resource://devtools/client/responsivedesign/responsivedesign.jsm");
loader.lazyImporter(this, "ScratchpadManager", "resource://devtools/client/scratchpad/scratchpad-manager.jsm");
loader.lazyImporter(this, "CustomizableUI", "resource:///modules/CustomizableUI.jsm");
loader.lazyImporter(this, "CustomizableWidgets", "resource:///modules/CustomizableWidgets.jsm");
@ -274,6 +277,53 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
}
},
/**
* Called by devtools/client/devtools-startup.js when a key shortcut is pressed
*
* @param {Window} window
* The top level browser window from which the key shortcut is pressed.
* @param {Object} key
* Key object describing the key shortcut being pressed. It comes
* from devtools-startup.js's KeyShortcuts array. The useful fields here
* are:
* - `toolId` used to identify a toolbox's panel like inspector or webconsole,
* - `id` used to identify any other key shortcuts like scratchpad or
* about:debugging
*/
onKeyShortcut(window, key) {
// If this is a toolbox's panel key shortcut, delegate to selectToolCommand
if (key.toolId) {
gDevToolsBrowser.selectToolCommand(window.gBrowser, key.toolId);
return;
}
// Otherwise implement all other key shortcuts individually here
switch (key.id) {
case "toggleToolbox":
case "toggleToolboxF12":
gDevToolsBrowser.toggleToolboxCommand(window.gBrowser);
break;
case "toggleToolbar":
window.DeveloperToolbar.focusToggle();
break;
case "webide":
gDevToolsBrowser.openWebIDE();
break;
case "browserToolbox":
BrowserToolboxProcess.init();
break;
case "browserConsole":
let HUDService = require("devtools/client/webconsole/hudservice");
HUDService.openBrowserConsoleOrFocus();
break;
case "responsiveDesignMode":
ResponsiveUIManager.toggle(window, window.gBrowser.selectedTab);
break;
case "scratchpad":
ScratchpadManager.openScratchpad();
break;
}
},
/**
* Open a tab on "about:debugging", optionally pre-select a given tab.
*/

View File

@ -0,0 +1,67 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# LOCALIZATION NOTE (toogleToolbox.commandkey):
# Key pressed to open a toolbox with the default panel selected
toggleToolbox.commandkey=I
# LOCALIZATION NOTE (toogleToolboxF12.commandkey):
# Alternative key pressed to open a toolbox with the default panel selected
toggleToolboxF12.commandkey=VK_F12
# LOCALIZATION NOTE (toogleToolbar.commandkey):
# Key pressed to open the Developer Toolbar (a.k.a gcli)
toggleToolbar.commandkey=VK_F2
# LOCALIZATION NOTE (webide.commandkey):
# Key pressed to open the Web IDE window
webide.commandkey=VK_F8
# LOCALIZATION NOTE (browserToolbox.commandkey):
# Key pressed to open the Browser Toolbox, used for debugging Firefox itself
browserToolbox.commandkey=I
# LOCALIZATION NOTE (browserConsole.commandkey):
# Key pressed to open the Browser Console, used for debugging Firefox itself
browserConsole.commandkey=J
# LOCALIZATION NOTE (responsiveDesignMode.commandkey):
# Key pressed to toggle on the Responsive Design Mode
responsiveDesignMode.commandkey=M
# LOCALIZATION NOTE (scratchpad.commandkey):
# Key pressed to open the Scratchpad in its own window
scratchpad.commandkey=VK_F4
# LOCALIZATION NOTE (inspector.commandkey):
# Key pressed to open a toolbox with the inspector panel selected
inspector.commandkey=C
# LOCALIZATION NOTE (webconsole.commandkey):
# Key pressed to open a toolbox with the web console panel selected
webconsole.commandkey=K
# LOCALIZATION NOTE (debugger.commandkey):
# Key pressed to open a toolbox with the debugger panel selected
debugger.commandkey=S
# LOCALIZATION NOTE (netmonitor.commandkey):
# Key pressed to open a toolbox with the network monitor panel selected
netmonitor.commandkey=E
# LOCALIZATION NOTE (styleeditor.commandkey):
# Key pressed to open a toolbox with the style editor panel selected
styleeditor.commandkey=VK_F7
# LOCALIZATION NOTE (performance.commandkey):
# Key pressed to open a toolbox with the performance panel selected
performance.commandkey=VK_F5
# LOCALIZATION NOTE (storage.commandkey):
# Key pressed to open a toolbox with the storage panel selected
storage.commandkey=VK_F9
# LOCALIZATION NOTE (dom.commandkey):
# Key pressed to open a toolbox with the DOM panel selected
dom.commandkey=W

View File

@ -2,9 +2,6 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
devToolsCmd.key = VK_F12
devToolsCmd.keytext = F12
devtoolsServiceWorkers.label = Service Workers
devtoolsServiceWorkers.accesskey = k
@ -13,11 +10,9 @@ devtoolsConnect.accesskey = C
browserConsoleCmd.label = Browser Console
browserConsoleCmd.accesskey = B
browserConsoleCmd.key = j
responsiveDesignMode.label = Responsive Design Mode
responsiveDesignMode.accesskey = R
responsiveDesignMode.key = M
eyedropper.label = Eyedropper
eyedropper.accesskey = Y
@ -34,14 +29,11 @@ eyedropper.accesskey = Y
# "simple discardable text editor".
scratchpad.label = Scratchpad
scratchpad.accesskey = s
scratchpad.key = VK_F4
scratchpad.keytext = F4
# LOCALIZATION NOTE (browserToolboxMenu.label): This is the label for the
# application menu item that opens the browser toolbox UI in the Tools menu.
browserToolboxMenu.label = Browser Toolbox
browserToolboxMenu.accesskey = e
browserToolboxMenu.key = i
# LOCALIZATION NOTE (browserContentToolboxMenu.label): This is the label for the
# application menu item that opens the browser content toolbox UI in the Tools menu.
@ -51,17 +43,12 @@ browserContentToolboxMenu.accesskey = x
devToolbarMenu.label = Developer Toolbar
devToolbarMenu.accesskey = v
devToolbarMenu.key = VK_F2
devToolbarMenu.keytext = F2
webide.label = WebIDE
webide.accesskey = W
webide.key = VK_F8
webide.keytext = F8
devToolboxMenuItem.label = Toggle Tools
devToolboxMenuItem.accesskey = T
devToolboxMenuItem.key = I
getMoreDevtoolsCmd.label = Get More Tools
getMoreDevtoolsCmd.accesskey = M

View File

@ -35,9 +35,8 @@ performance.label=Performance
# This is used as the label for the toolbox panel.
performance.panelLabel=Performance Panel
# LOCALIZATION NOTE (performance.commandkey, performance.accesskey)
# LOCALIZATION NOTE (performance.accesskey)
# Used for the menuitem in the tool menu
performance.commandkey=VK_F5
performance.accesskey=P
# LOCALIZATION NOTE (performance.tooltip):
@ -64,7 +63,6 @@ ToolboxWebConsole.panelLabel=Console Panel
# Keyboard shortcut for Console will be shown inside the brackets.
ToolboxWebconsole.tooltip2=Web Console (%S)
cmd.commandkey=K
webConsoleCmd.accesskey=W
# LOCALIZATION NOTE (ToolboxDebugger.label):
@ -82,9 +80,8 @@ ToolboxDebugger.panelLabel=Debugger Panel
# A keyboard shortcut for JS Debugger will be shown inside brackets.
ToolboxDebugger.tooltip2=JavaScript Debugger (%S)
# LOCALIZATION NOTE (debuggerMenu.commandkey, debuggerMenu.accesskey)
# LOCALIZATION NOTE (debuggerMenu.accesskey)
# Used for the menuitem in the tool menu
debuggerMenu.commandkey=S
debuggerMenu.accesskey=D
# LOCALIZATION NOTE (ToolboxStyleEditor.label):
@ -102,10 +99,6 @@ ToolboxStyleEditor.panelLabel=Style Editor Panel
# A keyboard shortcut for Stylesheet Editor will be shown inside the latter pair of brackets.
ToolboxStyleEditor.tooltip3=Stylesheet Editor (CSS) (%S)
# LOCALIZATION NOTE (open.commandkey): This the key to use in
# conjunction with shift to open the style editor
open.commandkey=VK_F7
# LOCALIZATION NOTE (open.accesskey): The access key used to open the style
# editor.
open.accesskey=l
@ -155,7 +148,6 @@ ToolboxWebAudioEditor1.tooltip=Web Audio context visualizer and audio node inspe
# LOCALIZATION NOTE (inspector.*)
# Used for the menuitem in the tool menu
inspector.label=Inspector
inspector.commandkey=C
inspector.accesskey=I
# LOCALIZATION NOTE (inspector.panelLabel)
@ -175,9 +167,8 @@ netmonitor.label=Network
# This is used as the label for the toolbox panel.
netmonitor.panelLabel=Network Panel
# LOCALIZATION NOTE (netmonitor.commandkey2, netmonitor.accesskey)
# LOCALIZATION NOTE (netmonitor.accesskey)
# Used for the menuitem in the tool menu
netmonitor.commandkey2=E
netmonitor.accesskey=N
# LOCALIZATION NOTE (netmonitor.tooltip2):
@ -186,10 +177,6 @@ netmonitor.accesskey=N
# Keyboard shortcut for Network Monitor will be shown inside the brackets.
netmonitor.tooltip2=Network Monitor (%S)
# LOCALIZATION NOTE (storage.commandkey): This the key to use in
# conjunction with shift to open the storage editor
storage.commandkey=VK_F9
# LOCALIZATION NOTE (storage.accesskey): The access key used to open the storage
# editor.
storage.accesskey=a
@ -250,9 +237,8 @@ dom.label=DOM
# This is used as the label for the toolbox panel.
dom.panelLabel=DOM Panel
# LOCALIZATION NOTE (dom.commandkey, dom.accesskey)
# LOCALIZATION NOTE (dom.accesskey)
# Used for the menuitem in the tool menu
dom.commandkey=W
dom.accesskey=D
# LOCALIZATION NOTE (dom.tooltip):

View File

@ -16,15 +16,10 @@
* prefix used to locale localization strings from menus.properties
* - oncommand:
* function called when the menu item or key shortcut are fired
* - key:
* - id:
* prefixed by 'key_' to compute <xul:key> id attribute
* - modifiers:
* optional modifiers for the key shortcut
* - keytext:
* boolean, to set to true for key shortcut using regular character
* - additionalKeys:
* Array of additional keys, see `key` definition.
* - keyId:
* Identifier used in devtools/client/devtools-startup.js
* Helps figuring out the DOM id for the related <xul:key>
* in order to have the key text displayed in menus.
* - disabled:
* If true, the menuitem and key shortcut are going to be hidden and disabled
* on startup, until some runtime code eventually enable them.
@ -33,9 +28,6 @@
* toggle it.
*/
const Services = require("Services");
const isMac = Services.appinfo.OS === "Darwin";
loader.lazyRequireGetter(this, "gDevToolsBrowser", "devtools/client/framework/devtools-browser", true);
loader.lazyRequireGetter(this, "CommandUtils", "devtools/client/shared/developer-toolbar", true);
loader.lazyRequireGetter(this, "TargetFactory", "devtools/client/framework/target", true);
@ -51,17 +43,7 @@ exports.menuitems = [
let window = event.target.ownerDocument.defaultView;
gDevToolsBrowser.toggleToolboxCommand(window.gBrowser);
},
key: {
id: "devToolboxMenuItem",
modifiers: isMac ? "accel,alt" : "accel,shift",
// This is the only one with a letter key
// and needs to be translated differently
keytext: true,
},
additionalKeys: [{
id: "devToolboxMenuItemF12",
l10nKey: "devToolsCmd",
}],
keyId: "toggleToolbox",
checkbox: true
},
{ id: "menu_devtools_separator",
@ -80,10 +62,7 @@ exports.menuitems = [
gDevToolsBrowser.getDeveloperToolbar(window).focusToggle();
}
},
key: {
id: "devToolbar",
modifiers: "shift"
},
keyId: "toggleToolbar",
checkbox: true
},
{ id: "menu_webide",
@ -92,10 +71,7 @@ exports.menuitems = [
oncommand() {
gDevToolsBrowser.openWebIDE();
},
key: {
id: "webide",
modifiers: "shift"
}
keyId: "webide",
},
{ id: "menu_browserToolbox",
l10nKey: "browserToolboxMenu",
@ -103,11 +79,7 @@ exports.menuitems = [
oncommand() {
BrowserToolboxProcess.init();
},
key: {
id: "browserToolbox",
modifiers: "accel,alt,shift",
keytext: true
}
keyId: "browserToolbox",
},
{ id: "menu_browserContentToolbox",
l10nKey: "browserContentToolboxMenu",
@ -123,11 +95,7 @@ exports.menuitems = [
let HUDService = require("devtools/client/webconsole/hudservice");
HUDService.openBrowserConsoleOrFocus();
},
key: {
id: "browserConsole",
modifiers: "accel,shift",
keytext: true
}
keyId: "browserConsole",
},
{ id: "menu_responsiveUI",
l10nKey: "responsiveDesignMode",
@ -135,11 +103,7 @@ exports.menuitems = [
let window = event.target.ownerDocument.defaultView;
ResponsiveUIManager.toggle(window, window.gBrowser.selectedTab);
},
key: {
id: "responsiveUI",
modifiers: isMac ? "accel,alt" : "accel,shift",
keytext: true
},
keyId: "responsiveDesignMode",
checkbox: true
},
{ id: "menu_eyedropper",
@ -157,10 +121,7 @@ exports.menuitems = [
oncommand() {
ScratchpadManager.openScratchpad();
},
key: {
id: "scratchpad",
modifiers: "shift"
}
keyId: "scratchpad",
},
{ id: "menu_devtools_serviceworkers",
l10nKey: "devtoolsServiceWorkers",

View File

@ -12,7 +12,7 @@ add_task(function* () {
let STARTUP_L10N = new LocalizationHelper("devtools/client/locales/startup.properties");
let TOOLBOX_L10N = new LocalizationHelper("devtools/client/locales/toolbox.properties");
let str1 = STARTUP_L10N.getStr("inspector.label");
let str2 = STARTUP_L10N.getStr("inspector.commandkey");
let str2 = STARTUP_L10N.getStr("inspector.accesskey");
let str3 = TOOLBOX_L10N.getStr("toolbox.defaultTitle");
ok(str1 && str2 && str3, "If this failed, strings should be updated in the test");
@ -22,11 +22,11 @@ add_task(function* () {
`<div data-localization-bundle="devtools/client/locales/startup.properties">
<div id="d0" data-localization="content=inspector.someInvalidKey"></div>
<div id="d1" data-localization="content=inspector.label">Text will disappear</div>
<div id="d2" data-localization="content=inspector.label;title=inspector.commandkey">
<div id="d2" data-localization="content=inspector.label;title=inspector.accesskey">
</div>
<!-- keep the following data-localization on two separate lines -->
<div id="d3" data-localization="content=inspector.label;
title=inspector.commandkey"></div>
title=inspector.accesskey"></div>
<div id="d4" data-localization="aria-label=inspector.label">Some content</div>
<div data-localization-bundle="devtools/client/locales/toolbox.properties">
<div id="d5" data-localization="content=toolbox.defaultTitle"></div>