--- a/devtools/client/definitions.js
+++ b/devtools/client/definitions.js
@@ -503,32 +503,16 @@ exports.defaultThemes = [
Tools.darkTheme,
Tools.lightTheme,
];
// White-list buttons that can be toggled to prevent adding prefs for
// addons that have manually inserted toolbarbuttons into DOM.
// (By default, supported target is only local tab)
exports.ToolboxButtons = [
- { id: "command-button-splitconsole",
- description: l10n("toolbox.buttons.splitconsole", "Esc"),
- isTargetSupported: target => !target.isAddon,
- onClick(event, toolbox) {
- toolbox.toggleSplitConsole();
- },
- isChecked(toolbox) {
- return toolbox.splitConsole;
- },
- setup(toolbox, onChange) {
- toolbox.on("split-console", onChange);
- },
- teardown(toolbox, onChange) {
- toolbox.off("split-console", onChange);
- }
- },
{ id: "command-button-paintflashing",
description: l10n("toolbox.buttons.paintflashing"),
isTargetSupported: target => target.isLocalTab,
onClick(event, toolbox) {
CommandUtils.executeOnTarget(toolbox.target, "paintflashing toggle");
},
isChecked(toolbox) {
return CommandState.isEnabledForTarget(toolbox.target, "paintflashing");
--- a/devtools/client/framework/components/toolbox-controller.js
+++ b/devtools/client/framework/components/toolbox-controller.js
@@ -23,31 +23,33 @@ class ToolboxController extends Componen
focusedButton: ELEMENT_PICKER_ID,
toolboxButtons: [],
currentToolId: null,
highlightedTools: new Set(),
panelDefinitions: [],
hostTypes: [],
areDockOptionsEnabled: true,
canCloseToolbox: true,
+ isSplitConsoleActive: false,
canRender: false,
buttonIds: [],
checkedButtonsUpdated: () => {
this.forceUpdate();
}
};
this.setFocusedButton = this.setFocusedButton.bind(this);
this.setToolboxButtons = this.setToolboxButtons.bind(this);
this.setCurrentToolId = this.setCurrentToolId.bind(this);
this.highlightTool = this.highlightTool.bind(this);
this.unhighlightTool = this.unhighlightTool.bind(this);
this.setHostTypes = this.setHostTypes.bind(this);
this.setDockOptionsEnabled = this.setDockOptionsEnabled.bind(this);
this.setCanCloseToolbox = this.setCanCloseToolbox.bind(this);
+ this.setIsSplitConsoleActive = this.setIsSplitConsoleActive.bind(this);
this.setCanRender = this.setCanRender.bind(this);
this.setPanelDefinitions = this.setPanelDefinitions.bind(this);
this.updateButtonIds = this.updateButtonIds.bind(this);
this.updateFocusedButton = this.updateFocusedButton.bind(this);
}
shouldComponentUpdate() {
return this.state.canRender;
@@ -132,16 +134,20 @@ class ToolboxController extends Componen
setHostTypes(hostTypes) {
this.setState({ hostTypes });
}
setCanCloseToolbox(canCloseToolbox) {
this.setState({ canCloseToolbox }, this.updateButtonIds);
}
+ setIsSplitConsoleActive(isSplitConsoleActive) {
+ this.setState({ isSplitConsoleActive });
+ }
+
setPanelDefinitions(panelDefinitions) {
this.setState({ panelDefinitions }, this.updateButtonIds);
}
get panelDefinitions() {
return this.state.panelDefinitions;
}
--- a/devtools/client/framework/components/toolbox-toolbar.js
+++ b/devtools/client/framework/components/toolbox-toolbar.js
@@ -40,18 +40,22 @@ class ToolboxToolbar extends Component {
switchHost: PropTypes.func.isRequired,
})),
// Should the docking options be enabled? They are disabled in some
// contexts such as WebIDE.
areDockButtonsEnabled: PropTypes.bool,
// Do we need to add UI for closing the toolbox? We don't when the
// toolbox is undocked, for example.
canCloseToolbox: PropTypes.bool,
+ // Is the split console currently visible?
+ isSplitConsoleActive: PropTypes.bool,
// Function to select a tool based on its id.
selectTool: PropTypes.func,
+ // Function to turn the split console on / off.
+ toggleSplitConsole: PropTypes.func,
// Function to completely close the toolbox.
closeToolbox: PropTypes.func,
// Keep a record of what button is focused.
focusButton: PropTypes.func,
// Hold off displaying the toolbar until enough information is ready for
// it to render nicely.
canRender: PropTypes.bool,
// Localization interface.
@@ -174,18 +178,23 @@ function renderSeparator() {
* @param {Function} hostTypes[].switchHost
* Function to switch the host.
* @param {boolean} areDockOptionsEnabled
* They are not enabled in certain situations like when they are in the
* WebIDE.
* @param {boolean} canCloseToolbox
* Do we need to add UI for closing the toolbox? We don't when the
* toolbox is undocked, for example.
+ * @param {boolean} isSplitConsoleActive
+ * Is the split console currently visible?
+ * toolbox is undocked, for example.
* @param {Function} selectTool
* Function to select a tool based on its id.
+ * @param {Function} toggleSplitConsole
+ * Function to turn the split console on / off.
* @param {Function} closeToolbox
* Completely close the toolbox.
* @param {Function} focusButton
* Keep a record of the currently focused button.
* @param {Object} L10N
* Localization interface.
*/
function renderToolboxControls(props) {
@@ -239,46 +248,77 @@ function renderToolboxControls(props) {
/**
* Display the "..." menu (affectionately known as the meatball menu).
*
* @param {Object} menuButton
* The <button> element from which the menu should pop out. The geometry
* of this element is used to position the menu.
* @param {Object} props
* Properties as described below.
+ * @param {string} props.currentToolId
+ * The id of the currently selected tool.
* @param {Object[]} props.hostTypes
* Array of host type objects.
* @param {string} props.hostTypes[].position
* Position name.
* @param {Function} props.hostTypes[].switchHost
* Function to switch the host.
* This array will be empty if we shouldn't shouldn't show any dock
* options.
+ * @param {boolean} isSplitConsoleActive
+ * Is the split console currently visible?
* @param {Function} props.selectTool
* Function to select a tool based on its id.
+ * @param {Function} toggleSplitConsole
+ * Function to turn the split console on / off.
* @param {Object} props.L10N
* Localization interface.
* @param {Object} props.toolbox
* The devtools toolbox. Used by the Menu component to determine which
* document to use.
*/
-function showMeatballMenu(menuButton, {hostTypes, selectTool, L10N, toolbox}) {
+function showMeatballMenu(
+ menuButton,
+ {
+ currentToolId,
+ hostTypes,
+ isSplitConsoleActive,
+ selectTool,
+ toggleSplitConsole,
+ L10N,
+ toolbox,
+ }
+) {
const menu = new Menu({ id: "toolbox-meatball-menu" });
// Dock options
for (const hostType of hostTypes) {
menu.append(new MenuItem({
id: `toolbox-meatball-menu-dock-${hostType.position}`,
label: L10N.getStr(
`toolbox.meatballMenu.dock.${hostType.position}.label`
),
click: () => hostType.switchHost(),
}));
}
+ // Split console
+ if (currentToolId !== "webconsole") {
+ menu.append(new MenuItem({
+ id: "toolbox-meatball-menu-splitconsole",
+ label: L10N.getStr(
+ `toolbox.meatballMenu.${
+ isSplitConsoleActive ? "hideconsole" : "splitconsole"
+ }.label`
+ ),
+ accelerator: "Esc",
+ click: toggleSplitConsole,
+ }));
+ }
+
if (menu.items.length) {
menu.append(new MenuItem({ type: "separator" }));
}
// Settings
menu.append(new MenuItem({
id: "toolbox-meatball-menu-settings",
label: L10N.getStr("toolbox.meatballMenu.settings.label"),
--- a/devtools/client/framework/toolbox.js
+++ b/devtools/client/framework/toolbox.js
@@ -147,16 +147,17 @@ function Toolbox(target, selectedTool, h
this._onPickerClick = this._onPickerClick.bind(this);
this._onPickerKeypress = this._onPickerKeypress.bind(this);
this._onPickerStarted = this._onPickerStarted.bind(this);
this._onPickerStopped = this._onPickerStopped.bind(this);
this._onInspectObject = this._onInspectObject.bind(this);
this._onNewSelectedNodeFront = this._onNewSelectedNodeFront.bind(this);
this._updatePickerButton = this._updatePickerButton.bind(this);
this.selectTool = this.selectTool.bind(this);
+ this.toggleSplitConsole = this.toggleSplitConsole.bind(this);
this._target.on("close", this.destroy);
if (!selectedTool) {
selectedTool = Services.prefs.getCharPref(this._prefs.LAST_TOOL);
}
this._defaultToolId = selectedTool;
@@ -1106,16 +1107,17 @@ Toolbox.prototype = {
},
_mountReactComponent: function() {
// Ensure the toolbar doesn't try to render until the tool is ready.
const element = this.React.createElement(this.ToolboxController, {
L10N,
currentToolId: this.currentToolId,
selectTool: this.selectTool,
+ toggleSplitConsole: this.toggleSplitConsole,
closeToolbox: this.destroy,
focusButton: this._onToolbarFocus,
toolbox: this
});
this.component = this.ReactDOM.render(element, this._componentMount);
},
@@ -1902,31 +1904,33 @@ Toolbox.prototype = {
// Ensure split console is visible if console was already loaded in background
let iframe = this.webconsolePanel.querySelector(".toolbox-panel-iframe");
if (iframe) {
this.setIframeVisible(iframe, true);
}
return this.loadTool("webconsole").then(() => {
+ this.component.setIsSplitConsoleActive(true);
this.emit("split-console");
this.focusConsoleInput();
});
},
/**
* Closes the split console.
*
* @returns {Promise} a promise that resolves once the tool has been
* closed.
*/
closeSplitConsole: function() {
this._splitConsole = false;
Services.prefs.setBoolPref(SPLITCONSOLE_ENABLED_PREF, false);
this._refreshConsoleDisplay();
+ this.component.setIsSplitConsoleActive(false);
this.emit("split-console");
if (this._lastFocusedElement) {
this._lastFocusedElement.focus();
}
return promise.resolve();
},
--- a/devtools/client/jar.mn
+++ b/devtools/client/jar.mn
@@ -144,17 +144,16 @@ devtools.jar:
skin/rules.css (themes/rules.css)
skin/commandline.css (themes/commandline.css)
skin/images/command-paintflashing.svg (themes/images/command-paintflashing.svg)
skin/images/command-screenshot.svg (themes/images/command-screenshot.svg)
skin/images/command-responsivemode.svg (themes/images/command-responsivemode.svg)
skin/images/command-pick.svg (themes/images/command-pick.svg)
skin/images/command-pick-accessibility.svg (themes/images/command-pick-accessibility.svg)
skin/images/command-frames.svg (themes/images/command-frames.svg)
- skin/images/command-console.svg (themes/images/command-console.svg)
skin/images/command-eyedropper.svg (themes/images/command-eyedropper.svg)
skin/images/command-rulers.svg (themes/images/command-rulers.svg)
skin/images/command-measure.svg (themes/images/command-measure.svg)
skin/images/command-noautohide.svg (themes/images/command-noautohide.svg)
skin/markup.css (themes/markup.css)
skin/images/editor-error.png (themes/images/editor-error.png)
skin/images/breakpoint.svg (themes/images/breakpoint.svg)
skin/webconsole.css (themes/webconsole.css)
--- a/devtools/client/locales/en-US/startup.properties
+++ b/devtools/client/locales/en-US/startup.properties
@@ -257,22 +257,16 @@ accessibility.panelLabel=Accessibility P
accessibility.accesskey=y
# LOCALIZATION NOTE (accessibility.tooltip2):
# This string is displayed in the tooltip of the tab when the Accessibility is
# displayed inside the developer tools window.
# Keyboard shortcut for Accessibility panel will be shown inside the brackets.
accessibility.tooltip2=Accessibility
-# LOCALIZATION NOTE (toolbox.buttons.splitconsole):
-# This is the tooltip of the button in the toolbox toolbar used to toggle
-# the split console.
-# Keyboard shortcut will be shown inside brackets.
-toolbox.buttons.splitconsole = Toggle split console (%S)
-
# LOCALIZATION NOTE (toolbox.buttons.responsive):
# This is the tooltip of the button in the toolbox toolbar that toggles
# the Responsive mode.
# Keyboard shortcut will be shown inside brackets.
toolbox.buttons.responsive = Responsive Design Mode (%S)
# LOCALIZATION NOTE (toolbox.buttons.paintflashing):
# This is the tooltip of the paintflashing button in the toolbox toolbar
--- a/devtools/client/locales/en-US/toolbox.properties
+++ b/devtools/client/locales/en-US/toolbox.properties
@@ -158,16 +158,23 @@ toolbox.meatballMenu.button.tooltip=Cust
# LOCALIZATION NOTE (toolbox.meatballMenu.dock.*.label): These labels are shown
# in the "..." menu in the toolbox and represent the different arrangements for
# docking (or undocking) the developer tools toolbox.
toolbox.meatballMenu.dock.bottom.label=Dock to bottom
toolbox.meatballMenu.dock.side.label=Dock to side
toolbox.meatballMenu.dock.window.label=Undock
+# LOCALIZATION NOTE (toolbox.meatballMenu.{splitconsole,hideconsole}.label):
+# These are the labels in the "..." menu in the toolbox for toggling the split
+# console window.
+# The keyboard shortcut will be shown to the side of the label.
+toolbox.meatballMenu.splitconsole.label=Show split console
+toolbox.meatballMenu.hideconsole.label=Hide split console
+
# LOCALIZATION NOTE (toolbox.meatballMenu.settings.label): This is the label for
# the item in the "..." menu in the toolbox that brings up the Settings
# (Options) panel.
# The keyboard shortcut will be shown to the side of the label.
toolbox.meatballMenu.settings.label=Settings
# LOCALIZATION NOTE (toolbox.closebutton.tooltip): This is the tooltip for
# the close button the developer tools toolbox.
deleted file mode 100644
--- a/devtools/client/themes/images/command-console.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<!-- 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/. -->
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="context-fill #0b0b0b">
- <path d="M6.8 9.7c0-.2 0-.3-.2-.4L4.9 7.6c-.3-.3-.7-.3-.9 0s-.3.6 0 .9l1.3 1.4L4 11.3c-.3.3-.3.6 0 .9s.6.3.9 0l1.8-1.8c.1-.2.2-.5.1-.7z"/>
- <path d="M14.2 2H1.8c-.4 0-.8.4-.8.9v11.2c0 .4.3.9.8.9h12.4c.4 0 .8-.4.8-.9V2.9c0-.7-.6-.9-.8-.9zM14 14H2V6h12v8zm0-9H2V3h12v2z"/>
-</svg>
--- a/devtools/client/themes/toolbox.css
+++ b/devtools/client/themes/toolbox.css
@@ -9,17 +9,16 @@
--command-paintflashing-image: url(images/command-paintflashing.svg);
--command-screenshot-image: url(images/command-screenshot.svg);
--command-responsive-image: url(images/command-responsivemode.svg);
--command-scratchpad-image: url(images/tool-scratchpad.svg);
--command-pick-image: url(images/command-pick.svg);
--command-pick-accessibility-image: url(images/command-pick-accessibility.svg);
--command-frames-image: url(images/command-frames.svg);
- --command-splitconsole-image: url(images/command-console.svg);
--command-noautohide-image: url(images/command-noautohide.svg);
--command-rulers-image: url(images/command-rulers.svg);
--command-measure-image: url(images/command-measure.svg);
}
/* Toolbox tabbar */
.devtools-tabbar {
@@ -208,20 +207,16 @@
#command-button-pick::before {
background-image: var(--command-pick-image);
}
#command-button-pick.accessibility::before {
background-image: var(--command-pick-accessibility-image);
}
-#command-button-splitconsole::before {
- background-image: var(--command-splitconsole-image);
-}
-
#command-button-noautohide::before {
background-image: var(--command-noautohide-image);
}
#command-button-eyedropper::before {
background-image: var(--command-eyedropper-image);
}
--- a/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_split.js
+++ b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_split.js
@@ -2,16 +2,19 @@
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const TEST_URI = "data:text/html;charset=utf-8,Web Console test for splitting";
const {Toolbox} = require("devtools/client/framework/toolbox");
+const {LocalizationHelper} = require("devtools/shared/l10n");
+const L10N =
+ new LocalizationHelper("devtools/client/locales/toolbox.properties");
// Test is slow on Linux EC2 instances - Bug 962931
requestLongerTimeout(2);
add_task(async function() {
let toolbox;
await addTab(TEST_URI);
@@ -29,18 +32,18 @@ add_task(async function() {
checkHostType(Toolbox.HostType.WINDOW);
checkToolboxUI();
await toolbox.switchHost(Toolbox.HostType.BOTTOM);
async function testConsoleLoadOnDifferentPanel() {
info("About to check console loads even when non-webconsole panel is open");
await openPanel("inspector");
- let webconsoleReady = toolbox.once("webconsole-ready");
- toolbox.toggleSplitConsole();
+ const webconsoleReady = toolbox.once("webconsole-ready");
+ await toolbox.toggleSplitConsole();
await webconsoleReady;
ok(true, "Webconsole has been triggered as loaded while another tool is active");
}
async function testKeyboardShortcuts() {
info("About to check that panel responds to ESCAPE keyboard shortcut");
let splitConsoleReady = toolbox.once("split-console");
@@ -55,144 +58,176 @@ add_task(async function() {
await openAndCheckPanel("inspector");
await openAndCheckPanel("styleeditor");
await openAndCheckPanel("performance");
await openAndCheckPanel("netmonitor");
await checkWebconsolePanelOpened();
}
- function getCurrentUIState() {
+ async function getCurrentUIState() {
let deck = toolbox.doc.querySelector("#toolbox-deck");
let webconsolePanel = toolbox.webconsolePanel;
let splitter = toolbox.doc.querySelector("#toolbox-console-splitter");
let containerHeight = deck.parentNode.getBoundingClientRect().height;
let deckHeight = deck.getBoundingClientRect().height;
let webconsoleHeight = webconsolePanel.getBoundingClientRect().height;
let splitterVisibility = !splitter.getAttribute("hidden");
let openedConsolePanel = toolbox.currentToolId === "webconsole";
- let cmdButton = toolbox.doc.querySelector("#command-button-splitconsole");
+ let menuLabel = await getMenuLabel(toolbox);
return {
deckHeight: deckHeight,
containerHeight: containerHeight,
webconsoleHeight: webconsoleHeight,
splitterVisibility: splitterVisibility,
openedConsolePanel: openedConsolePanel,
- buttonSelected: cmdButton.classList.contains("checked")
+ menuLabel,
};
}
+ function getMenuLabel() {
+ return new Promise(resolve => {
+ const button = toolbox.doc.getElementById("toolbox-meatball-menu-button");
+ EventUtils.sendMouseEvent({ type: "click" }, button);
+
+ toolbox.doc.addEventListener("popupshown", () => {
+ const menuItem =
+ toolbox.doc.getElementById("toolbox-meatball-menu-splitconsole");
+
+ // Return undefined if the menu item is not available
+ let label;
+ if (menuItem) {
+ label =
+ menuItem.label ===
+ L10N.getStr("toolbox.meatballMenu.hideconsole.label")
+ ? "hide"
+ : "split";
+ }
+
+ // Wait for menu to close
+ toolbox.doc.addEventListener("popuphidden", () => {
+ resolve(label);
+ }, { once: true });
+ EventUtils.synthesizeKey("KEY_Escape");
+ }, { once: true });
+ });
+ }
+
async function checkWebconsolePanelOpened() {
info("About to check special cases when webconsole panel is open.");
// Start with console split, so we can test for transition to main panel.
await toolbox.toggleSplitConsole();
- let currentUIState = getCurrentUIState();
+ let currentUIState = await getCurrentUIState();
ok(currentUIState.splitterVisibility,
"Splitter is visible when console is split");
ok(currentUIState.deckHeight > 0,
"Deck has a height > 0 when console is split");
ok(currentUIState.webconsoleHeight > 0,
"Web console has a height > 0 when console is split");
ok(!currentUIState.openedConsolePanel,
"The console panel is not the current tool");
- ok(currentUIState.buttonSelected, "The command button is selected");
+ is(currentUIState.menuLabel, "hide",
+ "The menu item indicates the console is split");
await openPanel("webconsole");
- currentUIState = getCurrentUIState();
+ currentUIState = await getCurrentUIState();
ok(!currentUIState.splitterVisibility,
"Splitter is hidden when console is opened.");
is(currentUIState.deckHeight, 0,
"Deck has a height == 0 when console is opened.");
is(currentUIState.webconsoleHeight, currentUIState.containerHeight,
"Web console is full height.");
ok(currentUIState.openedConsolePanel,
"The console panel is the current tool");
- ok(currentUIState.buttonSelected,
- "The command button is still selected.");
+ is(currentUIState.menuLabel, undefined,
+ "The menu item is hidden when console is opened");
// Make sure splitting console does nothing while webconsole is opened
await toolbox.toggleSplitConsole();
- currentUIState = getCurrentUIState();
+ currentUIState = await getCurrentUIState();
ok(!currentUIState.splitterVisibility,
"Splitter is hidden when console is opened.");
is(currentUIState.deckHeight, 0,
"Deck has a height == 0 when console is opened.");
is(currentUIState.webconsoleHeight, currentUIState.containerHeight,
"Web console is full height.");
ok(currentUIState.openedConsolePanel,
"The console panel is the current tool");
- ok(currentUIState.buttonSelected,
- "The command button is still selected.");
+ is(currentUIState.menuLabel, undefined,
+ "The menu item is hidden when console is opened");
// Make sure that split state is saved after opening another panel
await openPanel("inspector");
- currentUIState = getCurrentUIState();
+ currentUIState = await getCurrentUIState();
ok(currentUIState.splitterVisibility,
"Splitter is visible when console is split");
ok(currentUIState.deckHeight > 0,
"Deck has a height > 0 when console is split");
ok(currentUIState.webconsoleHeight > 0,
"Web console has a height > 0 when console is split");
ok(!currentUIState.openedConsolePanel,
"The console panel is not the current tool");
- ok(currentUIState.buttonSelected,
- "The command button is still selected.");
+ is(currentUIState.menuLabel, "hide",
+ "The menu item still indicates the console is split");
await toolbox.toggleSplitConsole();
}
async function checkToolboxUI() {
- let currentUIState = getCurrentUIState();
+ let currentUIState = await getCurrentUIState();
ok(!currentUIState.splitterVisibility, "Splitter is hidden by default");
is(currentUIState.deckHeight, currentUIState.containerHeight,
"Deck has a height > 0 by default");
is(currentUIState.webconsoleHeight, 0,
"Web console is collapsed by default");
ok(!currentUIState.openedConsolePanel,
"The console panel is not the current tool");
- ok(!currentUIState.buttonSelected, "The command button is not selected.");
+ is(currentUIState.menuLabel, "split",
+ "The menu item indicates the console is not split");
await toolbox.toggleSplitConsole();
- currentUIState = getCurrentUIState();
+ currentUIState = await getCurrentUIState();
ok(currentUIState.splitterVisibility,
"Splitter is visible when console is split");
ok(currentUIState.deckHeight > 0,
"Deck has a height > 0 when console is split");
ok(currentUIState.webconsoleHeight > 0,
"Web console has a height > 0 when console is split");
is(Math.round(currentUIState.deckHeight + currentUIState.webconsoleHeight),
currentUIState.containerHeight,
"Everything adds up to container height");
ok(!currentUIState.openedConsolePanel,
"The console panel is not the current tool");
- ok(currentUIState.buttonSelected, "The command button is selected.");
+ is(currentUIState.menuLabel, "hide",
+ "The menu item indicates the console is split");
await toolbox.toggleSplitConsole();
- currentUIState = getCurrentUIState();
+ currentUIState = await getCurrentUIState();
ok(!currentUIState.splitterVisibility, "Splitter is hidden after toggling");
is(currentUIState.deckHeight, currentUIState.containerHeight,
"Deck has a height > 0 after toggling");
is(currentUIState.webconsoleHeight, 0,
"Web console is collapsed after toggling");
ok(!currentUIState.openedConsolePanel,
"The console panel is not the current tool");
- ok(!currentUIState.buttonSelected, "The command button is not selected.");
+ is(currentUIState.menuLabel, "split",
+ "The menu item indicates the console is not split");
}
async function openPanel(toolId) {
let target = TargetFactory.forTab(gBrowser.selectedTab);
toolbox = await gDevTools.showToolbox(target, toolId);
}
async function openAndCheckPanel(toolId) {
--- a/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_split_persist.js
+++ b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_split_persist.js
@@ -2,57 +2,63 @@
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test that the split console state is persisted.
+let {LocalizationHelper} = require("devtools/shared/l10n");
+let L10N = new LocalizationHelper("devtools/client/locales/toolbox.properties");
+
const TEST_URI = "data:text/html;charset=utf-8,<p>Web Console test for splitting</p>";
add_task(async function() {
info("Opening a tab while there is no user setting on split console pref");
let toolbox = await openNewTabAndToolbox(TEST_URI, "inspector");
ok(!toolbox.splitConsole, "Split console is hidden by default");
- ok(!isCommandButtonChecked(toolbox), "Split console button is unchecked by default.");
+ ok(!(await doesMenuSayHide(toolbox)),
+ "Split console menu item says split by default");
await toggleSplitConsoleWithEscape(toolbox);
ok(toolbox.splitConsole, "Split console is now visible.");
- ok(isCommandButtonChecked(toolbox), "Split console button is now checked.");
+ ok(await doesMenuSayHide(toolbox), "Split console menu item now says hide");
ok(getVisiblePrefValue(), "Visibility pref is true");
is(getHeightPrefValue(), toolbox.webconsolePanel.height,
"Panel height matches the pref");
toolbox.webconsolePanel.height = 200;
await toolbox.destroy();
info("Opening a tab while there is a true user setting on split console pref");
toolbox = await openNewTabAndToolbox(TEST_URI, "inspector");
ok(toolbox.splitConsole, "Split console is visible by default.");
- ok(isCommandButtonChecked(toolbox), "Split console button is checked by default.");
+ ok(await doesMenuSayHide(toolbox),
+ "Split console menu item initially says hide");
is(getHeightPrefValue(), 200, "Height is set based on panel height after closing");
let activeElement = getActiveElement(toolbox.doc);
let inputNode = toolbox.getPanel("webconsole").hud.jsterm.inputNode;
is(activeElement, inputNode, "Split console input is focused by default");
toolbox.webconsolePanel.height = 1;
ok(toolbox.webconsolePanel.clientHeight > 1,
"The actual height of the console is bound with a min height");
toolbox.webconsolePanel.height = 10000;
ok(toolbox.webconsolePanel.clientHeight < 10000,
"The actual height of the console is bound with a max height");
await toggleSplitConsoleWithEscape(toolbox);
ok(!toolbox.splitConsole, "Split console is now hidden.");
- ok(!isCommandButtonChecked(toolbox), "Split console button is now unchecked.");
+ ok(!(await doesMenuSayHide(toolbox)),
+ "Split console menu item now says split");
ok(!getVisiblePrefValue(), "Visibility pref is false");
await toolbox.destroy();
is(getHeightPrefValue(), 10000, "Height is set based on panel height after closing");
info("Opening a tab while there is a false user setting on split " +
"console pref");
@@ -75,19 +81,38 @@ function getActiveElement(doc) {
function getVisiblePrefValue() {
return Services.prefs.getBoolPref("devtools.toolbox.splitconsoleEnabled");
}
function getHeightPrefValue() {
return Services.prefs.getIntPref("devtools.toolbox.splitconsoleHeight");
}
-function isCommandButtonChecked(toolbox) {
- return toolbox.doc.querySelector("#command-button-splitconsole")
- .classList.contains("checked");
+function doesMenuSayHide(toolbox) {
+ return new Promise(resolve => {
+ const button = toolbox.doc.getElementById("toolbox-meatball-menu-button");
+ EventUtils.sendMouseEvent({ type: "click" }, button);
+
+ toolbox.doc.addEventListener("popupshown", () => {
+ const menuItem =
+ toolbox.doc.getElementById("toolbox-meatball-menu-splitconsole");
+
+ const result =
+ menuItem &&
+ menuItem.label ===
+ L10N.getStr("toolbox.meatballMenu.hideconsole.label");
+
+ toolbox.doc.addEventListener("popuphidden", () => {
+ resolve(result);
+ },
+ { once: true });
+ EventUtils.synthesizeKey("KEY_Escape");
+ },
+ { once: true });
+ });
}
function toggleSplitConsoleWithEscape(toolbox) {
let onceSplitConsole = toolbox.once("split-console");
let toolboxWindow = toolbox.win;
toolboxWindow.focus();
EventUtils.sendKey("ESCAPE", toolboxWindow);
return onceSplitConsole;
--- a/devtools/client/webconsole/test/browser_webconsole_split.js
+++ b/devtools/client/webconsole/test/browser_webconsole_split.js
@@ -8,32 +8,39 @@
const TEST_URI = "data:text/html;charset=utf-8,Web Console test for splitting";
function test() {
waitForExplicitFinish();
// Test is slow on Linux EC2 instances - Bug 962931
requestLongerTimeout(2);
let {Toolbox} = require("devtools/client/framework/toolbox");
+ let {LocalizationHelper} = require("devtools/shared/l10n");
+ let L10N =
+ new LocalizationHelper("devtools/client/locales/toolbox.properties");
let toolbox;
loadTab(TEST_URI).then(testConsoleLoadOnDifferentPanel);
function testConsoleLoadOnDifferentPanel() {
info("About to check console loads even when non-webconsole panel is open");
openPanel("inspector").then(() => {
+ let initialOpenComplete;
+
toolbox.on("webconsole-ready", () => {
ok(true, "Webconsole has been triggered as loaded while another tool " +
"is active");
- testKeyboardShortcuts();
+ initialOpenComplete.then(() => {
+ testKeyboardShortcuts();
+ });
});
// Opens split console.
- toolbox.toggleSplitConsole();
+ initialOpenComplete = toolbox.toggleSplitConsole();
});
}
function testKeyboardShortcuts() {
info("About to check that panel responds to ESCAPE keyboard shortcut");
toolbox.once("split-console", () => {
ok(true, "Split console has been triggered via ESCAPE keypress");
@@ -54,148 +61,179 @@ function test() {
yield openAndCheckPanel("performance");
yield openAndCheckPanel("netmonitor");
yield checkWebconsolePanelOpened();
testBottomHost();
});
}
- function getCurrentUIState() {
+ async function getCurrentUIState() {
let win = toolbox.win;
let deck = toolbox.doc.querySelector("#toolbox-deck");
let webconsolePanel = toolbox.webconsolePanel;
let splitter = toolbox.doc.querySelector("#toolbox-console-splitter");
let containerHeight = parseFloat(win.getComputedStyle(deck.parentNode)
.getPropertyValue("height"));
let deckHeight = parseFloat(win.getComputedStyle(deck)
.getPropertyValue("height"));
let webconsoleHeight = parseFloat(win.getComputedStyle(webconsolePanel)
.getPropertyValue("height"));
let splitterVisibility = !splitter.getAttribute("hidden");
let openedConsolePanel = toolbox.currentToolId === "webconsole";
- let cmdButton = toolbox.doc.querySelector("#command-button-splitconsole");
return {
deckHeight: deckHeight,
containerHeight: containerHeight,
webconsoleHeight: webconsoleHeight,
splitterVisibility: splitterVisibility,
openedConsolePanel: openedConsolePanel,
- buttonSelected: cmdButton.classList.contains("checked")
+ menuLabel: await getMenuLabel(toolbox),
};
}
+ function getMenuLabel(toolbox) {
+ return new Promise(resolve => {
+ const button = toolbox.doc.getElementById("toolbox-meatball-menu-button");
+ EventUtils.sendMouseEvent({ type: "click" }, button);
+
+ toolbox.doc.addEventListener("popupshown", () => {
+ const menuItem =
+ toolbox.doc.getElementById("toolbox-meatball-menu-splitconsole");
+
+ // Return undefined if the menu item is not available
+ let label;
+ if (menuItem) {
+ label =
+ menuItem.label ===
+ L10N.getStr("toolbox.meatballMenu.hideconsole.label")
+ ? "hide"
+ : "split";
+ }
+
+ // Wait for menu to close
+ toolbox.doc.addEventListener("popuphidden", () => {
+ resolve(label);
+ }, { once: true });
+ EventUtils.synthesizeKey("KEY_Escape");
+ }, { once: true });
+ });
+ }
+
const checkWebconsolePanelOpened = Task.async(function* () {
info("About to check special cases when webconsole panel is open.");
// Start with console split, so we can test for transition to main panel.
yield toolbox.toggleSplitConsole();
- let currentUIState = getCurrentUIState();
+ let currentUIState = yield getCurrentUIState();
ok(currentUIState.splitterVisibility,
"Splitter is visible when console is split");
ok(currentUIState.deckHeight > 0,
"Deck has a height > 0 when console is split");
ok(currentUIState.webconsoleHeight > 0,
"Web console has a height > 0 when console is split");
ok(!currentUIState.openedConsolePanel,
"The console panel is not the current tool");
- ok(currentUIState.buttonSelected, "The command button is selected");
+ is(currentUIState.menuLabel, "hide",
+ "The menu item indicates the console is split");
yield openPanel("webconsole");
- currentUIState = getCurrentUIState();
+ currentUIState = yield getCurrentUIState();
ok(!currentUIState.splitterVisibility,
"Splitter is hidden when console is opened.");
is(currentUIState.deckHeight, 0,
"Deck has a height == 0 when console is opened.");
is(currentUIState.webconsoleHeight, currentUIState.containerHeight,
"Web console is full height.");
ok(currentUIState.openedConsolePanel,
"The console panel is the current tool");
- ok(currentUIState.buttonSelected,
- "The command button is still selected.");
+ is(currentUIState.menuLabel, undefined,
+ "The menu item is hidden when console is opened");
// Make sure splitting console does nothing while webconsole is opened
yield toolbox.toggleSplitConsole();
- currentUIState = getCurrentUIState();
+ currentUIState = yield getCurrentUIState();
ok(!currentUIState.splitterVisibility,
"Splitter is hidden when console is opened.");
is(currentUIState.deckHeight, 0,
"Deck has a height == 0 when console is opened.");
is(currentUIState.webconsoleHeight, currentUIState.containerHeight,
"Web console is full height.");
ok(currentUIState.openedConsolePanel,
"The console panel is the current tool");
- ok(currentUIState.buttonSelected,
- "The command button is still selected.");
+ is(currentUIState.menuLabel, undefined,
+ "The menu item is hidden when console is opened");
// Make sure that split state is saved after opening another panel
yield openPanel("inspector");
- currentUIState = getCurrentUIState();
+ currentUIState = yield getCurrentUIState();
ok(currentUIState.splitterVisibility,
"Splitter is visible when console is split");
ok(currentUIState.deckHeight > 0,
"Deck has a height > 0 when console is split");
ok(currentUIState.webconsoleHeight > 0,
"Web console has a height > 0 when console is split");
ok(!currentUIState.openedConsolePanel,
"The console panel is not the current tool");
- ok(currentUIState.buttonSelected,
- "The command button is still selected.");
+ is(currentUIState.menuLabel, "hide",
+ "The menu item still indicates the console is split");
yield toolbox.toggleSplitConsole();
});
const checkToolboxUI = Task.async(function* () {
- let currentUIState = getCurrentUIState();
+ let currentUIState = yield getCurrentUIState();
ok(!currentUIState.splitterVisibility, "Splitter is hidden by default");
is(currentUIState.deckHeight, currentUIState.containerHeight,
"Deck has a height > 0 by default");
is(currentUIState.webconsoleHeight, 0,
"Web console is collapsed by default");
ok(!currentUIState.openedConsolePanel,
"The console panel is not the current tool");
- ok(!currentUIState.buttonSelected, "The command button is not selected.");
+ is(currentUIState.menuLabel, "split",
+ "The menu item indicates the console is not split");
yield toolbox.toggleSplitConsole();
- currentUIState = getCurrentUIState();
+ currentUIState = yield getCurrentUIState();
ok(currentUIState.splitterVisibility,
"Splitter is visible when console is split");
ok(currentUIState.deckHeight > 0,
"Deck has a height > 0 when console is split");
ok(currentUIState.webconsoleHeight > 0,
"Web console has a height > 0 when console is split");
is(Math.round(currentUIState.deckHeight + currentUIState.webconsoleHeight),
currentUIState.containerHeight,
"Everything adds up to container height");
ok(!currentUIState.openedConsolePanel,
"The console panel is not the current tool");
- ok(currentUIState.buttonSelected, "The command button is selected.");
+ is(currentUIState.menuLabel, "hide",
+ "The menu item indicates the console is split");
yield toolbox.toggleSplitConsole();
- currentUIState = getCurrentUIState();
+ currentUIState = yield getCurrentUIState();
ok(!currentUIState.splitterVisibility, "Splitter is hidden after toggling");
is(currentUIState.deckHeight, currentUIState.containerHeight,
"Deck has a height > 0 after toggling");
is(currentUIState.webconsoleHeight, 0,
"Web console is collapsed after toggling");
ok(!currentUIState.openedConsolePanel,
"The console panel is not the current tool");
- ok(!currentUIState.buttonSelected, "The command button is not selected.");
+ is(currentUIState.menuLabel, "split",
+ "The menu item indicates the console is not split");
});
function openPanel(toolId) {
let deferred = defer();
let target = TargetFactory.forTab(gBrowser.selectedTab);
gDevTools.showToolbox(target, toolId).then(function (box) {
toolbox = box;
deferred.resolve();
--- a/devtools/client/webconsole/test/browser_webconsole_split_persist.js
+++ b/devtools/client/webconsole/test/browser_webconsole_split_persist.js
@@ -3,50 +3,54 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
function test() {
info("Test that the split console state is persisted");
+ let {LocalizationHelper} = require("devtools/shared/l10n");
+ let L10N =
+ new LocalizationHelper("devtools/client/locales/toolbox.properties");
+
let toolbox;
let TEST_URI = "data:text/html;charset=utf-8,<p>Web Console test for " +
"splitting</p>";
Task.spawn(runner).then(finish);
function* runner() {
info("Opening a tab while there is no user setting on split console pref");
let {tab} = yield loadTab(TEST_URI);
let target = TargetFactory.forTab(tab);
toolbox = yield gDevTools.showToolbox(target, "inspector");
ok(!toolbox.splitConsole, "Split console is hidden by default.");
- ok(!isCommandButtonChecked(), "Split console button is unchecked by " +
- "default.");
+ ok(!(yield doesMenuSayHide()),
+ "Split console menu item says split by default");
yield toggleSplitConsoleWithEscape();
ok(toolbox.splitConsole, "Split console is now visible.");
- ok(isCommandButtonChecked(), "Split console button is now checked.");
+ ok(yield doesMenuSayHide(), "Split console menu item now says hide");
ok(getVisiblePrefValue(), "Visibility pref is true");
is(getHeightPrefValue(), toolbox.webconsolePanel.height,
"Panel height matches the pref");
toolbox.webconsolePanel.height = 200;
yield toolbox.destroy();
info("Opening a tab while there is a true user setting on split console " +
"pref");
({tab} = yield loadTab(TEST_URI));
target = TargetFactory.forTab(tab);
toolbox = yield gDevTools.showToolbox(target, "inspector");
ok(toolbox.splitConsole, "Split console is visible by default.");
- ok(isCommandButtonChecked(), "Split console button is checked by default.");
+ ok(yield doesMenuSayHide(), "Split console menu item initially says hide");
is(getHeightPrefValue(), 200, "Height is set based on panel height after " +
"closing");
// Use the binding element since jsterm.inputNode is a XUL textarea element.
let activeElement = getActiveElement(toolbox.doc);
activeElement = activeElement.ownerDocument.getBindingParent(activeElement);
let inputNode = toolbox.getPanel("webconsole").hud.jsterm.inputNode;
is(activeElement, inputNode, "Split console input is focused by default");
@@ -56,17 +60,17 @@
"The actual height of the console is bound with a min height");
toolbox.webconsolePanel.height = 10000;
ok(toolbox.webconsolePanel.clientHeight < 10000,
"The actual height of the console is bound with a max height");
yield toggleSplitConsoleWithEscape();
ok(!toolbox.splitConsole, "Split console is now hidden.");
- ok(!isCommandButtonChecked(), "Split console button is now unchecked.");
+ ok(!(yield doesMenuSayHide()), "Split console menu item now says split");
ok(!getVisiblePrefValue(), "Visibility pref is false");
yield toolbox.destroy();
is(getHeightPrefValue(), 10000,
"Height is set based on panel height after closing");
info("Opening a tab while there is a false user setting on split " +
@@ -92,26 +96,45 @@
function getVisiblePrefValue() {
return Services.prefs.getBoolPref("devtools.toolbox.splitconsoleEnabled");
}
function getHeightPrefValue() {
return Services.prefs.getIntPref("devtools.toolbox.splitconsoleHeight");
}
- function isCommandButtonChecked() {
- return toolbox.doc.querySelector("#command-button-splitconsole")
- .classList.contains("checked");
+ function doesMenuSayHide() {
+ return new Promise(resolve => {
+ const button = toolbox.doc.getElementById("toolbox-meatball-menu-button");
+ EventUtils.sendMouseEvent({ type: "click" }, button);
+
+ toolbox.doc.addEventListener("popupshown", () => {
+ const menuItem =
+ toolbox.doc.getElementById("toolbox-meatball-menu-splitconsole");
+
+ const result =
+ menuItem &&
+ menuItem.label ===
+ L10N.getStr("toolbox.meatballMenu.hideconsole.label");
+
+ toolbox.doc.addEventListener("popuphidden", () => {
+ resolve(result);
+ },
+ { once: true });
+ EventUtils.synthesizeKey("KEY_Escape");
+ },
+ { once: true });
+ });
}
function toggleSplitConsoleWithEscape() {
let onceSplitConsole = toolbox.once("split-console");
let contentWindow = toolbox.win;
contentWindow.focus();
- EventUtils.sendKey("ESCAPE", contentWindow);
+ EventUtils.synthesizeKey("KEY_Escape");
return onceSplitConsole;
}
function finish() {
toolbox = TEST_URI = null;
finishTest();
}
}