Bug 1172500 - Add a keyboard shortcut to minimize the toolbox. r=jryans

This commit is contained in:
Patrick Brosset 2015-06-11 11:11:35 +02:00
Родитель f4bb63d6c0
Коммит 140ef7acb1
4 изменённых файлов: 99 добавлений и 37 удалений

Просмотреть файл

@ -30,6 +30,16 @@ add_task(function*() {
ok(parseInt(toolbox._host.frame.style.marginBottom, 10) == 0, ok(parseInt(toolbox._host.frame.style.marginBottom, 10) == 0,
"The toolbox host is shown again"); "The toolbox host is shown again");
info("Try to minimize again using the keyboard shortcut");
yield minimizeWithShortcut(toolbox);
ok(parseInt(toolbox._host.frame.style.marginBottom, 10) < 0,
"The toolbox host has been hidden away with a negative-margin");
info("Try to maximize again using the keyboard shortcut");
yield maximizeWithShortcut(toolbox);
ok(parseInt(toolbox._host.frame.style.marginBottom, 10) == 0,
"The toolbox host is shown again");
info("Minimize again and switch to another tool"); info("Minimize again and switch to another tool");
yield minimize(toolbox); yield minimize(toolbox);
let onMaximized = toolbox._host.once("maximized"); let onMaximized = toolbox._host.once("maximized");
@ -67,9 +77,27 @@ function* minimize(toolbox) {
yield onMinimized; yield onMinimized;
} }
function* minimizeWithShortcut(toolbox) {
let key = toolbox.doc.getElementById("toolbox-minimize-key")
.getAttribute("key");
let onMinimized = toolbox._host.once("minimized");
EventUtils.synthesizeKey(key, {accelKey: true, shiftKey: true},
toolbox.doc.defaultView);
yield onMinimized;
}
function* maximize(toolbox) { function* maximize(toolbox) {
let button = toolbox.doc.querySelector("#toolbox-dock-bottom-minimize"); let button = toolbox.doc.querySelector("#toolbox-dock-bottom-minimize");
let onMaximized = toolbox._host.once("maximized"); let onMaximized = toolbox._host.once("maximized");
EventUtils.synthesizeMouseAtCenter(button, {}, toolbox.doc.defaultView); EventUtils.synthesizeMouseAtCenter(button, {}, toolbox.doc.defaultView);
yield onMaximized; yield onMaximized;
} }
function* maximizeWithShortcut(toolbox) {
let key = toolbox.doc.getElementById("toolbox-minimize-key")
.getAttribute("key");
let onMaximized = toolbox._host.once("maximized");
EventUtils.synthesizeKey(key, {accelKey: true, shiftKey: true},
toolbox.doc.defaultView);
yield onMaximized;
}

Просмотреть файл

@ -2,8 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* globals gDevTools, DOMHelpers, toolboxStrings, InspectorFront, Selection, /* globals gDevTools, DOMHelpers, toolboxStrings, InspectorFront, Selection,
getPerformanceActorsConnection, CommandUtils, DevToolsUtils, screenManager, CommandUtils, DevToolsUtils, screenManager, oscpu, Hosts, is64Bit,
oscpu, Hosts, is64Bit */ osString, showDoorhanger, getHighlighterUtils, getPerformanceFront */
"use strict"; "use strict";
@ -21,24 +21,20 @@ let {Cc, Ci, Cu} = require("chrome");
let {Promise: promise} = require("resource://gre/modules/Promise.jsm"); let {Promise: promise} = require("resource://gre/modules/Promise.jsm");
let EventEmitter = require("devtools/toolkit/event-emitter"); let EventEmitter = require("devtools/toolkit/event-emitter");
let Telemetry = require("devtools/shared/telemetry"); let Telemetry = require("devtools/shared/telemetry");
let {getHighlighterUtils} = require("devtools/framework/toolbox-highlighter-utils");
let HUDService = require("devtools/webconsole/hudservice"); let HUDService = require("devtools/webconsole/hudservice");
let {showDoorhanger} = require("devtools/shared/doorhanger");
let sourceUtils = require("devtools/shared/source-utils"); let sourceUtils = require("devtools/shared/source-utils");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource:///modules/devtools/gDevTools.jsm"); Cu.import("resource:///modules/devtools/gDevTools.jsm");
Cu.import("resource:///modules/devtools/scratchpad-manager.jsm"); Cu.import("resource:///modules/devtools/scratchpad-manager.jsm");
Cu.import("resource:///modules/devtools/DOMHelpers.jsm"); Cu.import("resource:///modules/devtools/DOMHelpers.jsm");
Cu.import("resource://gre/modules/Task.jsm"); Cu.import("resource://gre/modules/Task.jsm");
loader.lazyGetter(this, "Hosts", () => require("devtools/framework/toolbox-hosts").Hosts); loader.lazyImporter(this, "CommandUtils",
"resource:///modules/devtools/DeveloperToolbar.jsm");
loader.lazyImporter(this, "CommandUtils", "resource:///modules/devtools/DeveloperToolbar.jsm");
loader.lazyGetter(this, "toolboxStrings", () => { loader.lazyGetter(this, "toolboxStrings", () => {
let bundle = Services.strings.createBundle("chrome://browser/locale/devtools/toolbox.properties"); const properties = "chrome://browser/locale/devtools/toolbox.properties";
const bundle = Services.strings.createBundle(properties);
return (name, ...args) => { return (name, ...args) => {
try { try {
if (!args.length) { if (!args.length) {
@ -51,22 +47,31 @@ loader.lazyGetter(this, "toolboxStrings", () => {
} }
}; };
}); });
loader.lazyRequireGetter(this, "getHighlighterUtils",
loader.lazyGetter(this, "Selection", () => require("devtools/framework/selection").Selection); "devtools/framework/toolbox-highlighter-utils", true);
loader.lazyGetter(this, "InspectorFront", () => require("devtools/server/actors/inspector").InspectorFront); loader.lazyRequireGetter(this, "Hosts",
loader.lazyRequireGetter(this, "DevToolsUtils", "devtools/toolkit/DevToolsUtils"); "devtools/framework/toolbox-hosts", true);
loader.lazyRequireGetter(this, "getPerformanceFront", "devtools/performance/front", true); loader.lazyRequireGetter(this, "Selection",
"devtools/framework/selection", true);
XPCOMUtils.defineLazyGetter(this, "screenManager", () => { loader.lazyRequireGetter(this, "InspectorFront",
"devtools/server/actors/inspector", true);
loader.lazyRequireGetter(this, "DevToolsUtils",
"devtools/toolkit/DevToolsUtils");
loader.lazyRequireGetter(this, "showDoorhanger",
"devtools/shared/doorhanger", true);
loader.lazyRequireGetter(this, "getPerformanceFront",
"devtools/performance/front", true);
loader.lazyGetter(this, "osString", () => {
return Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).OS;
});
loader.lazyGetter(this, "screenManager", () => {
return Cc["@mozilla.org/gfx/screenmanager;1"].getService(Ci.nsIScreenManager); return Cc["@mozilla.org/gfx/screenmanager;1"].getService(Ci.nsIScreenManager);
}); });
loader.lazyGetter(this, "oscpu", () => {
XPCOMUtils.defineLazyGetter(this, "oscpu", () => {
return Cc["@mozilla.org/network/protocol;1?name=http"] return Cc["@mozilla.org/network/protocol;1?name=http"]
.getService(Ci.nsIHttpProtocolHandler).oscpu; .getService(Ci.nsIHttpProtocolHandler).oscpu;
}); });
loader.lazyGetter(this, "is64Bit", () => {
XPCOMUtils.defineLazyGetter(this, "is64Bit", () => {
return Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo).is64Bit; return Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo).is64Bit;
}); });
@ -79,8 +84,9 @@ const ToolboxButtons = exports.ToolboxButtons = [
target.getTrait("highlightable") target.getTrait("highlightable")
}, },
{ id: "command-button-frames", { id: "command-button-frames",
isTargetSupported: target => isTargetSupported: target => {
( target.activeTab && target.activeTab.traits.frames ) return target.activeTab && target.activeTab.traits.frames;
}
}, },
{ id: "command-button-splitconsole", { id: "command-button-splitconsole",
isTargetSupported: target => !target.isAddon }, isTargetSupported: target => !target.isAddon },
@ -135,6 +141,7 @@ function Toolbox(target, selectedTool, hostType, hostOptions) {
this._onBottomHostMaximized = this._onBottomHostMaximized.bind(this); this._onBottomHostMaximized = this._onBottomHostMaximized.bind(this);
this._onToolSelectWhileMinimized = this._onToolSelectWhileMinimized.bind(this); this._onToolSelectWhileMinimized = this._onToolSelectWhileMinimized.bind(this);
this._onBottomHostWillChange = this._onBottomHostWillChange.bind(this); this._onBottomHostWillChange = this._onBottomHostWillChange.bind(this);
this._toggleMinimizeMode = this._toggleMinimizeMode.bind(this);
this._target.on("close", this.destroy); this._target.on("close", this.destroy);
@ -481,7 +488,7 @@ Toolbox.prototype = {
["toolbox-force-reload-key", true], ["toolbox-force-reload-key", true],
["toolbox-force-reload-key2", true] ["toolbox-force-reload-key2", true]
].forEach(([id, force]) => { ].forEach(([id, force]) => {
this.doc.getElementById(id).addEventListener("command", (event) => { this.doc.getElementById(id).addEventListener("command", () => {
this.reloadTarget(force); this.reloadTarget(force);
}, true); }, true);
}); });
@ -493,6 +500,9 @@ Toolbox.prototype = {
let prevKey = this.doc.getElementById("toolbox-previous-tool-key"); let prevKey = this.doc.getElementById("toolbox-previous-tool-key");
prevKey.addEventListener("command", this.selectPreviousTool.bind(this), true); prevKey.addEventListener("command", this.selectPreviousTool.bind(this), true);
let minimizeKey = this.doc.getElementById("toolbox-minimize-key");
minimizeKey.addEventListener("command", this._toggleMinimizeMode, true);
// Split console uses keypress instead of command so the event can be // Split console uses keypress instead of command so the event can be
// cancelled with stopPropagation on the keypress, and not preventDefault. // cancelled with stopPropagation on the keypress, and not preventDefault.
this.doc.addEventListener("keypress", this._splitConsoleOnKeypress, false); this.doc.addEventListener("keypress", this._splitConsoleOnKeypress, false);
@ -703,18 +713,11 @@ Toolbox.prototype = {
if (this.hostType == Toolbox.HostType.BOTTOM) { if (this.hostType == Toolbox.HostType.BOTTOM) {
let minimizeBtn = this.doc.createElement("toolbarbutton"); let minimizeBtn = this.doc.createElement("toolbarbutton");
minimizeBtn.id = "toolbox-dock-bottom-minimize"; minimizeBtn.id = "toolbox-dock-bottom-minimize";
minimizeBtn.className = "maximized";
minimizeBtn.setAttribute("tooltiptext", minimizeBtn.addEventListener("command", this._toggleMinimizeMode);
toolboxStrings("toolboxDockButtons.bottom.minimize"));
// Calculate the height to which the host should be minimized so the
// tabbar is still visible.
let toolbarHeight = this.doc.querySelector(".devtools-tabbar")
.getBoxQuads({box: "content"})[0]
.bounds.height;
minimizeBtn.addEventListener("command", () => {
this._host.toggleMinimizeMode(toolbarHeight);
});
dockBox.appendChild(minimizeBtn); dockBox.appendChild(minimizeBtn);
// Show the button in its maximized state.
this._onBottomHostMaximized();
// Update the label and icon when the state changes. // Update the label and icon when the state changes.
this._host.on("minimized", this._onBottomHostMinimized); this._host.on("minimized", this._onBottomHostMinimized);
@ -754,18 +757,29 @@ Toolbox.prototype = {
} }
}, },
_getMinimizeButtonShortcutTooltip: function() {
let key = this.doc.getElementById("toolbox-minimize-key")
.getAttribute("key");
return "(" + (osString == "Darwin" ? "Cmd+Shift+" : "Ctrl+Shift+") +
key.toUpperCase() + ")";
},
_onBottomHostMinimized: function() { _onBottomHostMinimized: function() {
let btn = this.doc.querySelector("#toolbox-dock-bottom-minimize"); let btn = this.doc.querySelector("#toolbox-dock-bottom-minimize");
btn.className = "minimized"; btn.className = "minimized";
btn.setAttribute("tooltiptext", btn.setAttribute("tooltiptext",
toolboxStrings("toolboxDockButtons.bottom.maximize")); toolboxStrings("toolboxDockButtons.bottom.maximize") + " " +
this._getMinimizeButtonShortcutTooltip());
}, },
_onBottomHostMaximized: function() { _onBottomHostMaximized: function() {
let btn = this.doc.querySelector("#toolbox-dock-bottom-minimize"); let btn = this.doc.querySelector("#toolbox-dock-bottom-minimize");
btn.className = "maximized"; btn.className = "maximized";
btn.setAttribute("tooltiptext", btn.setAttribute("tooltiptext",
toolboxStrings("toolboxDockButtons.bottom.minimize")); toolboxStrings("toolboxDockButtons.bottom.minimize") + " " +
this._getMinimizeButtonShortcutTooltip());
}, },
_onToolSelectWhileMinimized: function() { _onToolSelectWhileMinimized: function() {
@ -780,6 +794,19 @@ Toolbox.prototype = {
this.off("before-select", this._onToolSelectWhileMinimized); this.off("before-select", this._onToolSelectWhileMinimized);
}, },
_toggleMinimizeMode: function() {
if (this.hostType !== Toolbox.HostType.BOTTOM) {
return;
}
// Calculate the height to which the host should be minimized so the
// tabbar is still visible.
let toolbarHeight = this.doc.querySelector(".devtools-tabbar")
.getBoxQuads({box: "content"})[0]
.bounds.height;
this._host.toggleMinimizeMode(toolbarHeight);
},
/** /**
* Add tabs to the toolbox UI for registered tools * Add tabs to the toolbox UI for registered tools
*/ */

Просмотреть файл

@ -70,6 +70,10 @@
keycode="VK_F5" keycode="VK_F5"
oncommand="void(0);" oncommand="void(0);"
modifiers="accel"/> modifiers="accel"/>
<key id="toolbox-minimize-key"
key="&toolboxToggleMinimize.key;"
oncommand="void(0);"
modifiers="shift, accel"/>
</keyset> </keyset>
<popupset> <popupset>

Просмотреть файл

@ -21,6 +21,9 @@
<!ENTITY toolboxZoomReset.key "0"> <!ENTITY toolboxZoomReset.key "0">
<!ENTITY toolboxReload.key "r"> <!ENTITY toolboxReload.key "r">
<!-- This key is used with the accel+shift modifiers to minimize the toolbox -->
<!ENTITY toolboxToggleMinimize.key "U">
<!-- LOCALIZATION NOTE (toolboxFramesButton): This is the label for <!-- LOCALIZATION NOTE (toolboxFramesButton): This is the label for
- the iframes menu list that appears only when the document has some. - the iframes menu list that appears only when the document has some.
- It allows you to switch the context of the whole toolbox. --> - It allows you to switch the context of the whole toolbox. -->