mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Bug 1307227 - Integrate the profiler popup widget into the browser; r=jdescottes
This commit takes the popup, and wires it up the button using the CustomizableUI interface. It is integrated with the DevTools initialization code. Differential Revision: https://phabricator.services.mozilla.com/D31629 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
ae0bdac16c
commit
eccc1fe1ef
@ -625,6 +625,10 @@
|
||||
<vbox id="PanelUI-developerItems" class="panel-subview-body"/>
|
||||
</panelview>
|
||||
|
||||
<panelview id="PanelUI-profiler" flex="1">
|
||||
<iframe id="PanelUI-profilerIframe" className="PanelUI-developer-iframe" />
|
||||
</panelview>
|
||||
|
||||
<panelview id="PanelUI-characterEncodingView" flex="1">
|
||||
<vbox class="panel-subview-body">
|
||||
<vbox id="PanelUI-characterEncodingView-pinned"
|
||||
|
@ -29,6 +29,9 @@ developer-button.label = Developer
|
||||
# LOCALIZATION NOTE(developer-button.tooltiptext): %S is the keyboard shortcut
|
||||
developer-button.tooltiptext2 = Open Web developer tools (%S)
|
||||
|
||||
profiler-button.label = Profiler
|
||||
profiler-button.tooltiptext = Record a performance profile
|
||||
|
||||
sidebar-button.label = Sidebars
|
||||
sidebar-button.tooltiptext2 = Show sidebars
|
||||
|
||||
|
@ -250,6 +250,14 @@ toolbar[brighttext] {
|
||||
list-style-image: url("chrome://browser/skin/developer.svg");
|
||||
}
|
||||
|
||||
#profiler-button {
|
||||
list-style-image: url("chrome://devtools/skin/images/profiler-stopwatch.svg");
|
||||
}
|
||||
|
||||
#PanelUI-profilerIframe {
|
||||
width: 352px;
|
||||
}
|
||||
|
||||
#preferences-button {
|
||||
list-style-image: url("chrome://browser/skin/settings.svg");
|
||||
}
|
||||
|
@ -29,12 +29,10 @@ devtools.jar:
|
||||
content/performance/index.xul (performance/index.xul)
|
||||
content/performance-new/index.xhtml (performance-new/index.xhtml)
|
||||
content/performance-new/frame-script.js (performance-new/frame-script.js)
|
||||
content/performance-new/popup/background.jsm (performance-new/popup/background.jsm)
|
||||
content/performance-new/popup/icons/capture-profile-icon.svg (performance-new/popup/icons/capture-profile-icon.svg)
|
||||
content/performance-new/popup/initializer.js (performance-new/popup/initializer.js)
|
||||
content/performance-new/popup/popup.css (performance-new/popup/popup.css)
|
||||
content/performance-new/popup/popup.html (performance-new/popup/popup.html)
|
||||
content/performance-new/popup/popup.js (performance-new/popup/popup.js)
|
||||
content/memory/index.xhtml (memory/index.xhtml)
|
||||
content/framework/toolbox-window.xul (framework/toolbox-window.xul)
|
||||
content/framework/toolbox-options.xhtml (framework/toolbox-options.xhtml)
|
||||
|
@ -44,6 +44,11 @@ browserToolboxMenu.accesskey = e
|
||||
browserContentToolboxMenu.label = Browser Content Toolbox
|
||||
browserContentToolboxMenu.accesskey = x
|
||||
|
||||
# LOCALIZATION NOTE (toggleProfilerButtonMenu.label): This is the label for the
|
||||
# application menu item that toggles the profiler button to record performance profiles.
|
||||
toggleProfilerButtonMenu.label = Enable Profiler Toolbar Icon
|
||||
toggleProfilerButtonMenu.accesskey = P
|
||||
|
||||
webide.label = WebIDE
|
||||
webide.accesskey = W
|
||||
|
||||
|
@ -38,6 +38,7 @@ loader.lazyRequireGetter(this, "openDocLink", "devtools/client/shared/link", tru
|
||||
|
||||
loader.lazyImporter(this, "BrowserToolboxProcess", "resource://devtools/client/framework/ToolboxProcess.jsm");
|
||||
loader.lazyImporter(this, "ScratchpadManager", "resource://devtools/client/scratchpad/scratchpad-manager.jsm");
|
||||
loader.lazyImporter(this, "ProfilerMenuButton", "resource://devtools/client/performance-new/popup/menu-button.jsm");
|
||||
|
||||
const isAboutDebuggingEnabled =
|
||||
Services.prefs.getBoolPref("devtools.aboutdebugging.new-enabled", false);
|
||||
@ -100,6 +101,13 @@ exports.menuitems = [
|
||||
},
|
||||
keyId: "browserConsole",
|
||||
},
|
||||
{ id: "menu_toggleProfilerButtonMenu",
|
||||
l10nKey: "toggleProfilerButtonMenu",
|
||||
checkbox: true,
|
||||
oncommand(event) {
|
||||
ProfilerMenuButton.toggle(event.target.ownerDocument);
|
||||
},
|
||||
},
|
||||
{ id: "menu_responsiveUI",
|
||||
l10nKey: "responsiveDesignMode",
|
||||
oncommand(event) {
|
||||
|
150
devtools/client/performance-new/popup/menu-button.jsm
Normal file
150
devtools/client/performance-new/popup/menu-button.jsm
Normal file
@ -0,0 +1,150 @@
|
||||
/* 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/. */
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* This file controls the enabling and disabling of the menu button for the profiler.
|
||||
* Care should be taken to keep it minimal as it can be run with browser initialization.
|
||||
*/
|
||||
|
||||
ChromeUtils.defineModuleGetter(this, "Services",
|
||||
"resource://gre/modules/Services.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "CustomizableUI",
|
||||
"resource:///modules/CustomizableUI.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "CustomizableWidgets",
|
||||
"resource:///modules/CustomizableWidgets.jsm");
|
||||
|
||||
// The profiler's menu button and its popup can be enabled/disabled by the user.
|
||||
// This is the pref to control whether the user has turned it on or not.
|
||||
// This pref is repeated across many files in order to avoid loading this file if
|
||||
// it's not needed. Make sure and search the rest of the codebase for other uses.
|
||||
const BUTTON_ENABLED_PREF = "devtools.performance.popup.enabled";
|
||||
const WIDGET_ID = "profiler-button";
|
||||
|
||||
function isEnabled() {
|
||||
return Services.prefs.getBoolPref(BUTTON_ENABLED_PREF, false);
|
||||
}
|
||||
|
||||
function setMenuItemChecked(document, isChecked) {
|
||||
const menuItem = document.querySelector("#menu_toggleProfilerButtonMenu");
|
||||
if (!menuItem) {
|
||||
return;
|
||||
}
|
||||
menuItem.setAttribute("checked", isChecked);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle the menu button, and initialize the widget if needed.
|
||||
*
|
||||
* @param {Object} document - The browser's document.
|
||||
*/
|
||||
function toggle(document) {
|
||||
const toggledValue = !isEnabled();
|
||||
Services.prefs.setBoolPref(BUTTON_ENABLED_PREF, toggledValue);
|
||||
if (toggledValue) {
|
||||
initialize();
|
||||
CustomizableUI.addWidgetToArea(WIDGET_ID, CustomizableUI.AREA_NAVBAR);
|
||||
} else {
|
||||
setMenuItemChecked(document, false);
|
||||
CustomizableUI.destroyWidget(WIDGET_ID);
|
||||
|
||||
// The widgets are not being properly destroyed. This is a workaround
|
||||
// until Bug 1552565 lands.
|
||||
const element = document.getElementById("PanelUI-profiler");
|
||||
delete element._addedEventListeners;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a utility function to get the iframe from an event.
|
||||
* @param {Object} The event fired by the CustomizableUI interface, contains a target.
|
||||
*/
|
||||
function getIframeFromEvent(event) {
|
||||
const panelview = event.target;
|
||||
const document = panelview.ownerDocument;
|
||||
|
||||
// Create the iframe, and append it.
|
||||
const iframe = document.getElementById("PanelUI-profilerIframe");
|
||||
if (!iframe) {
|
||||
throw new Error("Unable to select the PanelUI-profilerIframe.");
|
||||
}
|
||||
return iframe;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function creates the widget definition for the CustomizableUI. It should
|
||||
* only be run if the profiler button is enabled.
|
||||
*/
|
||||
function initialize() {
|
||||
const widget = CustomizableUI.getWidget(WIDGET_ID);
|
||||
if (widget && widget.provider == CustomizableUI.PROVIDER_API) {
|
||||
// This widget has already been created.
|
||||
return;
|
||||
}
|
||||
|
||||
let observer;
|
||||
|
||||
const item = {
|
||||
id: WIDGET_ID,
|
||||
type: "view",
|
||||
viewId: "PanelUI-profiler",
|
||||
tooltiptext: "profiler-button.tooltiptext",
|
||||
onViewShowing: (event) => {
|
||||
const iframe = getIframeFromEvent(event);
|
||||
iframe.src = "chrome://devtools/content/performance-new/popup/popup.html";
|
||||
|
||||
// Provide a mechanism for the iframe to close the popup.
|
||||
iframe.contentWindow.gClosePopup = () => {
|
||||
CustomizableUI.hidePanelForNode(iframe);
|
||||
};
|
||||
|
||||
// Provide a mechanism for the iframe to resize the popup.
|
||||
iframe.contentWindow.gResizePopup = height => {
|
||||
iframe.style.height = `${Math.min(600, height)}px`;
|
||||
};
|
||||
},
|
||||
onViewHiding(event) {
|
||||
const iframe = getIframeFromEvent(event);
|
||||
// Unset the iframe src so that when the popup DOM element is moved, the popup's
|
||||
// contents aren't re-initialized.
|
||||
iframe.src = "";
|
||||
},
|
||||
onBeforeCreated: (document) => {
|
||||
setMenuItemChecked(document, true);
|
||||
observer = {
|
||||
observe(subject, topic, data) {
|
||||
switch (topic) {
|
||||
case "profiler-started": {
|
||||
const button = document.querySelector("#profiler-button");
|
||||
if (button) {
|
||||
// Photon blue-60.
|
||||
button.style.fill = "#0060df";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "profiler-stopped": {
|
||||
const button = document.querySelector("#profiler-button");
|
||||
if (button) {
|
||||
button.style.fill = "";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
Services.obs.addObserver(observer, "profiler-started");
|
||||
Services.obs.addObserver(observer, "profiler-stopped");
|
||||
},
|
||||
onDestroyed: () => {
|
||||
Services.obs.removeObserver(observer, "profiler-started");
|
||||
Services.obs.removeObserver(observer, "profiler-stopped");
|
||||
},
|
||||
};
|
||||
CustomizableUI.createWidget(item);
|
||||
CustomizableWidgets.push(item);
|
||||
}
|
||||
|
||||
const ProfilerMenuButton = { toggle, initialize };
|
||||
|
||||
var EXPORTED_SYMBOLS = ["ProfilerMenuButton"];
|
@ -5,7 +5,7 @@
|
||||
|
||||
DevToolsModules(
|
||||
'background.jsm',
|
||||
'initializer.js',
|
||||
'menu-button.jsm',
|
||||
'popup.js',
|
||||
)
|
||||
|
||||
|
@ -99,6 +99,7 @@ function initializePopup() {
|
||||
.addEventListener("click", async () => {
|
||||
if (document.documentElement.classList.contains("status-running")) {
|
||||
await background.captureProfile();
|
||||
window.gClosePopup();
|
||||
}
|
||||
});
|
||||
|
||||
@ -175,6 +176,12 @@ function renderState(state) {
|
||||
}
|
||||
|
||||
renderControls(state);
|
||||
|
||||
window.requestAnimationFrame(() => {
|
||||
if (window.gResizePopup) {
|
||||
window.gResizePopup(document.body.clientHeight);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function renderControls(state) {
|
||||
|
@ -2,5 +2,5 @@
|
||||
- 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/. -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||
<path fill="context-fill" d="M10.85 6.85a.5.5 0 0 0-.7-.7l-2.5 2.5.7.7 2.5-2.5zM8 10a1 1 0 1 0 0-2 1 1 0 0 0 0 2zM5 1a1 1 0 0 1 1-1h4a1 1 0 1 1 0 2H6a1 1 0 0 1-1-1zM8 4a5 5 0 1 0 0 10A5 5 0 0 0 8 4zM1 9a7 7 0 1 1 14 0A7 7 0 0 1 1 9z"/>
|
||||
<path fill="context-fill" fill-opacity="context-fill-opacity" d="M10.85 6.85a.5.5 0 0 0-.7-.7l-2.5 2.5.7.7 2.5-2.5zM8 10a1 1 0 1 0 0-2 1 1 0 0 0 0 2zM5 1a1 1 0 0 1 1-1h4a1 1 0 1 1 0 2H6a1 1 0 0 1-1-1zM8 4a5 5 0 1 0 0 10A5 5 0 0 0 8 4zM1 9a7 7 0 1 1 14 0A7 7 0 0 1 1 9z"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 541 B After Width: | Height: | Size: 577 B |
@ -13,6 +13,7 @@
|
||||
* - 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.
|
||||
* - Inject the profiler recording button in toolbar customization.
|
||||
*
|
||||
* Only once any of these entry point is fired, this module ensures starting
|
||||
* core modules like 'devtools-browser.js' that hooks the browser windows
|
||||
@ -29,6 +30,7 @@ const kDebuggerPrefs = [
|
||||
const DEVTOOLS_ENABLED_PREF = "devtools.enabled";
|
||||
|
||||
const DEVTOOLS_POLICY_DISABLED_PREF = "devtools.policy.disabled";
|
||||
const PROFILER_POPUP_ENABLED_PREF = "devtools.performance.popup.enabled";
|
||||
|
||||
const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
@ -42,6 +44,8 @@ ChromeUtils.defineModuleGetter(this, "CustomizableWidgets",
|
||||
"resource:///modules/CustomizableWidgets.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "PrivateBrowsingUtils",
|
||||
"resource://gre/modules/PrivateBrowsingUtils.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "ProfilerMenuButton",
|
||||
"resource://devtools/client/performance-new/popup/menu-button.jsm");
|
||||
|
||||
// We don't want to spend time initializing the full loader here so we create
|
||||
// our own lazy require.
|
||||
@ -182,12 +186,47 @@ XPCOMUtils.defineLazyGetter(this, "KeyShortcuts", function() {
|
||||
});
|
||||
}
|
||||
|
||||
if (isProfilerButtonEnabled()) {
|
||||
shortcuts.push(...getProfilerKeyShortcuts());
|
||||
}
|
||||
|
||||
return shortcuts;
|
||||
});
|
||||
|
||||
function getProfilerKeyShortcuts() {
|
||||
return [
|
||||
// Start/stop the profiler
|
||||
{
|
||||
id: "profilerStartStop",
|
||||
shortcut: KeyShortcutsBundle.GetStringFromName("profilerStartStop.commandkey"),
|
||||
modifiers: "control,shift",
|
||||
},
|
||||
// Capture a profile
|
||||
{
|
||||
id: "profilerCapture",
|
||||
shortcut: KeyShortcutsBundle.GetStringFromName("profilerCapture.commandkey"),
|
||||
modifiers: "control,shift",
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Instead of loading the ProfilerMenuButton.jsm file, provide an independent check
|
||||
* to see if it is turned on.
|
||||
*/
|
||||
function isProfilerButtonEnabled() {
|
||||
return Services.prefs.getBoolPref(PROFILER_POPUP_ENABLED_PREF, false);
|
||||
}
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "ProfilerPopupBackground", function() {
|
||||
return ChromeUtils.import(
|
||||
"resource://devtools/client/performance-new/popup/background.jsm");
|
||||
});
|
||||
|
||||
function DevToolsStartup() {
|
||||
this.onEnabledPrefChanged = this.onEnabledPrefChanged.bind(this);
|
||||
this.onWindowReady = this.onWindowReady.bind(this);
|
||||
this.toggleProfilerKeyShortcuts = this.toggleProfilerKeyShortcuts.bind(this);
|
||||
}
|
||||
|
||||
DevToolsStartup.prototype = {
|
||||
@ -217,6 +256,12 @@ DevToolsStartup.prototype = {
|
||||
*/
|
||||
developerToggleCreated: false,
|
||||
|
||||
/**
|
||||
* Flag that indicates if the profiler recording popup was already added to
|
||||
* customizableUI.
|
||||
*/
|
||||
profilerRecordingButtonCreated: false,
|
||||
|
||||
isDisabledByPolicy: function() {
|
||||
return Services.prefs.getBoolPref(DEVTOOLS_POLICY_DISABLED_PREF, false);
|
||||
},
|
||||
@ -236,10 +281,14 @@ DevToolsStartup.prototype = {
|
||||
// Only top level Firefox Windows fire a browser-delayed-startup-finished event
|
||||
Services.obs.addObserver(this.onWindowReady, "browser-delayed-startup-finished");
|
||||
|
||||
if (AppConstants.MOZ_DEV_EDITION && !this.isDisabledByPolicy()) {
|
||||
// On DevEdition, the developer toggle is displayed by default in the navbar area
|
||||
// and should be created before the first paint.
|
||||
this.hookDeveloperToggle();
|
||||
if (!this.isDisabledByPolicy()) {
|
||||
if (AppConstants.MOZ_DEV_EDITION) {
|
||||
// On DevEdition, the developer toggle is displayed by default in the navbar
|
||||
// area and should be created before the first paint.
|
||||
this.hookDeveloperToggle();
|
||||
}
|
||||
|
||||
this.hookProfilerRecordingButton();
|
||||
}
|
||||
|
||||
// Update menu items when devtools.enabled changes.
|
||||
@ -360,6 +409,7 @@ DevToolsStartup.prototype = {
|
||||
// initialized before the first browser-delayed-startup-finished event is received.
|
||||
// We use a dedicated flag because we still need to hook the developer toggle.
|
||||
this.hookDeveloperToggle();
|
||||
this.hookProfilerRecordingButton();
|
||||
|
||||
// The developer menu hook only needs to be added if devtools have not been
|
||||
// initialized yet.
|
||||
@ -455,6 +505,22 @@ DevToolsStartup.prototype = {
|
||||
this.developerToggleCreated = true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Dynamically register a profiler recording button 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.)
|
||||
*/
|
||||
hookProfilerRecordingButton() {
|
||||
if (this.profilerRecordingButtonCreated) {
|
||||
return;
|
||||
}
|
||||
this.profilerRecordingButtonCreated = true;
|
||||
if (isProfilerButtonEnabled()) {
|
||||
ProfilerMenuButton.initialize();
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* 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
|
||||
@ -579,20 +645,90 @@ DevToolsStartup.prototype = {
|
||||
const keyset = doc.createXULElement("keyset");
|
||||
keyset.setAttribute("id", "devtoolsKeyset");
|
||||
|
||||
for (const key of KeyShortcuts) {
|
||||
const xulKey = this.createKey(doc, key, () => this.onKey(window, key));
|
||||
keyset.appendChild(xulKey);
|
||||
}
|
||||
this.attachKeys(doc, KeyShortcuts, keyset);
|
||||
|
||||
// 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).
|
||||
const mainKeyset = doc.getElementById("mainKeyset");
|
||||
mainKeyset.parentNode.insertBefore(keyset, mainKeyset);
|
||||
|
||||
// Watch for the profiler to enable or disable the profiler popup, then toggle
|
||||
// the keyboard shortcuts on and off.
|
||||
Services.prefs.addObserver(PROFILER_POPUP_ENABLED_PREF,
|
||||
this.toggleProfilerKeyShortcuts);
|
||||
},
|
||||
|
||||
/**
|
||||
* This method attaches on the key elements to the devtools keyset.
|
||||
*/
|
||||
attachKeys(doc, keyShortcuts, keyset = doc.getElementById("devtoolsKeyset")) {
|
||||
const window = doc.defaultView;
|
||||
for (const key of keyShortcuts) {
|
||||
const xulKey = this.createKey(doc, key, () => this.onKey(window, key));
|
||||
keyset.appendChild(xulKey);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* This method removes keys from the devtools keyset.
|
||||
*/
|
||||
removeKeys(doc, keyShortcuts) {
|
||||
for (const key of keyShortcuts) {
|
||||
const keyElement = doc.getElementById(this.getKeyElementId(key));
|
||||
if (keyElement) {
|
||||
keyElement.remove();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* We only want to have the keyboard shortcuts active when the menu button is on.
|
||||
* This function either adds or removes the elements.
|
||||
*/
|
||||
toggleProfilerKeyShortcuts() {
|
||||
const isEnabled = isProfilerButtonEnabled();
|
||||
const profilerKeyShortcuts = getProfilerKeyShortcuts();
|
||||
for (const { document } of Services.wm.getEnumerator(null)) {
|
||||
const devtoolsKeyset = document.getElementById("devtoolsKeyset");
|
||||
const mainKeyset = document.getElementById("mainKeyset");
|
||||
|
||||
if (!devtoolsKeyset || !mainKeyset) {
|
||||
// There may not be devtools keyset on this window.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isEnabled) {
|
||||
this.attachKeys(document, profilerKeyShortcuts);
|
||||
} else {
|
||||
this.removeKeys(document, profilerKeyShortcuts);
|
||||
}
|
||||
// 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).
|
||||
mainKeyset.parentNode.insertBefore(devtoolsKeyset, mainKeyset);
|
||||
}
|
||||
|
||||
if (!isEnabled) {
|
||||
// Ensure the profiler isn't left profiling in the background.
|
||||
ProfilerPopupBackground.stopProfiler();
|
||||
}
|
||||
},
|
||||
|
||||
async onKey(window, key) {
|
||||
try {
|
||||
// The profiler doesn't care if DevTools is loaded, so provide a quick check
|
||||
// first to bail out of checking if DevTools is available.
|
||||
switch (key.id) {
|
||||
case "profilerStartStop": {
|
||||
ProfilerPopupBackground.toggleProfiler();
|
||||
return;
|
||||
}
|
||||
case "profilerCapture": {
|
||||
ProfilerPopupBackground.captureProfile();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!Services.prefs.getBoolPref(DEVTOOLS_ENABLED_PREF)) {
|
||||
const id = key.toolId || key.id;
|
||||
this.openInstallPage("KeyShortcut", id);
|
||||
@ -610,13 +746,23 @@ DevToolsStartup.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
getKeyElementId({ id, toolId }) {
|
||||
return "key_" + (id || toolId);
|
||||
},
|
||||
|
||||
// Create a <xul:key> DOM Element
|
||||
createKey(doc, { id, toolId, shortcut, modifiers: mod }, oncommand) {
|
||||
createKey(doc, key, oncommand) {
|
||||
const { shortcut, modifiers: mod } = key;
|
||||
const k = doc.createXULElement("key");
|
||||
k.id = "key_" + (id || toolId);
|
||||
k.id = this.getKeyElementId(key);
|
||||
|
||||
if (shortcut.startsWith("VK_")) {
|
||||
k.setAttribute("keycode", shortcut);
|
||||
if (shortcut.match(/^VK_\d$/)) {
|
||||
// Add the event keydown attribute to ensure that shortcuts work for combinations
|
||||
// such as ctrl shift 1.
|
||||
k.setAttribute("event", "keydown");
|
||||
}
|
||||
} else {
|
||||
k.setAttribute("key", shortcut);
|
||||
}
|
||||
|
@ -61,3 +61,11 @@ dom.commandkey=W
|
||||
# LOCALIZATION NOTE (accessibilityF12.commandkey):
|
||||
# Key pressed to open a toolbox with the accessibility panel selected
|
||||
accessibilityF12.commandkey=VK_F12
|
||||
|
||||
# LOCALIZATION NOTE (profilerStartStop.commandkey):
|
||||
# Key pressed to start or stop the performance profiler
|
||||
profilerStartStop.commandkey=VK_1
|
||||
|
||||
# LOCALIZATION NOTE (profilerCapture.commandkey):
|
||||
# Key pressed to capture a recorded performance profile
|
||||
profilerCapture.commandkey=VK_2
|
||||
|
Loading…
Reference in New Issue
Block a user