Bug 1327971 - Add support to show list of frames on key-press of "Alt+Down" on the "iframes" button. r=Honza
MozReview-Commit-ID: EZFG4br17mC
--- a/devtools/client/framework/components/toolbox-toolbar.js
+++ b/devtools/client/framework/components/toolbox-toolbar.js
@@ -101,30 +101,40 @@ function renderToolboxButtons({toolboxBu
});
if (visibleButtons.length === 0) {
return null;
}
return div({id: `toolbox-buttons-${isStart ? "start" : "end"}`},
...visibleButtons.map(command => {
- const {id, description, onClick, isChecked, className: buttonClass} = command;
+ const {
+ id,
+ description,
+ onClick,
+ isChecked,
+ className: buttonClass,
+ onKeyDown
+ } = command;
return button({
id,
title: description,
className: (
"command-button command-button-invertable devtools-button "
+ buttonClass + (isChecked ? " checked" : "")
),
onClick: (event) => {
onClick(event);
focusButton(id);
},
onFocus: () => focusButton(id),
- tabIndex: id === focusedButton ? "0" : "-1"
+ tabIndex: id === focusedButton ? "0" : "-1",
+ onKeyDown: (event) => {
+ onKeyDown(event);
+ }
});
}),
isStart ? div({className: "devtools-separator"}) : null
);
}
/**
* The options button is a ToolboxTab just like in the ToolboxTabs component. However
--- a/devtools/client/framework/test/browser_toolbox_window_title_frame_select.js
+++ b/devtools/client/framework/test/browser_toolbox_window_title_frame_select.js
@@ -11,16 +11,18 @@
* Check that the detached devtools window title is not updated when switching
* the selected frame. Also check that frames command button has 'open'
* attribute set when the list of frames is opened.
*/
var {Toolbox} = require("devtools/client/framework/toolbox");
const URL = URL_ROOT + "browser_toolbox_window_title_frame_select_page.html";
const IFRAME_URL = URL_ROOT + "browser_toolbox_window_title_changes_page.html";
+const {LocalizationHelper} = require("devtools/shared/l10n");
+const L10N = new LocalizationHelper("devtools/client/locales/toolbox.properties");
add_task(function* () {
Services.prefs.setBoolPref("devtools.command-button-frames.enabled", true);
yield addTab(URL);
let target = TargetFactory.forTab(gBrowser.selectedTab);
let toolbox = yield gDevTools.showToolbox(target, null,
Toolbox.HostType.BOTTOM);
@@ -36,19 +38,22 @@ add_task(function* () {
is(getTitle(), `Developer Tools - Page title - ${URL}`,
"Devtools title correct after switching to detached window host");
// Wait for tick to avoid unexpected 'popuphidden' event, which
// blocks the frame popup menu opened below. See also bug 1276873
yield waitForTick();
+ let btn = toolbox.doc.getElementById("command-button-frames");
+
+ yield testShortcutToOpenFrames(btn, toolbox);
+
// Open frame menu and wait till it's available on the screen.
// Also check 'open' attribute on the command button.
- let btn = toolbox.doc.getElementById("command-button-frames");
ok(!btn.classList.contains("checked"), "The checked class must not be present");
let menu = toolbox.showFramesMenu({target: btn});
yield once(menu, "open");
ok(btn.classList.contains("checked"), "The checked class must be set");
// Verify that the frame list menu is populated
let frames = menu.items;
@@ -87,8 +92,30 @@ add_task(function* () {
Services.prefs.clearUserPref("devtools.toolbox.sideEnabled");
Services.prefs.clearUserPref("devtools.command-button-frames.enabled");
finish();
});
function getTitle() {
return Services.wm.getMostRecentWindow("devtools:toolbox").document.title;
}
+
+function* testShortcutToOpenFrames(btn, toolbox) {
+ info("Tests if shortcut Alt+Down opens the frames");
+ // focus the button so that keyPress can be performed
+ btn.focus();
+ // perform keyPress - Alt+Down
+ let shortcut = L10N.getStr("toolbox.showFrames.key");
+ synthesizeKeyShortcut(shortcut, toolbox.win);
+
+ // wait for 200 ms for UI to render
+ yield wait(200);
+
+ // btn should now have the checked class set
+ ok(btn.classList.contains("checked"), "The checked class must be set");
+
+ // pressing Esc should hide the menu again
+ synthesizeKeyShortcut("Esc", toolbox.win);
+ yield wait(200);
+
+ // btn shouldn't have the checked class set
+ ok(!btn.classList.contains("checked"), "The checked class must not be set");
+}
--- a/devtools/client/framework/toolbox.js
+++ b/devtools/client/framework/toolbox.js
@@ -108,16 +108,18 @@ function Toolbox(target, selectedTool, h
this.frameMap = new Map();
this.selectedFrameId = null;
this._toolRegistered = this._toolRegistered.bind(this);
this._toolUnregistered = this._toolUnregistered.bind(this);
this._refreshHostTitle = this._refreshHostTitle.bind(this);
this._toggleNoAutohide = this._toggleNoAutohide.bind(this);
this.showFramesMenu = this.showFramesMenu.bind(this);
+ this.handleKeyDownOnFramesButton = this.handleKeyDownOnFramesButton.bind(this);
+ this.showFramesMenuOnKeyDown = this.showFramesMenuOnKeyDown.bind(this);
this._updateFrames = this._updateFrames.bind(this);
this._splitConsoleOnKeypress = this._splitConsoleOnKeypress.bind(this);
this.destroy = this.destroy.bind(this);
this.highlighterUtils = getHighlighterUtils(this);
this._highlighterReady = this._highlighterReady.bind(this);
this._highlighterHidden = this._highlighterHidden.bind(this);
this._applyCacheSettings = this._applyCacheSettings.bind(this);
this._applyServiceWorkersTestingSettings =
@@ -682,28 +684,43 @@ Toolbox.prototype = {
* the button based on the target. If the target don't support
* the button feature, this method should return false.
* @property {Function} isChecked - Optional function called to known if the button
* is toggled or not. The function should return true when
* the button should be displayed as toggled on.
*/
_createButtonState: function (options) {
let isCheckedValue = false;
- const { id, className, description, onClick, isInStartContainer, setup, teardown,
- isTargetSupported, isChecked } = options;
+ const {
+ id,
+ className,
+ description,
+ onClick,
+ isInStartContainer,
+ setup,
+ teardown,
+ isTargetSupported,
+ isChecked,
+ onKeyDown
+ } = options;
const toolbox = this;
const button = {
id,
className,
description,
onClick(event) {
if (typeof onClick == "function") {
onClick(event, toolbox);
}
},
+ onKeyDown(event) {
+ if (typeof onKeyDown == "function") {
+ onKeyDown(event, toolbox);
+ }
+ },
isTargetSupported,
get isChecked() {
if (typeof isChecked == "function") {
return isChecked(toolbox);
}
return isCheckedValue;
},
set isChecked(value) {
@@ -1200,17 +1217,18 @@ Toolbox.prototype = {
*/
_buildFrameButton() {
this.frameButton = this._createButtonState({
id: "command-button-frames",
description: L10N.getStr("toolbox.frames.tooltip"),
onClick: this.showFramesMenu,
isTargetSupported: target => {
return target.activeTab && target.activeTab.traits.frames;
- }
+ },
+ onKeyDown: this.handleKeyDownOnFramesButton
});
return this.frameButton;
},
/**
* Button that disables/enables auto-hiding XUL pop-ups. When enabled, XUL
* pop-ups will not automatically close when they lose focus.
@@ -2049,16 +2067,33 @@ Toolbox.prototype = {
let screenX = target.ownerDocument.defaultView.mozInnerScreenX;
let screenY = target.ownerDocument.defaultView.mozInnerScreenY;
menu.popup(rect.left + screenX, rect.bottom + screenY, this);
return menu;
},
/**
+ * Handle keyDown event on 'frames' button to show available frames
+ */
+ handleKeyDownOnFramesButton: function (event) {
+ this.shortcuts.on(L10N.getStr("toolbox.showFrames.key"),
+ this.showFramesMenuOnKeyDown);
+ },
+
+ /**
+ * Show 'frames' menu on key down
+ */
+ showFramesMenuOnKeyDown: function (name, event) {
+ if (event.target.id == "command-button-frames") {
+ this.showFramesMenu(event);
+ }
+ },
+
+ /**
* Select a frame by sending 'switchToFrame' packet to the backend.
*/
onSelectFrame: function (frameId) {
// Send packet to the backend to select specified frame and
// wait for 'frameUpdate' event packet to update the UI.
let packet = {
to: this._target.form.actor,
type: "switchToFrame",
--- a/devtools/client/locales/en-US/toolbox.properties
+++ b/devtools/client/locales/en-US/toolbox.properties
@@ -159,16 +159,20 @@ toolbox.minimize.key=CmdOrCtrl+Shift+U
# Key shortcut used to move the toolbox in bottom or side of the browser window
toolbox.toggleHost.key=CmdOrCtrl+Shift+D
# LOCALIZATION NOTE (toolbox.frames.tooltip): This is the label for
# the iframes menu list that appears only when the document has some.
# It allows you to switch the context of the whole toolbox.
toolbox.frames.tooltip=Select an iframe as the currently targeted document
+# LOCALIZATION NOTE (toolbox.showFrames.key)
+# Key shortcut used to show frames menu when 'frames' button is focused
+toolbox.showFrames.key=Alt+Down
+
# LOCALIZATION NOTE (toolbox.noautohide.tooltip): This is the label for
# the button to force the popups/panels to stay visible on blur.
# This is only visible in the browser toolbox as it is meant for
# addon developers and Firefox contributors.
toolbox.noautohide.tooltip=Disable popup auto hide
# LOCALIZATION NOTE (toolbox.closebutton.tooltip): This is the tooltip for
# the close button the developer tools toolbox.