--- a/devtools/client/framework/devtools-browser.js
+++ b/devtools/client/framework/devtools-browser.js
@@ -19,17 +19,16 @@ const {gDevTools} = require("./devtools"
// Load target and toolbox lazily as they need gDevTools to be fully initialized
loader.lazyRequireGetter(this, "TargetFactory", "devtools/client/framework/target", true);
loader.lazyRequireGetter(this, "Toolbox", "devtools/client/framework/toolbox", true);
loader.lazyRequireGetter(this, "DebuggerServer", "devtools/server/main", true);
loader.lazyRequireGetter(this, "DebuggerClient", "devtools/shared/client/debugger-client", true);
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.lazyRequireGetter(this, "ResponsiveUIManager", "devtools/client/responsive.html/manager", true);
loader.lazyImporter(this, "BrowserToolboxProcess", "resource://devtools/client/framework/ToolboxProcess.jsm");
loader.lazyImporter(this, "ScratchpadManager", "resource://devtools/client/scratchpad/scratchpad-manager.jsm");
loader.lazyImporter(this, "CustomizableUI", "resource:///modules/CustomizableUI.jsm");
const {LocalizationHelper} = require("devtools/shared/l10n");
const L10N = new LocalizationHelper("devtools/client/locales/toolbox.properties");
@@ -49,21 +48,16 @@ var gDevToolsBrowser = exports.gDevTools
/**
* WeakMap keeping track of the devtools-browser stylesheets loaded in the various
* tracked windows.
*/
_browserStyleSheets: new WeakMap(),
/**
- * WeakMap keeping track of DeveloperToolbar instances for each firefox window.
- */
- _toolbars: new WeakMap(),
-
- /**
* This function is for the benefit of Tools:DevToolbox in
* browser/base/content/browser-sets.inc and should not be used outside
* of there
*/
// used by browser-sets.inc, command
toggleToolboxCommand(gBrowser, startTime) {
let target = TargetFactory.forTab(gBrowser.selectedTab);
let toolbox = gDevTools.getToolbox(target);
@@ -93,29 +87,16 @@ var gDevToolsBrowser = exports.gDevTools
cmd.removeAttribute("disabled");
cmd.removeAttribute("hidden");
} else {
cmd.setAttribute("disabled", "true");
cmd.setAttribute("hidden", "true");
}
}
- // Enable developer toolbar?
- let devToolbarEnabled = Services.prefs.getBoolPref("devtools.toolbar.enabled");
- toggleMenuItem("menu_devToolbar", devToolbarEnabled);
- let focusEl = doc.getElementById("menu_devToolbar");
- if (devToolbarEnabled) {
- focusEl.removeAttribute("disabled");
- } else {
- focusEl.setAttribute("disabled", "true");
- }
- if (devToolbarEnabled && Services.prefs.getBoolPref("devtools.toolbar.visible")) {
- this.getDeveloperToolbar(win).show(false).catch(console.error);
- }
-
// Enable WebIDE?
let webIDEEnabled = Services.prefs.getBoolPref("devtools.webide.enabled");
toggleMenuItem("menu_webide", webIDEEnabled);
if (webIDEEnabled) {
gDevToolsBrowser.installWebIDEWidget();
} else {
gDevToolsBrowser.uninstallWebIDEWidget();
@@ -259,19 +240,16 @@ var gDevToolsBrowser = exports.gDevTools
return;
}
// Otherwise implement all other key shortcuts individually here
switch (key.id) {
case "toggleToolbox":
case "toggleToolboxF12":
gDevToolsBrowser.toggleToolboxCommand(window.gBrowser, startTime);
break;
- case "toggleToolbar":
- gDevToolsBrowser.getDeveloperToolbar(window).focusToggle();
- break;
case "webide":
gDevToolsBrowser.openWebIDE();
break;
case "browserToolbox":
BrowserToolboxProcess.init();
break;
case "browserConsole":
let {HUDService} = require("devtools/client/webconsole/hudservice");
@@ -482,32 +460,16 @@ var gDevToolsBrowser = exports.gDevTools
this.ensurePrefObserver();
win.addEventListener("unload", this);
let tabContainer = win.gBrowser.tabContainer;
tabContainer.addEventListener("TabSelect", this);
},
/**
- * Create singleton instance of the developer toolbar for a given top level window.
- *
- * @param {Window} win
- * The window to which the toolbar should be created.
- */
- getDeveloperToolbar(win) {
- let toolbar = this._toolbars.get(win);
- if (toolbar) {
- return toolbar;
- }
- toolbar = new DeveloperToolbar(win);
- this._toolbars.set(win, toolbar);
- return toolbar;
- },
-
- /**
* Hook the JS debugger tool to the "Debug Script" button of the slow script
* dialog.
*/
setSlowScriptDebugHandler() {
let debugService = Cc["@mozilla.org/dom/slow-script-debug;1"]
.getService(Ci.nsISlowScriptDebug);
function slowScriptDebugHandler(tab, callback) {
@@ -705,18 +667,16 @@ var gDevToolsBrowser = exports.gDevTools
}
let styleSheet = this._browserStyleSheets.get(win);
if (styleSheet) {
styleSheet.remove();
this._browserStyleSheets.delete(win);
}
- this._toolbars.delete(win);
-
let tabContainer = win.gBrowser.tabContainer;
tabContainer.removeEventListener("TabSelect", this);
},
handleEvent(event) {
switch (event.type) {
case "TabSelect":
gDevToolsBrowser._updateMenuCheckbox();
--- a/devtools/client/framework/test/browser_dynamic_tool_enabling.js
+++ b/devtools/client/framework/test/browser_dynamic_tool_enabling.js
@@ -1,17 +1,16 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* 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/ */
// Tests that toggling prefs immediately (de)activates the relevant menuitem
var gItemsToTest = {
- "menu_devToolbar": "devtools.toolbar.enabled",
"menu_browserToolbox": ["devtools.chrome.enabled", "devtools.debugger.remote-enabled"],
"menu_devtools_connect": "devtools.debugger.remote-enabled",
};
function expectedAttributeValueFromPrefs(prefs) {
return prefs.every((pref) => Services.prefs.getBoolPref(pref)) ?
"" : "true";
}
--- a/devtools/client/locales/en-US/menus.properties
+++ b/devtools/client/locales/en-US/menus.properties
@@ -36,19 +36,16 @@ browserToolboxMenu.label = Browser Toolb
browserToolboxMenu.accesskey = e
# LOCALIZATION NOTE (browserContentToolboxMenu.label): This is the label for the
# application menu item that opens the browser content toolbox UI in the Tools menu.
# This toolbox allows to debug the chrome of the content process in multiprocess builds.
browserContentToolboxMenu.label = Browser Content Toolbox
browserContentToolboxMenu.accesskey = x
-devToolbarMenu.label = Developer Toolbar
-devToolbarMenu.accesskey = v
-
webide.label = WebIDE
webide.accesskey = W
devToolboxMenuItem.label = Toggle Tools
devToolboxMenuItem.accesskey = T
getMoreDevtoolsCmd.label = Get More Tools
getMoreDevtoolsCmd.accesskey = M
--- a/devtools/client/locales/en-US/toolbox.properties
+++ b/devtools/client/locales/en-US/toolbox.properties
@@ -1,41 +1,12 @@
# 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 (toolboxToggleButton.errors): Semi-colon list of plural
-# forms.
-# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
-# #1 number of errors in the current web page
-toolboxToggleButton.errors=#1 error;#1 errors
-
-# LOCALIZATION NOTE (toolboxToggleButton.warnings): Semi-colon list of plural
-# forms.
-# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
-# #1 number of warnings in the current web page
-toolboxToggleButton.warnings=#1 warning;#1 warnings
-
-# LOCALIZATION NOTE (toolboxToggleButton.tooltip): This string is shown
-# as tooltip in the developer toolbar to open/close the developer tools.
-# It's using toolboxToggleButton.errors as first and
-# toolboxToggleButton.warnings as second argument to show the number of errors
-# and warnings.
-toolboxToggleButton.tooltip=%1$S, %2$S\nClick to toggle the developer tools.
-
-# LOCALIZATION NOTE (toolbar.closeButton.tooltip)
-# Used as a message in tooltip when overing the close button of the Developer
-# Toolbar.
-toolbar.closeButton.tooltip=Close Developer Toolbar
-
-# LOCALIZATION NOTE (toolbar.toolsButton.tooltip)
-# Used as a message in tooltip when overing the wrench icon of the Developer
-# Toolbar, which toggle the developer toolbox.
-toolbar.toolsButton.tooltip=Toggle developer tools
-
# LOCALIZATION NOTE (toolbox.titleTemplate1): This is the template
# used to format the title of the toolbox.
# The URL of the page being targeted: %1$S.
toolbox.titleTemplate1=Developer Tools - %1$S
# LOCALIZATION NOTE (toolbox.titleTemplate2): This is the template
# used to format the title of the toolbox.
# The page title or other name for the thing being targeted: %1$S
--- a/devtools/client/menus.js
+++ b/devtools/client/menus.js
@@ -45,33 +45,16 @@ exports.menuitems = [
let window = event.target.ownerDocument.defaultView;
gDevToolsBrowser.toggleToolboxCommand(window.gBrowser, Cu.now());
},
keyId: "toggleToolbox",
checkbox: true
},
{ id: "menu_devtools_separator",
separator: true },
- { id: "menu_devToolbar",
- l10nKey: "devToolbarMenu",
- disabled: true,
- oncommand(event) {
- let window = event.target.ownerDocument.defaultView;
- // Distinguish events when selecting a menuitem, where we either open
- // or close the toolbar and when hitting the key shortcut where we just
- // focus the toolbar if it doesn't already has it.
- if (event.target.tagName.toLowerCase() == "menuitem") {
- gDevToolsBrowser.getDeveloperToolbar(window).toggle();
- } else {
- gDevToolsBrowser.getDeveloperToolbar(window).focusToggle();
- }
- },
- keyId: "toggleToolbar",
- checkbox: true
- },
{ id: "menu_webide",
l10nKey: "webide",
disabled: true,
oncommand() {
gDevToolsBrowser.openWebIDE();
},
keyId: "webide",
},
--- a/devtools/client/preferences/devtools-client.js
+++ b/devtools/client/preferences/devtools-client.js
@@ -8,19 +8,16 @@ pref("devtools.devedition.promo.url", "h
// Only potentially show in beta release
#if MOZ_UPDATE_CHANNEL == beta
pref("devtools.devedition.promo.enabled", true);
#else
pref("devtools.devedition.promo.enabled", false);
#endif
-// Developer toolbar preferences
-pref("devtools.toolbar.enabled", true);
-
// Enable DevTools WebIDE by default
pref("devtools.webide.enabled", true);
// Toolbox preferences
pref("devtools.toolbox.footer.height", 250);
pref("devtools.toolbox.sidebar.width", 500);
pref("devtools.toolbox.host", "bottom");
pref("devtools.toolbox.previousHost", "side");
--- a/devtools/client/shared/developer-toolbar.js
+++ b/devtools/client/shared/developer-toolbar.js
@@ -1,31 +1,17 @@
/* 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";
const promise = require("promise");
-const Services = require("Services");
-const { TargetFactory } = require("devtools/client/framework/target");
-const Telemetry = require("devtools/client/shared/telemetry");
-const {LocalizationHelper} = require("devtools/shared/l10n");
-const L10N = new LocalizationHelper("devtools/client/locales/toolbox.properties");
-
-const NS_XHTML = "http://www.w3.org/1999/xhtml";
-
-const { PluralForm } = require("devtools/shared/plural-form");
loader.lazyRequireGetter(this, "gcliInit", "devtools/shared/gcli/commands/index");
-loader.lazyRequireGetter(this, "ConsoleServiceListener", "devtools/server/actors/webconsole/listeners", true);
-loader.lazyRequireGetter(this, "gDevTools", "devtools/client/framework/devtools", true);
-loader.lazyRequireGetter(this, "gDevToolsBrowser", "devtools/client/framework/devtools-browser", true);
-loader.lazyRequireGetter(this, "nodeConstants", "devtools/shared/dom-node-constants");
-loader.lazyRequireGetter(this, "EventEmitter", "devtools/shared/event-emitter");
/**
* A collection of utilities to help working with commands
*/
var CommandUtils = {
/**
* Caches requisitions created when calling executeOnTarget:
* Target => Requisition Promise
@@ -110,1218 +96,8 @@ var CommandUtils = {
// Error("environment.document is not available in runAt:client commands");
return this.chromeWindow.gBrowser.contentDocumentAsCPOW;
}
};
},
};
exports.CommandUtils = CommandUtils;
-
-/**
- * Due to a number of panel bugs we need a way to check if we are running on
- * Linux. See the comments for TooltipPanel and OutputPanel for further details.
- *
- * When bug 780102 is fixed all isLinux checks can be removed and we can revert
- * to using panels.
- */
-loader.lazyGetter(this, "isLinux", function() {
- return Services.appinfo.OS == "Linux";
-});
-loader.lazyGetter(this, "isMac", function() {
- return Services.appinfo.OS == "Darwin";
-});
-
-/**
- * A component to manage the global developer toolbar, which contains a GCLI
- * and buttons for various developer tools.
- * @param chromeWindow The browser window to which this toolbar is attached
- */
-function DeveloperToolbar(chromeWindow) {
- this._chromeWindow = chromeWindow;
-
- // Will be setup when show() is called
- this.target = null;
-
- // The `_showPromise` will be set once `show` is called the first time, and resolved
- // when the toolbar is shown. Since it will be set to `null` only when `hide` method
- // is called, multiple calls to `show` method will returns this promise instead of
- // process again all the initialization.
- this._showPromise = null;
- // The `_hidePromise` will be set once `hide` is called, and resolved when the method
- // has finished. Once the toolbar is hidden, both `_showPromise` and `_hidePromise`
- // will be set to `null`.
- this._hidePromise = null;
-
- this._doc = chromeWindow.document;
-
- this._telemetry = new Telemetry();
- this._errorsCount = {};
- this._warningsCount = {};
- this._errorListeners = {};
-
- this._onToolboxReady = this._onToolboxReady.bind(this);
- this._onToolboxDestroyed = this._onToolboxDestroyed.bind(this);
-
- EventEmitter.decorate(this);
-}
-exports.DeveloperToolbar = DeveloperToolbar;
-
-/**
- * Inspector notifications dispatched through the nsIObserverService
- */
-const NOTIFICATIONS = {
- /** DeveloperToolbar.show() has been called, and we're working on it */
- LOAD: "developer-toolbar-load",
-
- /** DeveloperToolbar.show() has completed */
- SHOW: "developer-toolbar-show",
-
- /** DeveloperToolbar.hide() has been called */
- HIDE: "developer-toolbar-hide"
-};
-
-/**
- * Attach notification constants to the object prototype so tests etc can
- * use them without needing to import anything
- */
-DeveloperToolbar.prototype.NOTIFICATIONS = NOTIFICATIONS;
-
-/**
- * Is the toolbar open?
- */
-Object.defineProperty(DeveloperToolbar.prototype, "visible", {
- get: function() {
- return this._element && !this._element.hidden;
- },
- enumerable: true
-});
-
-var _gSequenceId = 0;
-
-/**
- * Getter for a unique ID.
- */
-Object.defineProperty(DeveloperToolbar.prototype, "sequenceId", {
- get: function() {
- return _gSequenceId++;
- },
- enumerable: true
-});
-
-/**
- * Create the <toolbar> element to insert within browser UI
- */
-DeveloperToolbar.prototype.createToolbar = function() {
- if (this._element) {
- return;
- }
- let toolbar = this._doc.createElement("toolbar");
- toolbar.setAttribute("id", "developer-toolbar");
- toolbar.setAttribute("hidden", "true");
- toolbar.setAttribute("fullscreentoolbar", "true");
-
- let close = this._doc.createElement("toolbarbutton");
- close.setAttribute("id", "developer-toolbar-closebutton");
- close.setAttribute("class", "close-icon");
- close.addEventListener("command", (event) => {
- this.hide();
- });
- let closeTooltip = L10N.getStr("toolbar.closeButton.tooltip");
- close.setAttribute("tooltiptext", closeTooltip);
-
- let stack = this._doc.createElement("stack");
- stack.setAttribute("flex", "1");
-
- let input = this._doc.createElement("textbox");
- input.setAttribute("class", "gclitoolbar-input-node");
- input.setAttribute("rows", "1");
- stack.appendChild(input);
-
- let hbox = this._doc.createElement("hbox");
- hbox.setAttribute("class", "gclitoolbar-complete-node");
- stack.appendChild(hbox);
-
- let toolboxBtn = this._doc.createElement("toolbarbutton");
- toolboxBtn.setAttribute("id", "developer-toolbar-toolbox-button");
- toolboxBtn.setAttribute("class", "developer-toolbar-button");
- let toolboxTooltip = L10N.getStr("toolbar.toolsButton.tooltip");
- toolboxBtn.setAttribute("tooltiptext", toolboxTooltip);
- let toolboxOpen = gDevToolsBrowser.hasToolboxOpened(this._chromeWindow);
- toolboxBtn.setAttribute("checked", toolboxOpen);
- toolboxBtn.addEventListener("command", function(event) {
- let window = event.target.ownerDocument.defaultView;
- gDevToolsBrowser.toggleToolboxCommand(window.gBrowser);
- });
- this._errorCounterButton = toolboxBtn;
- this._errorCounterButton._defaultTooltipText = toolboxTooltip;
-
- // On Mac, the close button is on the left,
- // while it is on the right on every other platforms.
- if (isMac) {
- toolbar.appendChild(close);
- toolbar.appendChild(stack);
- toolbar.appendChild(toolboxBtn);
- } else {
- toolbar.appendChild(stack);
- toolbar.appendChild(toolboxBtn);
- toolbar.appendChild(close);
- }
-
- this._element = toolbar;
- let bottomBox = this._doc.getElementById("browser-bottombox");
- if (bottomBox) {
- bottomBox.appendChild(this._element);
- } else {
- // SeaMonkey does not have a "browser-bottombox".
- let statusBar = this._doc.getElementById("status-bar");
- if (statusBar) {
- statusBar.parentNode.insertBefore(this._element, statusBar);
- }
- }
-};
-
-/**
- * Called from browser.xul in response to menu-click or keyboard shortcut to
- * toggle the toolbar
- */
-DeveloperToolbar.prototype.toggle = function() {
- if (this.visible) {
- return this.hide().catch(console.error);
- }
- return this.show(true).catch(console.error);
-};
-
-/**
- * Called from browser.xul in response to menu-click or keyboard shortcut to
- * toggle the toolbar.
- * The method returns a promise that would be resolved once focused; if the toolbar is not
- * visible yet it will be automatically shown.
- */
-DeveloperToolbar.prototype.focus = function() {
- if (this.visible) {
- // If the toolbar was just inserted, the <textbox> may still have
- // its binding in process of being applied and not be focusable yet
- return new Promise((resolve, reject) => {
- let checkBinding = () => {
- // Bail out if the toolbar has been destroyed in the meantime
- if (!this._input) {
- reject();
- return;
- }
- // mInputField is a xbl field of <xul:textbox>
- if (typeof this._input.mInputField != "undefined") {
- this._input.focus();
- resolve();
- } else {
- this._input.ownerDocument.defaultView.setTimeout(checkBinding, 50);
- }
- };
- checkBinding();
- });
- }
-
- return this.show(true);
-};
-
-/**
- * Called from browser.xul in response to menu-click or keyboard shortcut to
- * toggle the toolbar
- */
-DeveloperToolbar.prototype.focusToggle = function() {
- if (this.visible) {
- // If we have focus then the active element is the HTML input contained
- // inside the xul input element
- let active = this._chromeWindow.document.activeElement;
- let position = this._input.compareDocumentPosition(active);
- if (position & nodeConstants.DOCUMENT_POSITION_CONTAINED_BY) {
- this.hide();
- } else {
- this._input.focus();
- }
- } else {
- this.show(true);
- }
-};
-
-/**
- * Even if the user has not clicked on 'Got it' in the intro, we only show it
- * once per session.
- * Warning this is slightly messed up because this.DeveloperToolbar is not the
- * same as this.DeveloperToolbar when in browser.js context.
- */
-DeveloperToolbar.introShownThisSession = false;
-
-/**
- * Show the developer toolbar
- */
-DeveloperToolbar.prototype.show = function(focus) {
- // if `_showPromise` is set, just returns it instead of process all the initialization
- // again; ensuring we're focusing the element too if `focus` argument is set to `true`.
- if (this._showPromise !== null) {
- if (focus) {
- return this.focus();
- }
- return this._showPromise;
- }
-
- this._showPromise = ((async function() {
- // hide() is async, so ensure we don't need to wait for hide() to
- // finish. We unconditionally yield here, even if _hidePromise is
- // null, so that the spawn call returns a promise before starting
- // to do any real work.
- await this._hidePromise;
-
- // Append the browser-level stylesheet to the browser document.
- await gDevToolsBrowser.loadBrowserStyleSheet(this._chromeWindow);
-
- this.createToolbar();
-
- Services.prefs.setBoolPref("devtools.toolbar.visible", true);
-
- this._telemetry.toolOpened("developertoolbar");
-
- this._notify(NOTIFICATIONS.LOAD);
-
- this._input = this._doc.querySelector(".gclitoolbar-input-node");
-
- // Initializing GCLI can only be done when we've got content windows to
- // write to, so this needs to be done asynchronously.
- let panelPromises = [
- TooltipPanel.create(this),
- OutputPanel.create(this)
- ];
- let panels = await promise.all(panelPromises);
-
- [ this.tooltipPanel, this.outputPanel ] = panels;
-
- this._doc.getElementById("menu_devToolbar").setAttribute("checked", "true");
-
- this.target = TargetFactory.forTab(this._chromeWindow.gBrowser.selectedTab);
- const options = {
- environment: CommandUtils.createEnvironment(this, "target"),
- document: this.outputPanel.document,
- };
- let requisition = await CommandUtils.createRequisition(this.target, options);
- this.requisition = requisition;
-
- // The <textbox> `value` may still be undefined on the XUL binding if
- // we fetch it early
- let value = this._input.value || "";
- await this.requisition.update(value);
-
- const Inputter = require("gcli/mozui/inputter").Inputter;
- const Completer = require("gcli/mozui/completer").Completer;
- const Tooltip = require("gcli/mozui/tooltip").Tooltip;
- const FocusManager = require("gcli/ui/focus").FocusManager;
-
- this.onOutput = this.requisition.commandOutputManager.onOutput;
-
- this.focusManager = new FocusManager(this._doc, requisition.system.settings);
-
- this.inputter = new Inputter({
- requisition: this.requisition,
- focusManager: this.focusManager,
- element: this._input,
- });
-
- this.completer = new Completer({
- requisition: this.requisition,
- inputter: this.inputter,
- backgroundElement: this._doc.querySelector(".gclitoolbar-stack-node"),
- element: this._doc.querySelector(".gclitoolbar-complete-node"),
- });
-
- this.tooltip = new Tooltip({
- requisition: this.requisition,
- focusManager: this.focusManager,
- inputter: this.inputter,
- element: this.tooltipPanel.hintElement,
- });
-
- this.inputter.tooltip = this.tooltip;
-
- this.focusManager.addMonitoredElement(this.outputPanel._frame);
- this.focusManager.addMonitoredElement(this._element);
-
- this.focusManager.onVisibilityChange.add(this.outputPanel._visibilityChanged,
- this.outputPanel);
- this.focusManager.onVisibilityChange.add(this.tooltipPanel._visibilityChanged,
- this.tooltipPanel);
- this.onOutput.add(this.outputPanel._outputChanged, this.outputPanel);
-
- let tabbrowser = this._chromeWindow.gBrowser;
- tabbrowser.tabContainer.addEventListener("TabSelect", this);
- tabbrowser.tabContainer.addEventListener("TabClose", this);
- tabbrowser.addEventListener("load", this, true);
- tabbrowser.addEventListener("beforeunload", this, true);
-
- gDevTools.on("toolbox-ready", this._onToolboxReady);
- gDevTools.on("toolbox-destroyed", this._onToolboxDestroyed);
-
- this._initErrorsCount(tabbrowser.selectedTab);
-
- this._element.hidden = false;
-
- if (focus) {
- await this.focus();
- }
- this._notify(NOTIFICATIONS.SHOW);
-
- if (!DeveloperToolbar.introShownThisSession) {
- let intro = require("gcli/ui/intro");
- intro.maybeShowIntro(this.requisition.commandOutputManager,
- this.requisition.conversionContext,
- this.outputPanel);
- DeveloperToolbar.introShownThisSession = true;
- }
- }).bind(this))();
-
- return this._showPromise;
-};
-
-/**
- * Hide the developer toolbar.
- */
-DeveloperToolbar.prototype.hide = function() {
- // If we're already in the process of hiding, just returns the promise
- if (this._hidePromise !== null) {
- return this._hidePromise;
- }
-
- // If `_showPromise` is `null`, it means `show` method was never called, so just
- // returns a resolved promise.
- if (this._showPromise === null) {
- return promise.resolve();
- }
-
- // show() is async, so ensure we don't need to wait for show() to finish
- this._hidePromise = this._showPromise.then(() => {
- this._element.hidden = true;
-
- Services.prefs.setBoolPref("devtools.toolbar.visible", false);
-
- this._doc.getElementById("menu_devToolbar").setAttribute("checked", "false");
- this.destroy();
-
- this._telemetry.toolClosed("developertoolbar");
- this._notify(NOTIFICATIONS.HIDE);
-
- // The developer toolbar is now closed, is neither shown or in process of hiding,
- // so we're set to `null` both `_showPromise` and `_hidePromise`.
- this._showPromise = null;
- this._hidePromise = null;
- });
-
- return this._hidePromise;
-};
-
-/**
- * Initialize the listeners needed for tracking the number of errors for a given
- * tab.
- *
- * @private
- * @param nsIDOMNode tab the xul:tab for which you want to track the number of
- * errors.
- */
-DeveloperToolbar.prototype._initErrorsCount = function(tab) {
- let tabId = tab.linkedPanel;
- if (tabId in this._errorsCount) {
- this._updateErrorsCount();
- return;
- }
-
- let window = tab.linkedBrowser.contentWindow;
- let listener = new ConsoleServiceListener(window, {
- onConsoleServiceMessage: this._onPageError.bind(this, tabId),
- });
- listener.init();
-
- this._errorListeners[tabId] = listener;
- this._errorsCount[tabId] = 0;
- this._warningsCount[tabId] = 0;
-
- let messages = listener.getCachedMessages();
- messages.forEach(this._onPageError.bind(this, tabId));
-
- this._updateErrorsCount();
-};
-
-/**
- * Stop the listeners needed for tracking the number of errors for a given
- * tab.
- *
- * @private
- * @param nsIDOMNode tab the xul:tab for which you want to stop tracking the
- * number of errors.
- */
-DeveloperToolbar.prototype._stopErrorsCount = function(tab) {
- let tabId = tab.linkedPanel;
- if (!(tabId in this._errorsCount) || !(tabId in this._warningsCount)) {
- this._updateErrorsCount();
- return;
- }
-
- this._errorListeners[tabId].destroy();
- delete this._errorListeners[tabId];
- delete this._errorsCount[tabId];
- delete this._warningsCount[tabId];
-
- this._updateErrorsCount();
-};
-
-/**
- * Hide the developer toolbar
- */
-DeveloperToolbar.prototype.destroy = function() {
- if (this._input == null) {
- // Already destroyed
- return;
- }
-
- let tabbrowser = this._chromeWindow.gBrowser;
- tabbrowser.tabContainer.removeEventListener("TabSelect", this);
- tabbrowser.tabContainer.removeEventListener("TabClose", this);
- tabbrowser.removeEventListener("load", this, true);
- tabbrowser.removeEventListener("beforeunload", this, true);
-
- gDevTools.off("toolbox-ready", this._onToolboxReady);
- gDevTools.off("toolbox-destroyed", this._onToolboxDestroyed);
-
- Array.prototype.forEach.call(tabbrowser.tabs, this._stopErrorsCount, this);
-
- this.focusManager.removeMonitoredElement(this.outputPanel._frame);
- this.focusManager.removeMonitoredElement(this._element);
-
- this.focusManager.onVisibilityChange.remove(this.outputPanel._visibilityChanged,
- this.outputPanel);
- this.focusManager.onVisibilityChange.remove(this.tooltipPanel._visibilityChanged,
- this.tooltipPanel);
- this.onOutput.remove(this.outputPanel._outputChanged, this.outputPanel);
-
- this.tooltip.destroy();
- this.completer.destroy();
- this.inputter.destroy();
- this.focusManager.destroy();
-
- this.outputPanel.destroy();
- this.tooltipPanel.destroy();
- delete this._input;
-
- CommandUtils.destroyRequisition(this.requisition, this.target);
- this.target = undefined;
-
- this._element.remove();
- delete this._element;
-};
-
-/**
- * Utility for sending notifications
- * @param topic a NOTIFICATION constant
- */
-DeveloperToolbar.prototype._notify = function(topic) {
- let data = { toolbar: this };
- data.wrappedJSObject = data;
- Services.obs.notifyObservers(data, topic);
-};
-
-/**
- * Update various parts of the UI when the current tab changes
- */
-DeveloperToolbar.prototype.handleEvent = function(ev) {
- if (ev.type == "TabSelect" || ev.type == "load") {
- if (this.visible) {
- let tab = this._chromeWindow.gBrowser.selectedTab;
- this.target = TargetFactory.forTab(tab);
- gcliInit.getSystem(this.target).then(system => {
- this.requisition.system = system;
- }, error => {
- if (!this._chromeWindow.gBrowser.getBrowserForTab(tab)) {
- // The tab was closed, suppress the error and print a warning as the
- // destroyed tab was likely the cause.
- console.warn("An error occurred as the tab was closed while " +
- "updating Developer Toolbar state. The error was: ", error);
- return;
- }
-
- // Propagate other errors as they're more likely to cause real issues
- // and thus should cause tests to fail.
- throw error;
- });
-
- if (ev.type == "TabSelect") {
- let toolboxOpen = gDevToolsBrowser.hasToolboxOpened(this._chromeWindow);
- this._errorCounterButton.setAttribute("checked", toolboxOpen);
- this._initErrorsCount(ev.target);
- }
- }
- } else if (ev.type == "TabClose") {
- this._stopErrorsCount(ev.target);
- } else if (ev.type == "beforeunload") {
- this._onPageBeforeUnload(ev);
- }
-};
-
-/**
- * Update toolbox toggle button when toolbox goes on and off
- */
-DeveloperToolbar.prototype._onToolboxReady = function() {
- this._errorCounterButton.setAttribute("checked", "true");
-};
-DeveloperToolbar.prototype._onToolboxDestroyed = function() {
- this._errorCounterButton.setAttribute("checked", "false");
-};
-
-/**
- * Count a page error received for the currently selected tab. This
- * method counts the JavaScript exceptions received and CSS errors/warnings.
- *
- * @private
- * @param string tabId the ID of the tab from where the page error comes.
- * @param object pageError the page error object received from the
- * PageErrorListener.
- */
-DeveloperToolbar.prototype._onPageError = function(tabId, pageError) {
- if (pageError.category == "CSS Parser" ||
- pageError.category == "CSS Loader") {
- return;
- }
- if ((pageError.flags & pageError.warningFlag) ||
- (pageError.flags & pageError.strictFlag)) {
- this._warningsCount[tabId]++;
- } else {
- this._errorsCount[tabId]++;
- }
- this._updateErrorsCount(tabId);
-};
-
-/**
- * The |beforeunload| event handler. This function resets the errors count when
- * a different page starts loading.
- *
- * @private
- * @param Event ev the beforeunload DOM event.
- */
-DeveloperToolbar.prototype._onPageBeforeUnload = function(ev) {
- let window = ev.target.defaultView;
- if (window.top !== window) {
- return;
- }
-
- let tabs = this._chromeWindow.gBrowser.tabs;
- Array.prototype.some.call(tabs, function(tab) {
- if (tab.linkedBrowser.contentWindow === window) {
- let tabId = tab.linkedPanel;
- if (tabId in this._errorsCount || tabId in this._warningsCount) {
- this._errorsCount[tabId] = 0;
- this._warningsCount[tabId] = 0;
- this._updateErrorsCount(tabId);
- }
- return true;
- }
- return false;
- }, this);
-};
-
-/**
- * Update the page errors count displayed in the Web Console button for the
- * currently selected tab.
- *
- * @private
- * @param string [changedTabId] Optional. The tab ID that had its page errors
- * count changed. If this is provided and it doesn't match the currently
- * selected tab, then the button is not updated.
- */
-DeveloperToolbar.prototype._updateErrorsCount = function(changedTabId) {
- let tabId = this._chromeWindow.gBrowser.selectedTab.linkedPanel;
- if (changedTabId && tabId != changedTabId) {
- return;
- }
-
- let errors = this._errorsCount[tabId];
- let warnings = this._warningsCount[tabId];
- let btn = this._errorCounterButton;
- if (errors) {
- let errorsText = L10N.getStr("toolboxToggleButton.errors");
- errorsText = PluralForm.get(errors, errorsText).replace("#1", errors);
-
- let warningsText = L10N.getStr("toolboxToggleButton.warnings");
- warningsText = PluralForm.get(warnings, warningsText).replace("#1", warnings);
-
- let tooltiptext = L10N.getFormatStr("toolboxToggleButton.tooltip",
- errorsText, warningsText);
-
- btn.setAttribute("error-count", errors);
- btn.setAttribute("tooltiptext", tooltiptext);
- } else {
- btn.removeAttribute("error-count");
- btn.setAttribute("tooltiptext", btn._defaultTooltipText);
- }
-
- this.emit("errors-counter-updated");
-};
-
-/**
- * Reset the errors counter for the given tab.
- *
- * @param Element tab The xul:tab for which you want to reset the page
- * errors counters.
- */
-DeveloperToolbar.prototype.resetErrorsCount = function(tab) {
- let tabId = tab.linkedPanel;
- if (tabId in this._errorsCount || tabId in this._warningsCount) {
- this._errorsCount[tabId] = 0;
- this._warningsCount[tabId] = 0;
- this._updateErrorsCount(tabId);
- }
-};
-
-/**
- * Creating a OutputPanel is asynchronous
- */
-function OutputPanel() {
- throw new Error("Use OutputPanel.create()");
-}
-
-/**
- * Panel to handle command line output.
- *
- * There is a tooltip bug on Windows and OSX that prevents tooltips from being
- * positioned properly (bug 786975). There is a Gnome panel bug on Linux that
- * causes ugly focus issues (https://bugzilla.gnome.org/show_bug.cgi?id=621848).
- * We now use a tooltip on Linux and a panel on OSX & Windows.
- *
- * If a panel has no content and no height it is not shown when openPopup is
- * called on Windows and OSX (bug 692348) ... this prevents the panel from
- * appearing the first time it is shown. Setting the panel's height to 1px
- * before calling openPopup works around this issue as we resize it ourselves
- * anyway.
- *
- * @param devtoolbar The parent DeveloperToolbar object
- */
-OutputPanel.create = function(devtoolbar) {
- let outputPanel = Object.create(OutputPanel.prototype);
- return outputPanel._init(devtoolbar);
-};
-
-/**
- * @private See OutputPanel.create
- */
-OutputPanel.prototype._init = function(devtoolbar) {
- return new Promise((resolve, reject) => {
- this._devtoolbar = devtoolbar;
- this._input = this._devtoolbar._input;
- this._toolbar = this._devtoolbar._doc.getElementById("developer-toolbar");
-
- /*
- <tooltip|panel id="gcli-output"
- noautofocus="true"
- noautohide="true"
- class="gcli-panel">
- <html:iframe xmlns:html="http://www.w3.org/1999/xhtml"
- id="gcli-output-frame"
- src="chrome://devtools/content/commandline/commandlineoutput.xhtml"
- sandbox="allow-same-origin"/>
- </tooltip|panel>
- */
-
- // TODO: Switch back from tooltip to panel when metacity focus issue is fixed:
- // https://bugzilla.mozilla.org/show_bug.cgi?id=780102
- this._panel = this._devtoolbar._doc.createElement(isLinux ? "tooltip" : "panel");
-
- this._panel.id = "gcli-output";
- this._panel.classList.add("gcli-panel");
-
- if (isLinux) {
- this.canHide = false;
- this._onpopuphiding = this._onpopuphiding.bind(this);
- this._panel.addEventListener("popuphiding", this._onpopuphiding, true);
- } else {
- this._panel.setAttribute("noautofocus", "true");
- this._panel.setAttribute("noautohide", "true");
-
- // Bug 692348: On Windows and OSX if a panel has no content and no height
- // openPopup fails to display it. Setting the height to 1px alows the panel
- // to be displayed before has content or a real height i.e. the first time
- // it is displayed.
- this._panel.setAttribute("height", "1px");
- }
-
- this._toolbar.parentElement.insertBefore(this._panel, this._toolbar);
-
- this._frame = this._devtoolbar._doc.createElementNS(NS_XHTML, "iframe");
- this._frame.id = "gcli-output-frame";
- this._frame.setAttribute("src", "chrome://devtools/content/commandline/commandlineoutput.xhtml");
- this._frame.setAttribute("sandbox", "allow-same-origin");
- this._panel.appendChild(this._frame);
-
- this.displayedOutput = undefined;
-
- this._update = this._update.bind(this);
-
- // Wire up the element from the iframe, and resolve the promise
- let onload = () => {
- this._frame.removeEventListener("load", onload, true);
-
- this.document = this._frame.contentDocument;
- this._copyTheme();
-
- this._div = this.document.getElementById("gcli-output-root");
- this._div.classList.add("gcli-row-out");
- this._div.setAttribute("aria-live", "assertive");
-
- let styles = this._toolbar.ownerDocument.defaultView
- .getComputedStyle(this._toolbar);
- this._div.setAttribute("dir", styles.direction);
-
- resolve(this);
- };
- this._frame.addEventListener("load", onload, true);
- });
-};
-
-/* Copy the current devtools theme attribute into the iframe,
- so it can be styled correctly. */
-OutputPanel.prototype._copyTheme = function() {
- if (this.document) {
- let theme = this._devtoolbar._doc.getElementById("browser-bottombox")
- .getAttribute("devtoolstheme");
- this.document.documentElement.setAttribute("devtoolstheme", theme);
- }
-};
-
-/**
- * Prevent the popup from hiding if it is not permitted via this.canHide.
- */
-OutputPanel.prototype._onpopuphiding = function(ev) {
- // TODO: When we switch back from tooltip to panel we can remove this hack:
- // https://bugzilla.mozilla.org/show_bug.cgi?id=780102
- if (isLinux && !this.canHide) {
- ev.preventDefault();
- }
-};
-
-/**
- * Display the OutputPanel.
- */
-OutputPanel.prototype.show = function() {
- if (isLinux) {
- this.canHide = false;
- }
-
- // We need to reset the iframe size in order for future size calculations to
- // be correct
- this._frame.style.minHeight = this._frame.style.maxHeight = 0;
- this._frame.style.minWidth = 0;
-
- this._copyTheme();
- this._panel.openPopup(this._input, "before_start", 0, 0, false, false, null);
- this._resize();
-
- this._input.focus();
-};
-
-/**
- * Internal helper to set the height of the output panel to fit the available
- * content;
- */
-OutputPanel.prototype._resize = function() {
- if (this._panel == null || this.document == null || !this._panel.state == "closed") {
- return;
- }
-
- // Set max panel width to match any content with a max of the width of the
- // browser window.
- let maxWidth = this._panel.ownerDocument.documentElement.clientWidth;
-
- // Adjust max width according to OS.
- // We'd like to put this in CSS but we can't:
- // body { width: calc(min(-5px, max-content)); }
- // #_panel { max-width: -5px; }
- switch (Services.appinfo.OS) {
- case "Linux":
- maxWidth -= 5;
- break;
- case "Darwin":
- maxWidth -= 25;
- break;
- case "WINNT":
- maxWidth -= 5;
- break;
- }
-
- this.document.body.style.width = "-moz-max-content";
- let style = this._frame.contentWindow.getComputedStyle(this.document.body);
- let frameWidth = parseInt(style.width, 10);
- let width = Math.min(maxWidth, frameWidth);
- this.document.body.style.width = width + "px";
-
- // Set the width of the iframe.
- this._frame.style.minWidth = width + "px";
- this._panel.style.maxWidth = maxWidth + "px";
-
- // browserAdjustment is used to correct the panel height according to the
- // browsers borders etc.
- const browserAdjustment = 15;
-
- // Set max panel height to match any content with a max of the height of the
- // browser window.
- let maxHeight =
- this._panel.ownerDocument.documentElement.clientHeight - browserAdjustment;
- let height = Math.min(maxHeight, this.document.documentElement.scrollHeight);
-
- // Set the height of the iframe. Setting iframe.height does not work.
- this._frame.style.minHeight = this._frame.style.maxHeight = height + "px";
-
- // Set the height and width of the panel to match the iframe.
- this._panel.sizeTo(width, height);
-
- // Move the panel to the correct position in the case that it has been
- // positioned incorrectly.
- let screenX = this._input.boxObject.screenX;
- let screenY = this._toolbar.boxObject.screenY;
- this._panel.moveTo(screenX, screenY - height);
-};
-
-/**
- * Called by GCLI when a command is executed.
- */
-OutputPanel.prototype._outputChanged = function(ev) {
- if (ev.output.hidden) {
- return;
- }
-
- this.remove();
-
- this.displayedOutput = ev.output;
-
- if (this.displayedOutput.completed) {
- this._update();
- } else {
- this.displayedOutput.promise.then(this._update, this._update)
- .catch(console.error);
- }
-};
-
-/**
- * Called when displayed Output says it's changed or from outputChanged, which
- * happens when there is a new displayed Output.
- */
-OutputPanel.prototype._update = function() {
- // destroy has been called, bail out
- if (this._div == null) {
- return;
- }
-
- // Empty this._div
- while (this._div.hasChildNodes()) {
- this._div.firstChild.remove();
- }
-
- if (this.displayedOutput.data != null) {
- let context = this._devtoolbar.requisition.conversionContext;
- this.displayedOutput.convert("dom", context).then(node => {
- if (node == null) {
- return;
- }
-
- while (this._div.hasChildNodes()) {
- this._div.firstChild.remove();
- }
-
- let links = node.querySelectorAll("*[href]");
- for (let i = 0; i < links.length; i++) {
- links[i].setAttribute("target", "_blank");
- }
-
- this._div.appendChild(node);
- this.show();
- });
- }
-};
-
-/**
- * Detach listeners from the currently displayed Output.
- */
-OutputPanel.prototype.remove = function() {
- if (isLinux) {
- this.canHide = true;
- }
-
- if (this._panel && this._panel.hidePopup) {
- this._panel.hidePopup();
- }
-
- if (this.displayedOutput) {
- delete this.displayedOutput;
- }
-};
-
-/**
- * Detach listeners from the currently displayed Output.
- */
-OutputPanel.prototype.destroy = function() {
- this.remove();
-
- this._panel.removeEventListener("popuphiding", this._onpopuphiding, true);
-
- this._panel.removeChild(this._frame);
- this._toolbar.parentElement.removeChild(this._panel);
-
- delete this._devtoolbar;
- delete this._input;
- delete this._toolbar;
- delete this._onpopuphiding;
- delete this._panel;
- delete this._frame;
- delete this._content;
- delete this._div;
- delete this.document;
-};
-
-/**
- * Called by GCLI to indicate that we should show or hide one either the
- * tooltip panel or the output panel.
- */
-OutputPanel.prototype._visibilityChanged = function(ev) {
- if (ev.outputVisible === true) {
- // this.show is called by _outputChanged
- } else {
- if (isLinux) {
- this.canHide = true;
- }
- this._panel.hidePopup();
- }
-};
-
-/**
- * Creating a TooltipPanel is asynchronous
- */
-function TooltipPanel() {
- throw new Error("Use TooltipPanel.create()");
-}
-
-/**
- * Panel to handle tooltips.
- *
- * There is a tooltip bug on Windows and OSX that prevents tooltips from being
- * positioned properly (bug 786975). There is a Gnome panel bug on Linux that
- * causes ugly focus issues (https://bugzilla.gnome.org/show_bug.cgi?id=621848).
- * We now use a tooltip on Linux and a panel on OSX & Windows.
- *
- * If a panel has no content and no height it is not shown when openPopup is
- * called on Windows and OSX (bug 692348) ... this prevents the panel from
- * appearing the first time it is shown. Setting the panel's height to 1px
- * before calling openPopup works around this issue as we resize it ourselves
- * anyway.
- *
- * @param devtoolbar The parent DeveloperToolbar object
- */
-TooltipPanel.create = function(devtoolbar) {
- let tooltipPanel = Object.create(TooltipPanel.prototype);
- return tooltipPanel._init(devtoolbar);
-};
-
-/**
- * @private See TooltipPanel.create
- */
-TooltipPanel.prototype._init = function(devtoolbar) {
- return new Promise((resolve, reject) => {
- this._devtoolbar = devtoolbar;
- this._input = devtoolbar._doc.querySelector(".gclitoolbar-input-node");
- this._toolbar = devtoolbar._doc.querySelector("#developer-toolbar");
- this._dimensions = { start: 0, end: 0 };
-
- /*
- <tooltip|panel id="gcli-tooltip"
- type="arrow"
- noautofocus="true"
- noautohide="true"
- class="gcli-panel">
- <html:iframe xmlns:html="http://www.w3.org/1999/xhtml"
- id="gcli-tooltip-frame"
- src="chrome://devtools/content/commandline/commandlinetooltip.xhtml"
- flex="1"
- sandbox="allow-same-origin"/>
- </tooltip|panel>
- */
-
- // TODO: Switch back from tooltip to panel when metacity focus issue is fixed:
- // https://bugzilla.mozilla.org/show_bug.cgi?id=780102
- this._panel = devtoolbar._doc.createElement(isLinux ? "tooltip" : "panel");
-
- this._panel.id = "gcli-tooltip";
- this._panel.classList.add("gcli-panel");
-
- if (isLinux) {
- this.canHide = false;
- this._onpopuphiding = this._onpopuphiding.bind(this);
- this._panel.addEventListener("popuphiding", this._onpopuphiding, true);
- } else {
- this._panel.setAttribute("noautofocus", "true");
- this._panel.setAttribute("noautohide", "true");
-
- // Bug 692348: On Windows and OSX if a panel has no content and no height
- // openPopup fails to display it. Setting the height to 1px alows the panel
- // to be displayed before has content or a real height i.e. the first time
- // it is displayed.
- this._panel.setAttribute("height", "1px");
- }
-
- this._toolbar.parentElement.insertBefore(this._panel, this._toolbar);
-
- this._frame = devtoolbar._doc.createElementNS(NS_XHTML, "iframe");
- this._frame.id = "gcli-tooltip-frame";
- this._frame.setAttribute("src", "chrome://devtools/content/commandline/commandlinetooltip.xhtml");
- this._frame.setAttribute("flex", "1");
- this._frame.setAttribute("sandbox", "allow-same-origin");
- this._panel.appendChild(this._frame);
-
- /**
- * Wire up the element from the iframe, and resolve the promise.
- */
- let onload = () => {
- this._frame.removeEventListener("load", onload, true);
-
- this.document = this._frame.contentDocument;
- this._copyTheme();
- this.hintElement = this.document.getElementById("gcli-tooltip-root");
- this._connector = this.document.getElementById("gcli-tooltip-connector");
-
- let styles = this._toolbar.ownerDocument.defaultView
- .getComputedStyle(this._toolbar);
- this.hintElement.setAttribute("dir", styles.direction);
-
- resolve(this);
- };
- this._frame.addEventListener("load", onload, true);
- });
-};
-
-/* Copy the current devtools theme attribute into the iframe,
- so it can be styled correctly. */
-TooltipPanel.prototype._copyTheme = function() {
- if (this.document) {
- let theme = this._devtoolbar._doc.getElementById("browser-bottombox")
- .getAttribute("devtoolstheme");
- this.document.documentElement.setAttribute("devtoolstheme", theme);
- }
-};
-
-/**
- * Prevent the popup from hiding if it is not permitted via this.canHide.
- */
-TooltipPanel.prototype._onpopuphiding = function(ev) {
- // TODO: When we switch back from tooltip to panel we can remove this hack:
- // https://bugzilla.mozilla.org/show_bug.cgi?id=780102
- if (isLinux && !this.canHide) {
- ev.preventDefault();
- }
-};
-
-/**
- * Display the TooltipPanel.
- */
-TooltipPanel.prototype.show = function(dimensions) {
- if (!dimensions) {
- dimensions = { start: 0, end: 0 };
- }
- this._dimensions = dimensions;
-
- // This is nasty, but displaying the panel causes it to re-flow, which can
- // change the size it should be, so we need to resize the iframe after the
- // panel has displayed
- this._panel.ownerDocument.defaultView.setTimeout(() => {
- this._resize();
- }, 0);
-
- if (isLinux) {
- this.canHide = false;
- }
-
- this._copyTheme();
- this._resize();
- this._panel.openPopup(this._input, "before_start", dimensions.start * 10, 0,
- false, false, null);
- this._input.focus();
-};
-
-/**
- * One option is to spend lots of time taking an average width of characters
- * in the current font, dynamically, and weighting for the frequency of use of
- * various characters, or even to render the given string off screen, and then
- * measure the width.
- * Or we could do this...
- */
-const AVE_CHAR_WIDTH = 4.5;
-
-/**
- * Display the TooltipPanel.
- */
-TooltipPanel.prototype._resize = function() {
- if (this._panel == null || this.document == null || !this._panel.state == "closed") {
- return;
- }
-
- let offset = 10 + Math.floor(this._dimensions.start * AVE_CHAR_WIDTH);
- this._panel.style.marginLeft = offset + "px";
-
- /*
- // Bug 744906: UX review - Not sure if we want this code to fatten connector
- // with param width
- let width = Math.floor(this._dimensions.end * AVE_CHAR_WIDTH);
- width = Math.min(width, 100);
- width = Math.max(width, 10);
- this._connector.style.width = width + "px";
- */
-
- this._frame.height = this.document.body.scrollHeight;
-};
-
-/**
- * Hide the TooltipPanel.
- */
-TooltipPanel.prototype.remove = function() {
- if (isLinux) {
- this.canHide = true;
- }
- if (this._panel && this._panel.hidePopup) {
- this._panel.hidePopup();
- }
-};
-
-/**
- * Hide the TooltipPanel.
- */
-TooltipPanel.prototype.destroy = function() {
- this.remove();
-
- this._panel.removeEventListener("popuphiding", this._onpopuphiding, true);
-
- this._panel.removeChild(this._frame);
- this._toolbar.parentElement.removeChild(this._panel);
-
- delete this._connector;
- delete this._dimensions;
- delete this._input;
- delete this._onpopuphiding;
- delete this._panel;
- delete this._frame;
- delete this._toolbar;
- delete this._content;
- delete this.document;
- delete this.hintElement;
-};
-
-/**
- * Called by GCLI to indicate that we should show or hide one either the
- * tooltip panel or the output panel.
- */
-TooltipPanel.prototype._visibilityChanged = function(ev) {
- if (ev.tooltipVisible === true) {
- this.show(ev.dimensions);
- } else {
- if (isLinux) {
- this.canHide = true;
- }
- this._panel.hidePopup();
- }
-};
--- a/devtools/client/shared/test/browser.ini
+++ b/devtools/client/shared/test/browser.ini
@@ -19,18 +19,16 @@ support-files =
doc_layoutHelpers-getBoxQuads.html
doc_layoutHelpers.html
doc_options-view.xul
doc_spectrum.html
doc_tableWidget_basic.html
doc_tableWidget_keyboard_interaction.xul
doc_tableWidget_mouse_interaction.xul
doc_templater_basic.html
- doc_toolbar_basic.html
- doc_toolbar_webconsole_errors_count.html
dummy.html
frame-script-utils.js
head.js
helper_color_data.js
helper_html_tooltip.js
helper_inplace_editor.js
leakhunt.js
shared-head.js
@@ -188,18 +186,13 @@ skip-if = !e10s || os == "win" # RDM onl
[browser_telemetry_toolboxtabs_netmonitor.js]
[browser_telemetry_toolboxtabs_options.js]
[browser_telemetry_toolboxtabs_shadereditor.js]
[browser_telemetry_toolboxtabs_storage.js]
[browser_telemetry_toolboxtabs_styleeditor.js]
[browser_telemetry_toolboxtabs_webaudioeditor.js]
[browser_telemetry_toolboxtabs_webconsole.js]
[browser_templater_basic.js]
-[browser_toolbar_basic.js]
-skip-if = (e10s && debug) # Bug 1253035
-[browser_toolbar_tooltip.js]
-[browser_toolbar_webconsole_errors_count.js]
-skip-if = e10s # The developertoolbar error count isn't correct with e10s
[browser_treeWidget_basic.js]
[browser_treeWidget_keyboard_interaction.js]
[browser_treeWidget_mouse_interaction.js]
[browser_devices.js]
[browser_theme_switching.js]
deleted file mode 100644
--- a/devtools/client/shared/test/browser_toolbar_basic.js
+++ /dev/null
@@ -1,68 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-// Tests that the developer toolbar works properly
-
-// There are shutdown issues for which multiple rejections are left uncaught.
-// See bug 1018184 for resolving these issues.
-const { PromiseTestUtils } = scopedCuImport("resource://testing-common/PromiseTestUtils.jsm");
-PromiseTestUtils.whitelistRejectionsGlobally(/Connection closed/);
-
-const {gDevToolsBrowser} = require("devtools/client/framework/devtools-browser");
-
-const TEST_URI = TEST_URI_ROOT + "doc_toolbar_basic.html";
-
-add_task(async function() {
- info("Starting browser_toolbar_basic.js");
- await addTab(TEST_URI);
-
- let toolbar = gDevToolsBrowser.getDeveloperToolbar(window);
- ok(!toolbar.visible, "DeveloperToolbar is not visible in to start");
-
- let shown = oneTimeObserve(toolbar.NOTIFICATIONS.SHOW);
- document.getElementById("menu_devToolbar").doCommand();
- await shown;
- ok(toolbar.visible, "DeveloperToolbar is visible in checkOpen");
-
- let close = document.getElementById("developer-toolbar-closebutton");
- ok(close, "Close button exists");
-
- let toggleToolbox =
- document.getElementById("menu_devToolbox");
- ok(!isChecked(toggleToolbox), "toggle toolbox button is not checked");
-
- let target = TargetFactory.forTab(gBrowser.selectedTab);
- await gDevTools.showToolbox(target, "inspector");
- ok(isChecked(toggleToolbox), "toggle toolbox button is checked");
-
- await addTab("about:blank");
- info("Opened a new tab");
-
- ok(!isChecked(toggleToolbox), "toggle toolbox button is not checked");
-
- gBrowser.removeCurrentTab();
-
- let hidden = oneTimeObserve(toolbar.NOTIFICATIONS.HIDE);
- document.getElementById("menu_devToolbar").doCommand();
- await hidden;
- ok(!toolbar.visible, "DeveloperToolbar is not visible in hidden");
-
- shown = oneTimeObserve(toolbar.NOTIFICATIONS.SHOW);
- document.getElementById("menu_devToolbar").doCommand();
- await shown;
- ok(toolbar.visible, "DeveloperToolbar is visible in after open");
-
- ok(isChecked(toggleToolbox), "toggle toolbox button is checked");
-
- hidden = oneTimeObserve(toolbar.NOTIFICATIONS.HIDE);
- document.getElementById("developer-toolbar-closebutton").doCommand();
- await hidden;
-
- ok(!toolbar.visible, "DeveloperToolbar is not visible after re-close");
-});
-
-function isChecked(b) {
- return b.getAttribute("checked") == "true";
-}
deleted file mode 100644
--- a/devtools/client/shared/test/browser_toolbar_tooltip.js
+++ /dev/null
@@ -1,107 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-// Tests that the developer toolbar works properly
-
-const {gDevToolsBrowser} = require("devtools/client/framework/devtools-browser");
-
-const TEST_URI = "data:text/html;charset=utf-8,<p>Tooltip Tests</p>";
-const PREF_DEVTOOLS_THEME = "devtools.theme";
-
-registerCleanupFunction(() => {
- // Set preferences back to their original values
- Services.prefs.clearUserPref(PREF_DEVTOOLS_THEME);
-});
-
-let toolbar = gDevToolsBrowser.getDeveloperToolbar(window);
-
-add_task(async function showToolbar() {
- await addTab(TEST_URI);
-
- info("Starting browser_toolbar_tooltip.js");
-
- ok(!toolbar.visible, "DeveloperToolbar is not visible in runTest");
-
- let showPromise = observeOnce(toolbar.NOTIFICATIONS.SHOW);
- document.getElementById("menu_devToolbar").doCommand();
- await showPromise;
-});
-
-add_task(async function testDimensions() {
- let tooltipPanel = toolbar.tooltipPanel;
-
- toolbar.focusManager.helpRequest();
- await toolbar.inputter.setInput("help help");
-
- toolbar.inputter.setCursor({ start: "help help".length });
- is(tooltipPanel._dimensions.start, "help ".length,
- "search param start, when cursor at end");
- ok(getLeftMargin() > 30, "tooltip offset, when cursor at end");
-
- toolbar.inputter.setCursor({ start: "help".length });
- is(tooltipPanel._dimensions.start, 0,
- "search param start, when cursor at end of command");
- ok(getLeftMargin() > 9, "tooltip offset, when cursor at end of command");
-
- toolbar.inputter.setCursor({ start: "help help".length - 1 });
- is(tooltipPanel._dimensions.start, "help ".length,
- "search param start, when cursor at penultimate position");
- ok(getLeftMargin() > 30, "tooltip offset, when cursor at penultimate position");
-
- toolbar.inputter.setCursor({ start: 0 });
- is(tooltipPanel._dimensions.start, 0,
- "search param start, when cursor at start");
- ok(getLeftMargin() > 9, "tooltip offset, when cursor at start");
-});
-
-add_task(async function testThemes() {
- let tooltipPanel = toolbar.tooltipPanel;
- ok(tooltipPanel.document, "Tooltip panel is initialized");
-
- Services.prefs.setCharPref(PREF_DEVTOOLS_THEME, "dark");
-
- await toolbar.inputter.setInput("");
- await toolbar.inputter.setInput("help help");
- is(tooltipPanel.document.documentElement.getAttribute("devtoolstheme"),
- "dark", "Tooltip panel has correct theme");
-
- Services.prefs.setCharPref(PREF_DEVTOOLS_THEME, "light");
-
- await toolbar.inputter.setInput("");
- await toolbar.inputter.setInput("help help");
- is(tooltipPanel.document.documentElement.getAttribute("devtoolstheme"),
- "light", "Tooltip panel has correct theme");
-});
-
-add_task(async function hideToolbar() {
- info("Ending browser_toolbar_tooltip.js");
- await toolbar.inputter.setInput("");
-
- ok(toolbar.visible, "DeveloperToolbar is visible in hideToolbar");
-
- info("Hide toolbar");
- let hidePromise = observeOnce(toolbar.NOTIFICATIONS.HIDE);
- document.getElementById("menu_devToolbar").doCommand();
- await hidePromise;
-
- ok(!toolbar.visible, "DeveloperToolbar is not visible in hideToolbar");
-
- info("Done test");
-});
-
-function getLeftMargin() {
- let style = toolbar.tooltipPanel._panel.style.marginLeft;
- return parseInt(style.slice(0, -2), 10);
-}
-
-function observeOnce(topic, ownsWeak = false) {
- return new Promise(function(resolve, reject) {
- let resolver = function(subject) {
- Services.obs.removeObserver(resolver, topic);
- resolve(subject);
- };
- Services.obs.addObserver(resolver, topic, ownsWeak);
- });
-}
deleted file mode 100644
--- a/devtools/client/shared/test/browser_toolbar_webconsole_errors_count.js
+++ /dev/null
@@ -1,250 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-// Tests that the developer toolbar errors count works properly.
-
-const {gDevToolsBrowser} = require("devtools/client/framework/devtools-browser");
-
-let toolbar = gDevToolsBrowser.getDeveloperToolbar(window);
-
-function test() {
- const TEST_URI = TEST_URI_ROOT + "doc_toolbar_webconsole_errors_count.html";
-
- let tab1, tab2, webconsole;
-
- Services.prefs.setBoolPref("javascript.options.strict", true);
-
- registerCleanupFunction(() => {
- Services.prefs.clearUserPref("javascript.options.strict");
- });
-
- ignoreAllUncaughtExceptions();
- addTab(TEST_URI).then(openToolbar);
-
- function openToolbar(tab) {
- tab1 = tab;
- ignoreAllUncaughtExceptions(false);
-
- expectUncaughtException();
-
- if (!toolbar.visible) {
- toolbar.show(true).then(onOpenToolbar);
- } else {
- onOpenToolbar();
- }
- }
-
- function onOpenToolbar() {
- ok(toolbar.visible, "DeveloperToolbar is visible");
- webconsole = document.getElementById("developer-toolbar-toolbox-button");
-
- waitForButtonUpdate({
- name: "web console button shows page errors",
- errors: 3,
- warnings: 0,
- callback: addErrors,
- });
- }
-
- function addErrors() {
- expectUncaughtException();
-
- waitForFocus(function() {
- let button = content.document.querySelector("button");
- executeSoon(function() {
- EventUtils.synthesizeMouse(button, 3, 2, {}, content);
- });
- }, content);
-
- waitForButtonUpdate({
- name: "button shows one more error after click in page",
- errors: 4,
- warnings: 1,
- callback: () => {
- ignoreAllUncaughtExceptions();
- addTab(TEST_URI).then(onOpenSecondTab);
- },
- });
- }
-
- function onOpenSecondTab(tab) {
- tab2 = tab;
-
- ignoreAllUncaughtExceptions(false);
- expectUncaughtException();
-
- waitForButtonUpdate({
- name: "button shows correct number of errors after new tab is open",
- errors: 3,
- warnings: 0,
- callback: switchToTab1,
- });
- }
-
- function switchToTab1() {
- gBrowser.selectedTab = tab1;
- waitForButtonUpdate({
- name: "button shows the page errors from tab 1",
- errors: 4,
- warnings: 1,
- callback: openWebConsole.bind(null, tab1, onWebConsoleOpen),
- });
- }
-
- function onWebConsoleOpen(hud) {
- dump("lolz!!\n");
- waitForValue({
- name: "web console shows the page errors",
- validator: function() {
- let selector = ".message[category=exception][severity=error]";
- return hud.outputNode.querySelectorAll(selector).length;
- },
- value: 4,
- success: checkConsoleOutput.bind(null, hud),
- failure: () => {
- finish();
- },
- });
- }
-
- function checkConsoleOutput(hud) {
- let msgs = ["foobarBug762996a", "foobarBug762996b", "foobarBug762996load",
- "foobarBug762996click", "foobarBug762996consoleLog",
- "foobarBug762996css", "fooBug788445"];
- msgs.forEach(function(msg) {
- isnot(hud.outputNode.textContent.indexOf(msg), -1,
- msg + " found in the Web Console output");
- });
-
- hud.jsterm.clearOutput();
-
- is(hud.outputNode.textContent.indexOf("foobarBug762996color"), -1,
- "clearOutput() worked");
-
- expectUncaughtException();
- let button = content.document.querySelector("button");
- EventUtils.synthesizeMouse(button, 2, 2, {}, content);
-
- waitForButtonUpdate({
- name: "button shows one more error after another click in page",
- errors: 5,
- // warnings are not repeated by the js engine
- warnings: 1,
- callback: () => waitForValue(waitForNewError),
- });
-
- let waitForNewError = {
- name: "the Web Console displays the new error",
- validator: function() {
- return hud.outputNode.textContent.indexOf("foobarBug762996click") > -1;
- },
- success: doClearConsoleButton.bind(null, hud),
- failure: finish,
- };
- }
-
- function doClearConsoleButton(hud) {
- let clearButton = hud.ui.rootElement
- .querySelector(".webconsole-clear-console-button");
- EventUtils.synthesizeMouse(clearButton, 2, 2, {}, hud.iframeWindow);
-
- is(hud.outputNode.textContent.indexOf("foobarBug762996click"), -1,
- "clear console button worked");
- is(getErrorsCount(), 0, "page errors counter has been reset");
- let tooltip = getTooltipValues();
- is(tooltip[1], 0, "page warnings counter has been reset");
-
- doPageReload(hud);
- }
-
- function doPageReload(hud) {
- tab1.linkedBrowser.addEventListener("load", onReload, true);
-
- ignoreAllUncaughtExceptions();
- content.location.reload();
-
- function onReload() {
- tab1.linkedBrowser.removeEventListener("load", onReload, true);
- ignoreAllUncaughtExceptions(false);
- expectUncaughtException();
-
- waitForButtonUpdate({
- name: "the Web Console button count has been reset after page reload",
- errors: 3,
- warnings: 0,
- callback: waitForValue.bind(null, waitForConsoleOutputAfterReload),
- });
- }
-
- let waitForConsoleOutputAfterReload = {
- name: "the Web Console displays the correct number of errors after reload",
- validator: function() {
- let selector = ".message[category=exception][severity=error]";
- return hud.outputNode.querySelectorAll(selector).length;
- },
- value: 3,
- success: function() {
- isnot(hud.outputNode.textContent.indexOf("foobarBug762996load"), -1,
- "foobarBug762996load found in console output after page reload");
- testEnd();
- },
- failure: testEnd,
- };
- }
-
- function testEnd() {
- document.getElementById("developer-toolbar-closebutton").doCommand();
- let target1 = TargetFactory.forTab(tab1);
- gDevTools.closeToolbox(target1).then(() => {
- gBrowser.removeTab(tab1);
- gBrowser.removeTab(tab2);
- finish();
- });
- }
-
- // Utility functions
-
- function getErrorsCount() {
- let count = webconsole.getAttribute("error-count");
- return count ? count : "0";
- }
-
- function getTooltipValues() {
- let matches = webconsole.getAttribute("tooltiptext")
- .match(/(\d+) errors?, (\d+) warnings?/);
- return matches ? [matches[1], matches[2]] : [0, 0];
- }
-
- function waitForButtonUpdate(options) {
- function check() {
- let errors = getErrorsCount();
- let tooltip = getTooltipValues();
- let result = errors == options.errors && tooltip[1] == options.warnings;
- if (result) {
- ok(true, options.name);
- is(errors, tooltip[0], "button error-count is the same as in the tooltip");
-
- // Get out of the toolbar event execution loop.
- executeSoon(options.callback);
- }
- return result;
- }
-
- if (!check()) {
- info("wait for: " + options.name);
- toolbar.on("errors-counter-updated", function onUpdate() {
- if (check()) {
- toolbar.off("errors-counter-updated", onUpdate);
- }
- });
- }
- }
-
- function openWebConsole(tab, callback) {
- let target = TargetFactory.forTab(tab);
- gDevTools.showToolbox(target, "webconsole").then((toolbox) =>
- callback(toolbox.getCurrentPanel().hud));
- }
-}
deleted file mode 100644
--- a/devtools/client/shared/test/doc_toolbar_basic.html
+++ /dev/null
@@ -1,40 +0,0 @@
-<!doctype html>
-<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
-
-<html>
-<head>
- <meta charset="UTF-8">
- <title>Developer Toolbar Tests</title>
- <style type="text/css">
- #single { color: red; }
- </style>
- <script type="text/javascript">
- /* eslint-disable */
- var a = 1;
- </script>
-</head>
-<body>
-
-<p id=single>
-1
-</p>
-
-<p class=twin>
-2a
-</p>
-
-<p class=twin>
-2b
-</p>
-
-<style>
-.twin { color: blue; }
-</style>
-<script>
-/* eslint-disable */
-var b = 2;
-</script>
-
-</body>
-</html>
deleted file mode 100644
--- a/devtools/client/shared/test/doc_toolbar_webconsole_errors_count.html
+++ /dev/null
@@ -1,34 +0,0 @@
-<!DOCTYPE HTML>
-<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
-<html>
-<head>
- <meta charset="UTF-8">
- <title>Developer Toolbar Tests - errors count in the Web Console button</title>
- <script type="text/javascript">
- "use strict";
- console.log("foobarBug762996consoleLog");
- window.onload = function() {
- window.foobarBug762996load();
- };
- window.foobarBug762996a();
- </script>
- <script type="text/javascript">
- "use strict";
- window.foobarBug762996b();
- </script>
-</head>
-<body>
- <p>Hello world! Test for errors count in the Web Console button (developer
- toolbar).</p>
- <p style="color: foobarBug762996css"><button>click me</button></p>
- <script type="text/javascript">
- "use strict";
- let testObj = {};
- document.querySelector("button").onclick = function() {
- testObj.fooBug788445 + "warning";
- window.foobarBug762996click();
- };
- </script>
-</body>
-</html>
--- a/devtools/client/webconsole/hudservice.js
+++ b/devtools/client/webconsole/hudservice.js
@@ -3,17 +3,16 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
var Services = require("Services");
loader.lazyRequireGetter(this, "Utils", "devtools/client/webconsole/utils", true);
loader.lazyRequireGetter(this, "extend", "devtools/shared/extend", true);
loader.lazyRequireGetter(this, "TargetFactory", "devtools/client/framework/target", true);
-loader.lazyRequireGetter(this, "gDevToolsBrowser", "devtools/client/framework/devtools-browser", true);
loader.lazyRequireGetter(this, "Tools", "devtools/client/definitions", true);
loader.lazyRequireGetter(this, "Telemetry", "devtools/client/shared/telemetry");
loader.lazyRequireGetter(this, "NewWebConsoleFrame", "devtools/client/webconsole/new-webconsole", true);
loader.lazyRequireGetter(this, "gDevTools", "devtools/client/framework/devtools", true);
loader.lazyRequireGetter(this, "DebuggerServer", "devtools/server/main", true);
loader.lazyRequireGetter(this, "DebuggerClient", "devtools/shared/client/debugger-client", true);
loader.lazyRequireGetter(this, "showDoorhanger", "devtools/client/shared/doorhanger", true);
loader.lazyRequireGetter(this, "viewSource", "devtools/client/shared/view-source");
@@ -347,27 +346,16 @@ WebConsole.prototype = {
* @see webconsole.js::JSTerm
* @type object
*/
get jsterm() {
return this.ui ? this.ui.jsterm : null;
},
/**
- * The clear output button handler.
- * @private
- */
- _onClearButton() {
- if (this.target.isLocalTab) {
- gDevToolsBrowser.getDeveloperToolbar(this.browserWindow)
- .resetErrorsCount(this.target.tab);
- }
- },
-
- /**
* Alias for the WebConsoleFrame.setFilterState() method.
* @see webconsole.js::WebConsoleFrame.setFilterState()
*/
setFilterState() {
this.ui && this.ui.setFilterState.apply(this.ui, arguments);
},
/**