author | Alexandre Poirot <poirot.alex@gmail.com> |
Fri, 01 Apr 2016 05:49:00 -0700 | |
changeset 329202 | 9b9b8514c6b0479d470b0c30f84b6e9552591da5 |
parent 329201 | 0b016f319532937405bf971cdb1e426e81bc35f5 |
child 329203 | 97e1c3fdf6f22c4a643b378eec2b775d9d95bb3d |
push id | 6048 |
push user | kmoir@mozilla.com |
push date | Mon, 06 Jun 2016 19:02:08 +0000 |
treeherder | mozilla-beta@46d72a56c57d [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | gijs, jryans |
bugs | 1248603 |
milestone | 48.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/browser/base/content/browser-menubar.inc +++ b/browser/base/content/browser-menubar.inc @@ -515,59 +515,19 @@ accesskey="&syncReAuthItem.accesskey;" observes="sync-reauth-state" oncommand="gSyncUI.openSignInAgainPage('menubar');"/> <menuseparator id="devToolsSeparator"/> <menu id="webDeveloperMenu" label="&webDeveloperMenu.label;" accesskey="&webDeveloperMenu.accesskey;"> <menupopup id="menuWebDeveloperPopup"> - <menuitem id="menu_devToolbox" - observes="devtoolsMenuBroadcaster_DevToolbox" - accesskey="&devToolboxMenuItem.accesskey;"/> - <menuseparator id="menu_devtools_separator"/> - <menuitem id="menu_devToolbar" - observes="devtoolsMenuBroadcaster_DevToolbar" - accesskey="&devToolbarMenu.accesskey;"/> - <menuitem id="menu_webide" - observes="devtoolsMenuBroadcaster_webide" - accesskey="&webide.accesskey;"/> - <menuitem id="menu_browserToolbox" - observes="devtoolsMenuBroadcaster_BrowserToolbox" - accesskey="&browserToolboxMenu.accesskey;"/> - <menuitem id="menu_browserContentToolbox" - observes="devtoolsMenuBroadcaster_BrowserContentToolbox" - accesskey="&browserContentToolboxMenu.accesskey;" /> - <menuitem id="menu_browserConsole" - observes="devtoolsMenuBroadcaster_BrowserConsole" - accesskey="&browserConsoleCmd.accesskey;"/> - <menuitem id="menu_responsiveUI" - observes="devtoolsMenuBroadcaster_ResponsiveUI" - accesskey="&responsiveDesignMode.accesskey;"/> - <menuitem id="menu_eyedropper" - observes="devtoolsMenuBroadcaster_Eyedropper" - accesskey="&eyedropper.accesskey;"/> - <menuitem id="menu_scratchpad" - observes="devtoolsMenuBroadcaster_Scratchpad" - accesskey="&scratchpad.accesskey;"/> <menuitem id="menu_pageSource" observes="devtoolsMenuBroadcaster_PageSource" accesskey="&pageSourceCmd.accesskey;"/> - <menuitem id="javascriptConsole" - observes="devtoolsMenuBroadcaster_ErrorConsole" - accesskey="&errorConsoleCmd.accesskey;"/> - <menuitem id="menu_devtools_serviceworkers" - observes="devtoolsMenuBroadcaster_ServiceWorkers" - accesskey="&devtoolsServiceWorkers.accesskey;"/> - <menuitem id="menu_devtools_connect" - observes="devtoolsMenuBroadcaster_connect"/> - <menuseparator id="devToolsEndSeparator"/> - <menuitem id="getMoreDevtools" - observes="devtoolsMenuBroadcaster_GetMoreTools" - accesskey="&getMoreDevtoolsCmd.accesskey;"/> </menupopup> </menu> <menuitem id="menu_pageInfo" accesskey="&pageInfoCmd.accesskey;" label="&pageInfoCmd.label;" #ifndef XP_WIN key="key_viewInfo" #endif
--- a/browser/base/content/browser-sets.inc +++ b/browser/base/content/browser-sets.inc @@ -90,30 +90,17 @@ <command id="cmd_gestureRotateRight" oncommand="gGestureSupport.rotate(event.sourceEvent)"/> <command id="cmd_gestureRotateEnd" oncommand="gGestureSupport.rotateEnd()"/> <command id="Browser:OpenLocation" oncommand="openLocation();"/> <command id="Browser:RestoreLastSession" oncommand="restoreLastSession();" disabled="true"/> <command id="Browser:NewUserContextTab" oncommand="openNewUserContextTab(event.sourceEvent);" reserved="true"/> <command id="Tools:Search" oncommand="BrowserSearch.webSearch();"/> <command id="Tools:Downloads" oncommand="BrowserDownloadsUI();"/> - <command id="Tools:DevToolbox" oncommand="gDevToolsBrowser.toggleToolboxCommand(gBrowser);"/> - <command id="Tools:DevToolbar" oncommand="DeveloperToolbar.toggle();" disabled="true" hidden="true"/> - <command id="Tools:DevToolbarFocus" oncommand="DeveloperToolbar.focusToggle();" disabled="true"/> - <command id="Tools:WebIDE" oncommand="gDevToolsBrowser.openWebIDE();" disabled="true" hidden="true"/> - <command id="Tools:BrowserToolbox" oncommand="BrowserToolboxProcess.init();" disabled="true" hidden="true"/> - <command id="Tools:BrowserContentToolbox" oncommand="gDevToolsBrowser.openContentProcessToolbox();" disabled="true" hidden="true"/> - <command id="Tools:BrowserConsole" oncommand="HUDService.openBrowserConsoleOrFocus();"/> - <command id="Tools:Scratchpad" oncommand="Scratchpad.openScratchpad();"/> - <command id="Tools:ResponsiveUI" oncommand="ResponsiveUI.toggle();"/> - <command id="Tools:Eyedropper" oncommand="openEyedropper();"/> <command id="Tools:Addons" oncommand="BrowserOpenAddonsMgr();"/> - <command id="Tools:ErrorConsole" oncommand="toJavaScriptConsole()" disabled="true" hidden="true"/> - <command id="Tools:ServiceWorkers" oncommand="gDevToolsBrowser.openAboutDebugging(gBrowser, 'workers')"/> - <command id="Tools:DevToolsConnect" oncommand="gDevToolsBrowser.openConnectScreen(gBrowser)" disabled="true" hidden="true"/> <command id="Tools:Sanitize" oncommand="Cc['@mozilla.org/browser/browserglue;1'].getService(Ci.nsIBrowserGlue).sanitize(window);"/> <command id="Tools:PrivateBrowsing" oncommand="OpenBrowserWindow({private: true});" reserved="true"/> #ifdef E10S_TESTING_ONLY <command id="Tools:NonRemoteWindow" oncommand="OpenBrowserWindow({remote: false});"/> #endif @@ -191,73 +178,22 @@ <broadcaster id="sync-reauth-state" hidden="true"/> <broadcaster id="viewTabsSidebar" autoCheck="false" sidebartitle="&syncedTabs.sidebar.label;" type="checkbox" group="sidebar" sidebarurl="chrome://browser/content/syncedtabs/sidebar.xhtml" oncommand="SidebarUI.toggle('viewTabsSidebar');"/> <broadcaster id="workOfflineMenuitemState"/> <broadcaster id="socialSidebarBroadcaster" hidden="true"/> - <!-- DevTools broadcasters --> - <broadcaster id="devtoolsMenuBroadcaster_DevToolbox" - label="&devToolboxMenuItem.label;" - type="checkbox" autocheck="false" - command="Tools:DevToolbox" - key="key_devToolboxMenuItem"/> - <broadcaster id="devtoolsMenuBroadcaster_DevToolbar" - label="&devToolbarMenu.label;" - type="checkbox" autocheck="false" - command="Tools:DevToolbar" - key="key_devToolbar"/> - <broadcaster id="devtoolsMenuBroadcaster_webide" - label="&webide.label;" - command="Tools:WebIDE" - key="key_webide"/> - <broadcaster id="devtoolsMenuBroadcaster_BrowserToolbox" - label="&browserToolboxMenu.label;" - key="key_browserToolbox" - command="Tools:BrowserToolbox"/> - <broadcaster id="devtoolsMenuBroadcaster_BrowserContentToolbox" - label="&browserContentToolboxMenu.label;" - command="Tools:BrowserContentToolbox"/> - <broadcaster id="devtoolsMenuBroadcaster_BrowserConsole" - label="&browserConsoleCmd.label;" - key="key_browserConsole" - command="Tools:BrowserConsole"/> - <broadcaster id="devtoolsMenuBroadcaster_Scratchpad" - label="&scratchpad.label;" - command="Tools:Scratchpad" - key="key_scratchpad"/> - <broadcaster id="devtoolsMenuBroadcaster_ResponsiveUI" - label="&responsiveDesignMode.label;" - type="checkbox" autocheck="false" - command="Tools:ResponsiveUI" - key="key_responsiveUI"/> - <broadcaster id="devtoolsMenuBroadcaster_Eyedropper" - label="&eyedropper.label;" - type="checkbox" autocheck="false" - command="Tools:Eyedropper"/> <broadcaster id="devtoolsMenuBroadcaster_PageSource" label="&pageSourceCmd.label;" key="key_viewSource" command="View:PageSource"> <observes element="canViewSource" attribute="disabled"/> </broadcaster> - <broadcaster id="devtoolsMenuBroadcaster_ErrorConsole" - label="&errorConsoleCmd.label;" - command="Tools:ErrorConsole"/> - <broadcaster id="devtoolsMenuBroadcaster_GetMoreTools" - label="&getMoreDevtoolsCmd.label;" - oncommand="openUILinkIn('https://addons.mozilla.org/firefox/collections/mozilla/webdeveloper/', 'tab');"/> - <broadcaster id="devtoolsMenuBroadcaster_ServiceWorkers" - label="&devtoolsServiceWorkers.label;" - command="Tools:ServiceWorkers"/> - <broadcaster id="devtoolsMenuBroadcaster_connect" - label="&devtoolsConnect.label;" - command="Tools:DevToolsConnect"/> </broadcasterset> <keyset id="mainKeyset"> <key id="key_newNavigator" key="&newNavigatorCmd.key;" command="cmd_newNavigator" modifiers="accel"/> <key id="key_newNavigatorTab" key="&tabCmd.commandkey;" modifiers="accel" command="cmd_newNavigatorTab"/> @@ -294,41 +230,16 @@ #endif #ifdef XP_GNOME <key id="key_search2" key="&searchFocusUnix.commandkey;" command="Tools:Search" modifiers="accel"/> <key id="key_openDownloads" key="&downloadsUnix.commandkey;" command="Tools:Downloads" modifiers="accel,shift"/> #else <key id="key_openDownloads" key="&downloads.commandkey;" command="Tools:Downloads" modifiers="accel"/> #endif <key id="key_openAddons" key="&addons.commandkey;" command="Tools:Addons" modifiers="accel,shift"/> - <key id="key_devToolboxMenuItemF12" keycode="&devToolsCmd.keycode;" keytext="&devToolsCmd.keytext;" command="Tools:DevToolbox"/> - <key id="key_browserConsole" key="&browserConsoleCmd.commandkey;" command="Tools:BrowserConsole" modifiers="accel,shift"/> - <key id="key_browserToolbox" key="&browserToolboxCmd.commandkey;" command="Tools:BrowserToolbox" modifiers="accel,alt,shift"/> - <key id="key_devToolbar" keycode="&devToolbar.keycode;" modifiers="shift" - keytext="&devToolbar.keytext;" command="Tools:DevToolbarFocus"/> - <key id="key_responsiveUI" key="&responsiveDesignMode.commandkey;" command="Tools:ResponsiveUI" -#ifdef XP_MACOSX - modifiers="accel,alt" -#else - modifiers="accel,shift" -#endif - /> - <key id="key_webide" keycode="&webide.keycode;" command="Tools:WebIDE" - modifiers="shift" keytext="&webide.keytext;"/> - <key id="key_devToolboxMenuItem" keytext="&devToolboxMenuItem.keytext;" - command="Tools:DevToolbox" key="&devToolboxMenuItem.keytext;" -#ifdef XP_MACOSX - modifiers="accel,alt" -#else - modifiers="accel,shift" -#endif - /> - - <key id="key_scratchpad" keycode="&scratchpad.keycode;" modifiers="shift" - keytext="&scratchpad.keytext;" command="Tools:Scratchpad"/> <key id="openFileKb" key="&openFileCmd.commandkey;" command="Browser:OpenFile" modifiers="accel"/> <key id="key_savePage" key="&savePageCmd.commandkey;" command="Browser:SavePage" modifiers="accel"/> <key id="printKb" key="&printCmd.commandkey;" command="cmd_print" modifiers="accel"/> <key id="key_close" key="&closeCmd.key;" command="cmd_close" modifiers="accel"/> <key id="key_closeWindow" key="&closeCmd.key;" command="cmd_closeWindow" modifiers="accel,shift"/> <key id="key_toggleMute" key="&toggleMuteCmd.key;" command="cmd_toggleMute" modifiers="control"/> <key id="key_undo" key="&undoCmd.key;"
--- a/browser/locales/en-US/chrome/browser/browser.dtd +++ b/browser/locales/en-US/chrome/browser/browser.dtd @@ -249,90 +249,25 @@ These should match what Safari and other <!ENTITY downloadsUnix.commandkey "y"> <!ENTITY addons.label "Add-ons"> <!ENTITY addons.accesskey "A"> <!ENTITY addons.commandkey "A"> <!ENTITY webDeveloperMenu.label "Web Developer"> <!ENTITY webDeveloperMenu.accesskey "W"> -<!ENTITY devToolsCmd.keycode "VK_F12"> -<!ENTITY devToolsCmd.keytext "F12"> - -<!ENTITY devtoolsServiceWorkers.label "Service Workers"> -<!ENTITY devtoolsServiceWorkers.accesskey "k"> - -<!ENTITY devtoolsConnect.label "Connect…"> -<!ENTITY devtoolsConnect.accesskey "e"> - -<!ENTITY errorConsoleCmd.label "Error Console"> -<!ENTITY errorConsoleCmd.accesskey "C"> - -<!ENTITY remoteWebConsoleCmd.label "Remote Web Console"> - -<!ENTITY browserConsoleCmd.label "Browser Console"> -<!ENTITY browserConsoleCmd.commandkey "j"> -<!ENTITY browserConsoleCmd.accesskey "B"> - <!ENTITY inspectContextMenu.label "Inspect Element"> <!ENTITY inspectContextMenu.accesskey "Q"> -<!ENTITY responsiveDesignMode.label "Responsive Design Mode"> -<!ENTITY responsiveDesignMode.accesskey "R"> -<!ENTITY responsiveDesignMode.commandkey "M"> - -<!ENTITY eyedropper.label "Eyedropper"> -<!ENTITY eyedropper.accesskey "Y"> - -<!-- LOCALIZATION NOTE (scratchpad.label): This menu item label appears - - in the Tools menu. See bug 653093. - - The Scratchpad is intended to provide a simple text editor for creating - - and evaluating bits of JavaScript code for the purposes of function - - prototyping, experimentation and convenient scripting. - - - - It's quite possible that you won't have a good analogue for the word - - "Scratchpad" in your locale. You should feel free to find a close - - approximation to it or choose a word (or words) that means - - "simple discardable text editor". --> -<!ENTITY scratchpad.label "Scratchpad"> -<!ENTITY scratchpad.accesskey "s"> -<!ENTITY scratchpad.keycode "VK_F4"> -<!ENTITY scratchpad.keytext "F4"> - -<!-- LOCALIZATION NOTE (browserToolboxMenu.label): This is the label for the - - application menu item that opens the browser toolbox UI in the Tools menu. --> -<!ENTITY browserToolboxMenu.label "Browser Toolbox"> -<!ENTITY browserToolboxMenu.accesskey "e"> -<!ENTITY browserToolboxCmd.commandkey "i"> - -<!-- 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. --> -<!ENTITY browserContentToolboxMenu.label "Browser Content Toolbox"> -<!ENTITY browserContentToolboxMenu.accesskey "x"> - <!ENTITY devToolbarCloseButton.tooltiptext "Close Developer Toolbar"> -<!ENTITY devToolbarMenu.label "Developer Toolbar"> -<!ENTITY devToolbarMenu.accesskey "v"> -<!ENTITY webide.label "WebIDE"> -<!ENTITY webide.accesskey "W"> -<!ENTITY webide.keycode "VK_F8"> -<!ENTITY webide.keytext "F8"> -<!ENTITY devToolbar.keycode "VK_F2"> -<!ENTITY devToolbar.keytext "F2"> -<!ENTITY devToolboxMenuItem.label "Toggle Tools"> -<!ENTITY devToolboxMenuItem.accesskey "T"> -<!ENTITY devToolboxMenuItem.keytext "I"> <!ENTITY devToolbarToolsButton.tooltip "Toggle developer tools"> + <!ENTITY devToolbarOtherToolsButton.label "More Tools"> -<!ENTITY getMoreDevtoolsCmd.label "Get More Tools"> -<!ENTITY getMoreDevtoolsCmd.accesskey "M"> - <!ENTITY fileMenu.label "File"> <!ENTITY fileMenu.accesskey "F"> <!ENTITY newUserContext.label "New Container Tab"> <!ENTITY newUserContext.accesskey "C"> <!ENTITY userContextPersonal.label "Personal"> <!ENTITY userContextPersonal.accesskey "P"> <!ENTITY userContextWork.label "Work"> <!ENTITY userContextWork.accesskey "W">
--- a/devtools/client/framework/browser-menus.js +++ b/devtools/client/framework/browser-menus.js @@ -8,19 +8,158 @@ * This module inject dynamically menu items and key shortcuts into browser UI. * * Menu and shortcut definitions are fetched from: * - devtools/client/menus for top level entires * - devtools/client/definitions for tool-specifics entries */ const Services = require("Services"); +const MenuStrings = Services.strings.createBundle("chrome://devtools/locale/menus.properties"); loader.lazyRequireGetter(this, "gDevTools", "devtools/client/framework/devtools", true); +// Keep list of inserted DOM Elements in order to remove them on unload +// Maps browser xul document => list of DOM Elements +const FragmentsCache = new Map(); + +function l10n(key) { + return MenuStrings.GetStringFromName(key); +} + +/** + * Create a xul:key element + * + * @param {XULDocument} doc + * The document to which keys are to be added. + * @param {String} l10nKey + * Prefix of the properties entry to look for key shortcut in + * localization file. We will look for {property}.key and + * {property}.keytext for non-character shortcuts like F12. + * @param {String} command + * Id of the xul:command to map to. + * @param {Object} key definition dictionnary + * Definition with following attributes: + * - {String} id + * xul:key's id, automatically prefixed with "key_", + * - {String} modifiers + * Space separater list of modifier names, + * - {Boolean} keytext + * If true, consider the shortcut as a characther one, + * otherwise a non-character one like F12. + * + * @return XULKeyElement + */ +function createKey(doc, l10nKey, command, key) { + let k = doc.createElement("key"); + k.id = "key_" + key.id; + let shortcut = l10n(l10nKey + ".key"); + if (shortcut.startsWith("VK_")) { + k.setAttribute("keycode", shortcut); + k.setAttribute("keytext", l10n(l10nKey + ".keytext")); + } else { + k.setAttribute("key", shortcut); + } + if (command) { + k.setAttribute("command", command); + } + if (key.modifiers) { + k.setAttribute("modifiers", key.modifiers); + } + return k; +} + +/** + * Create a xul:menuitem element + * + * @param {XULDocument} doc + * The document to which keys are to be added. + * @param {String} id + * Element id. + * @param {String} label + * Menu label. + * @param {String} broadcasterId (optional) + * Id of the xul:broadcaster to map to. + * @param {String} accesskey (optional) + * Access key of the menuitem, used as shortcut while opening the menu. + * @param {Boolean} isCheckbox + * If true, the menuitem will act as a checkbox and have an optional + * tick on its left. + * + * @return XULMenuItemElement + */ +function createMenuItem({ doc, id, label, broadcasterId, accesskey, isCheckbox }) { + let menuitem = doc.createElement("menuitem"); + menuitem.id = id; + if (label) { + menuitem.setAttribute("label", label); + } + if (broadcasterId) { + menuitem.setAttribute("observes", broadcasterId); + } + if (accesskey) { + menuitem.setAttribute("accesskey", accesskey); + } + if (isCheckbox) { + menuitem.setAttribute("type", "checkbox"); + menuitem.setAttribute("autocheck", "false"); + } + return menuitem; +} + +/** + * Create a xul:broadcaster element + * + * @param {XULDocument} doc + * The document to which keys are to be added. + * @param {String} id + * Element id. + * @param {String} label + * Broadcaster label. + * @param {Boolean} isCheckbox + * If true, the broadcaster is a checkbox one. + * + * @return XULMenuItemElement + */ +function createBroadcaster({ doc, id, label, isCheckbox }) { + let broadcaster = doc.createElement("broadcaster"); + broadcaster.id = id; + broadcaster.setAttribute("label", label); + if (isCheckbox) { + broadcaster.setAttribute("type", "checkbox"); + broadcaster.setAttribute("autocheck", "false"); + } + return broadcaster; +} + +/** + * Create a xul:command element + * + * @param {XULDocument} doc + * The document to which keys are to be added. + * @param {String} id + * Element id. + * @param {String} oncommand + * JS String to run when the command is fired. + * @param {Boolean} disabled + * If true, the command is disabled and hidden. + * + * @return XULCommandElement + */ +function createCommand({ doc, id, oncommand, disabled }) { + let command = doc.createElement("command"); + command.id = id; + command.setAttribute("oncommand", oncommand); + if (disabled) { + command.setAttribute("disabled", "true"); + command.setAttribute("hidden", "true"); + } + return command; +} + /** * Add a <key> to <keyset id="devtoolsKeyset">. * Appending a <key> element is not always enough. The <keyset> needs * to be detached and reattached to make sure the <key> is taken into * account (see bug 832984). * * @param {XULDocument} doc * The document to which keys are to be added @@ -50,52 +189,54 @@ function attachKeybindingsToBrowser(doc, function createToolMenuElements(toolDefinition, doc) { let id = toolDefinition.id; // Prevent multiple entries for the same tool. if (doc.getElementById("Tools:" + id)) { return; } - let cmd = doc.createElement("command"); - cmd.id = "Tools:" + id; - cmd.setAttribute("oncommand", - 'gDevToolsBrowser.selectToolCommand(gBrowser, "' + id + '");'); + let cmd = createCommand({ + doc, + id: "Tools:" + id, + oncommand: 'gDevToolsBrowser.selectToolCommand(gBrowser, "' + id + '");', + }); let key = null; if (toolDefinition.key) { key = doc.createElement("key"); key.id = "key_" + id; if (toolDefinition.key.startsWith("VK_")) { key.setAttribute("keycode", toolDefinition.key); } else { key.setAttribute("key", toolDefinition.key); } key.setAttribute("command", cmd.id); key.setAttribute("modifiers", toolDefinition.modifiers); } - let bc = doc.createElement("broadcaster"); - bc.id = "devtoolsMenuBroadcaster_" + id; - bc.setAttribute("label", toolDefinition.menuLabel || toolDefinition.label); + let bc = createBroadcaster({ + doc, + id: "devtoolsMenuBroadcaster_" + id, + label: toolDefinition.menuLabel || toolDefinition.label + }); bc.setAttribute("command", cmd.id); if (key) { bc.setAttribute("key", "key_" + id); } - let menuitem = doc.createElement("menuitem"); - menuitem.id = "menuitem_" + id; - menuitem.setAttribute("observes", "devtoolsMenuBroadcaster_" + id); - - if (toolDefinition.accesskey) { - menuitem.setAttribute("accesskey", toolDefinition.accesskey); - } + let menuitem = createMenuItem({ + doc, + id: "menuitem_" + id, + broadcasterId: "devtoolsMenuBroadcaster_" + id, + accesskey: toolDefinition.accesskey + }); return { cmd: cmd, key: key, bc: bc, menuitem: menuitem }; } @@ -208,29 +349,123 @@ function addAllToolsToMenu(doc) { let mps = doc.getElementById("menu_devtools_separator"); if (mps) { mps.parentNode.insertBefore(fragMenuItems, mps); } } /** - * Detect the presence of a Firebug. + * Add global menus and shortcuts that are not panel specific. + * + * @param {XULDocument} doc + * The document to which keys and menus are to be added. */ -function isFirebugInstalled() { - let bootstrappedAddons = Services.prefs.getCharPref("extensions.bootstrappedAddons"); - return bootstrappedAddons.indexOf("firebug@software.joehewitt.com") != -1; +function addTopLevelItems(doc) { + let keys = doc.createDocumentFragment(); + let menuItems = doc.createDocumentFragment(); + + let { menuitems } = require("../menus"); + for (let item of menuitems) { + if (item.separator) { + let separator = doc.createElement("menuseparator"); + separator.id = item.id; + menuItems.appendChild(separator); + } else { + let { id, l10nKey } = item; + + // Create a <menuitem> + let menuitem = createMenuItem({ + doc, + id, + label: l10n(l10nKey + ".label"), + accesskey: l10n(l10nKey + ".accesskey"), + isCheckbox: item.checkbox + }); + menuitem.addEventListener("command", item.oncommand); + menuItems.appendChild(menuitem); + + if (item.key && l10nKey) { + // Create a <key> + let key = createKey(doc, l10nKey, null, item.key); + // Bug 371900: command event is fired only if "oncommand" attribute is set. + key.setAttribute("oncommand", ";"); + key.addEventListener("command", item.oncommand); + // Refer to the key in order to display the key shortcut at menu ends + menuitem.setAttribute("key", key.id); + keys.appendChild(key); + } + if (item.additionalKeys) { + // Create additional <key> + for (let key of item.additionalKeys) { + let node = createKey(doc, key.l10nKey, null, key); + // Bug 371900: command event is fired only if "oncommand" attribute is set. + node.setAttribute("oncommand", ";"); + node.addEventListener("command", item.oncommand); + keys.appendChild(node); + } + } + } + } + + // Cache all nodes before insertion to be able to remove them on unload + let nodes = []; + for(let node of keys.children) { + nodes.push(node); + } + for(let node of menuItems.children) { + nodes.push(node); + } + FragmentsCache.set(doc, nodes); + + attachKeybindingsToBrowser(doc, keys); + + let menu = doc.getElementById("menuWebDeveloperPopup"); + menu.appendChild(menuItems); + + // There is still "Page Source" menuitem hardcoded into browser.xul. Instead + // of manually inserting everything around it, move it to the expected + // position. + let pageSource = doc.getElementById("menu_pageSource"); + let endSeparator = doc.getElementById("devToolsEndSeparator"); + menu.insertBefore(pageSource, endSeparator); +} + +/** + * Remove global menus and shortcuts that are not panel specific. + * + * @param {XULDocument} doc + * The document to which keys and menus are to be added. + */ +function removeTopLevelItems(doc) { + let nodes = FragmentsCache.get(doc); + if (!nodes) { + return; + } + FragmentsCache.delete(doc); + for (let node of nodes) { + node.remove(); + } } /** * Add menus and shortcuts to a browser document * * @param {XULDocument} doc * The document to which keys and menus are to be added. */ exports.addMenus = function (doc) { + addTopLevelItems(doc); + addAllToolsToMenu(doc); +}; - if (isFirebugInstalled()) { - let broadcaster = doc.getElementById("devtoolsMenuBroadcaster_DevToolbox"); - broadcaster.removeAttribute("key"); - } +/** + * Remove menus and shortcuts from a browser document + * + * @param {XULDocument} doc + * The document to which keys and menus are to be removed. + */ +exports.removeMenus = function (doc) { + // We only remove top level entries. Per-tool entries are removed while + // unregistering each tool. + removeTopLevelItems(doc); };
--- a/devtools/client/framework/devtools-browser.js +++ b/devtools/client/framework/devtools-browser.js @@ -75,64 +75,64 @@ var gDevToolsBrowser = exports.gDevTools /** * This function ensures the right commands are enabled in a window, * depending on their relevant prefs. It gets run when a window is registered, * or when any of the devtools prefs change. */ updateCommandAvailability: function(win) { let doc = win.document; - function toggleCmd(id, isEnabled) { + function toggleMenuItem(id, isEnabled) { let cmd = doc.getElementById(id); if (isEnabled) { 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"); - toggleCmd("Tools:DevToolbar", devToolbarEnabled); - let focusEl = doc.getElementById("Tools:DevToolbarFocus"); + 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")) { win.DeveloperToolbar.show(false).catch(console.error); } // Enable WebIDE? let webIDEEnabled = Services.prefs.getBoolPref("devtools.webide.enabled"); - toggleCmd("Tools:WebIDE", webIDEEnabled); + toggleMenuItem("menu_webide", webIDEEnabled); let showWebIDEWidget = Services.prefs.getBoolPref("devtools.webide.widget.enabled"); if (webIDEEnabled && showWebIDEWidget) { gDevToolsBrowser.installWebIDEWidget(); } else { gDevToolsBrowser.uninstallWebIDEWidget(); } // Enable Browser Toolbox? let chromeEnabled = Services.prefs.getBoolPref("devtools.chrome.enabled"); let devtoolsRemoteEnabled = Services.prefs.getBoolPref("devtools.debugger.remote-enabled"); let remoteEnabled = chromeEnabled && devtoolsRemoteEnabled; - toggleCmd("Tools:BrowserToolbox", remoteEnabled); - toggleCmd("Tools:BrowserContentToolbox", remoteEnabled && win.gMultiProcessBrowser); + toggleMenuItem("menu_browserToolbox", remoteEnabled); + toggleMenuItem("menu_browserContentToolbox", remoteEnabled && win.gMultiProcessBrowser); // Enable Error Console? let consoleEnabled = Services.prefs.getBoolPref("devtools.errorconsole.enabled"); - toggleCmd("Tools:ErrorConsole", consoleEnabled); + toggleMenuItem("javascriptConsole", consoleEnabled); // Enable DevTools connection screen, if the preference allows this. - toggleCmd("Tools:DevToolsConnect", devtoolsRemoteEnabled); + toggleMenuItem("menu_devtools_connect", devtoolsRemoteEnabled); }, observe: function(subject, topic, prefName) { switch (topic) { case "browser-delayed-startup-finished": this._registerBrowserWindow(subject); break; case "nsPref:changed": @@ -149,17 +149,16 @@ var gDevToolsBrowser = exports.gDevTools ensurePrefObserver: function() { if (!this._prefObserverRegistered) { this._prefObserverRegistered = true; Services.prefs.addObserver("devtools.", this, false); } }, - /** * This function is for the benefit of Tools:{toolId} commands, * triggered from the WebDeveloper menu and keyboard shortcuts. * * selectToolCommand's behavior: * - if the toolbox is closed, * we open the toolbox and select the tool * - if the toolbox is open, and the targeted tool is not selected, @@ -343,24 +342,27 @@ var gDevToolsBrowser = exports.gDevTools moveWebIDEWidgetInNavbar: function() { CustomizableUI.addWidgetToArea("webide-button", CustomizableUI.AREA_NAVBAR); }, /** * Add this DevTools's presence to a browser window's document * * @param {XULDocument} doc - * The document to which menuitems and handlers are to be added + * The document to which devtools should be hooked to. */ _registerBrowserWindow: function(win) { + if (gDevToolsBrowser._trackedBrowserWindows.has(win)) { + return; + } + gDevToolsBrowser._trackedBrowserWindows.add(win); + BrowserMenus.addMenus(win.document); - this.updateCommandAvailability(win); this.ensurePrefObserver(); - gDevToolsBrowser._trackedBrowserWindows.add(win); win.addEventListener("unload", this); let tabContainer = win.gBrowser.tabContainer; tabContainer.addEventListener("TabSelect", this, false); tabContainer.addEventListener("TabOpen", this, false); tabContainer.addEventListener("TabClose", this, false); tabContainer.addEventListener("TabPinned", this, false); tabContainer.addEventListener("TabUnpinned", this, false); @@ -515,17 +517,17 @@ var gDevToolsBrowser = exports.gDevTools * Update the "Toggle Tools" checkbox in the developer tools menu. This is * called when a toolbox is created or destroyed. */ _updateMenuCheckbox: function DT_updateMenuCheckbox() { for (let win of gDevToolsBrowser._trackedBrowserWindows) { let hasToolbox = gDevToolsBrowser.hasToolboxOpened(win); - let broadcaster = win.document.getElementById("devtoolsMenuBroadcaster_DevToolbox"); + let broadcaster = win.document.getElementById("menu_devToolbox"); if (hasToolbox) { broadcaster.setAttribute("checked", "true"); } else { broadcaster.removeAttribute("checked"); } } }, @@ -551,16 +553,18 @@ var gDevToolsBrowser = exports.gDevTools * * @param {XULWindow} win * The window containing the menu entry */ _forgetBrowserWindow: function(win) { gDevToolsBrowser._trackedBrowserWindows.delete(win); win.removeEventListener("unload", this); + BrowserMenus.removeMenus(win.document); + // Destroy toolboxes for closed window for (let [target, toolbox] of gDevTools._toolboxes) { if (toolbox.frame && toolbox.frame.ownerDocument.defaultView == win) { toolbox.destroy(); } } let tabContainer = win.gBrowser.tabContainer;
new file mode 100644 --- /dev/null +++ b/devtools/client/locales/en-US/menus.properties @@ -0,0 +1,70 @@ +# 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/. + +devToolsCmd.key = VK_F12 +devToolsCmd.keytext = F12 + +devtoolsServiceWorkers.label = Service Workers +devtoolsServiceWorkers.accesskey = k + +devtoolsConnect.label = Connect… +devtoolsConnect.accesskey = e + +errorConsoleCmd.label = Error Console +errorConsoleCmd.accesskey = C + +browserConsoleCmd.label = Browser Console +browserConsoleCmd.accesskey = B +browserConsoleCmd.key = j + +responsiveDesignMode.label = Responsive Design Mode +responsiveDesignMode.accesskey = R +responsiveDesignMode.key = M + +eyedropper.label = Eyedropper +eyedropper.accesskey = Y + +# LOCALIZATION NOTE (scratchpad.label): This menu item label appears +# in the Tools menu. See bug 653093. +# The Scratchpad is intended to provide a simple text editor for creating +# and evaluating bits of JavaScript code for the purposes of function +# prototyping, experimentation and convenient scripting. +# +# It's quite possible that you won't have a good analogue for the word +# "Scratchpad" in your locale. You should feel free to find a close +# approximation to it or choose a word (or words) that means +# "simple discardable text editor". +scratchpad.label = Scratchpad +scratchpad.accesskey = s +scratchpad.key = VK_F4 +scratchpad.keytext = F4 + +# LOCALIZATION NOTE (browserToolboxMenu.label): This is the label for the +# application menu item that opens the browser toolbox UI in the Tools menu. +browserToolboxMenu.label = Browser Toolbox +browserToolboxMenu.accesskey = e +browserToolboxMenu.key = i + +# 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 +devToolbarMenu.key = VK_F2 +devToolbarMenu.keytext = F2 + +webide.label = WebIDE +webide.accesskey = W +webide.key = VK_F8 +webide.keytext = F8 + +devToolboxMenuItem.label = Toggle Tools +devToolboxMenuItem.accesskey = T +devToolboxMenuItem.key = I + +getMoreDevtoolsCmd.label = Get More Tools +getMoreDevtoolsCmd.accesskey = M
new file mode 100644 --- /dev/null +++ b/devtools/client/menus.js @@ -0,0 +1,207 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +/** + * This module defines the sorted list of menuitems inserted into the + * "Web Developer" menu. + * It also defines the key shortcuts that relates to them. + * + * Various fields are necessary for historical compatiblity with XUL/addons: + * - id: + * used as <xul:menuitem> id attribute + * - l10nKey: + * prefix used to locale localization strings from menus.properties + * - oncommand: + * function called when the menu item or key shortcut are fired + * - key: + * - id: + * prefixed by 'key_' to compute <xul:key> id attribute + * - modifiers: + * optional modifiers for the key shortcut + * - keytext: + * boolean, to set to true for key shortcut using regular character + * - additionalKeys: + * Array of additional keys, see `key` definition. + * - disabled: + * If true, the menuitem and key shortcut are going to be hidden and disabled + * on startup, until some runtime code eventually enable them. + * - checkbox: + * If true, the menuitem is prefixed by a checkbox and runtime code can + * toggle it. + */ + +const Services = require("Services"); +const isMac = Services.appinfo.OS === "Darwin"; + +loader.lazyRequireGetter(this, "gDevToolsBrowser", "devtools/client/framework/devtools-browser", true); +loader.lazyRequireGetter(this, "Eyedropper", "devtools/client/eyedropper/eyedropper", true); + +loader.lazyImporter(this, "BrowserToolboxProcess", "resource://devtools/client/framework/ToolboxProcess.jsm"); +loader.lazyImporter(this, "ResponsiveUIManager", "resource://devtools/client/responsivedesign/responsivedesign.jsm"); +loader.lazyImporter(this, "ScratchpadManager", "resource://devtools/client/scratchpad/scratchpad-manager.jsm"); + +/** + * Detect the presence of a Firebug. + */ +function isFirebugInstalled() { + let bootstrappedAddons = Services.prefs + .getCharPref("extensions.bootstrappedAddons"); + return bootstrappedAddons.indexOf("firebug@software.joehewitt.com") != -1; +} + +exports.menuitems = [ + { id: "menu_devToolbox", + l10nKey: "devToolboxMenuItem", + oncommand(event) { + let window = event.target.ownerDocument.defaultView; + gDevToolsBrowser.toggleToolboxCommand(window.gBrowser); + }, + key: { + id: "devToolboxMenuItem", + modifiers: isMac ? "accel,alt" : "accel,shift", + // This is the only one with a letter key + // and needs to be translated differently + keytext: true, + }, + // This key conflicts with firebug, only enable it when it's not installed. + additionalKeys: !isFirebugInstalled() ? [{ + id: "devToolboxMenuItemF12", + l10nKey: "devToolsCmd", + }] : null, + 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") { + window.DeveloperToolbar.toggle(); + } else { + window.DeveloperToolbar.focusToggle(); + } + }, + key: { + id: "devToolbar", + modifiers: "shift" + }, + checkbox: true + }, + { id: "menu_webide", + l10nKey: "webide", + disabled: true, + oncommand() { + gDevToolsBrowser.openWebIDE(); + }, + key: { + id: "webide", + modifiers: "shift" + } + }, + { id: "menu_browserToolbox", + l10nKey: "browserToolboxMenu", + disabled: true, + oncommand() { + BrowserToolboxProcess.init(); + }, + key: { + id: "browserToolbox", + modifiers: "accel,alt,shift", + keytext: true + } + }, + { id: "menu_browserContentToolbox", + l10nKey: "browserContentToolboxMenu", + disabled: true, + oncommand() { + gDevToolsBrowser.openContentProcessToolbox(); + } + }, + { id: "menu_browserConsole", + l10nKey: "browserConsoleCmd", + oncommand() { + let HUDService = require("devtools/client/webconsole/hudservice"); + HUDService.openBrowserConsoleOrFocus(); + }, + key: { + id: "browserConsole", + modifiers: "accel,shift", + keytext: true + } + }, + { id: "menu_responsiveUI", + l10nKey: "responsiveDesignMode", + oncommand(event) { + let window = event.target.ownerDocument.defaultView; + ResponsiveUIManager.toggle(window, window.gBrowser.selectedTab); + }, + key: { + id: "responsiveUI", + modifiers: isMac ? "accel,alt" : "accel,shift", + keytext: true + }, + checkbox: true + }, + { id: "menu_eyedropper", + l10nKey: "eyedropper", + oncommand(event) { + let window = event.target.ownerDocument.defaultView; + let eyedropper = new Eyedropper(window, { context: "menu", + copyOnSelect: true }); + eyedropper.open(); + }, + checkbox: true + }, + { id: "menu_scratchpad", + l10nKey: "scratchpad", + oncommand() { + ScratchpadManager.openScratchpad(); + }, + key: { + id: "scratchpad", + modifiers: "shift" + } + }, + { id: "javascriptConsole", + l10nKey: "errorConsoleCmd", + disabled: true, + oncommand(event) { + let window = event.target.ownerDocument.defaultView; + window.toJavaScriptConsole(); + } + }, + { id: "menu_devtools_serviceworkers", + l10nKey: "devtoolsServiceWorkers", + disabled: true, + oncommand(event) { + let window = event.target.ownerDocument.defaultView; + gDevToolsBrowser.openAboutDebugging(window.gBrowser, "workers"); + } + }, + { id: "menu_devtools_connect", + l10nKey: "devtoolsConnect", + disabled: true, + oncommand(event) { + let window = event.target.ownerDocument.defaultView; + gDevToolsBrowser.openConnectScreen(window.gBrowser); + } + }, + { separator: true, + id: "devToolsEndSeparator" + }, + { id: "getMoreDevtools", + l10nKey: "getMoreDevtoolsCmd", + oncommand(event) { + let window = event.target.ownerDocument.defaultView; + window.openUILinkIn("https://addons.mozilla.org/firefox/collections/mozilla/webdeveloper/", "tab"); + } + }, +];
--- a/devtools/client/moz.build +++ b/devtools/client/moz.build @@ -47,9 +47,10 @@ EXTRA_COMPONENTS += [ 'devtools-startup.manifest', ] JAR_MANIFESTS += ['jar.mn'] DevToolsModules( 'definitions.js', 'main.js', + 'menus.js', )
--- a/devtools/client/responsivedesign/responsivedesign.jsm +++ b/devtools/client/responsivedesign/responsivedesign.jsm @@ -437,24 +437,24 @@ ResponsiveUI.prototype = { break; } }, /** * Check the menu items. */ checkMenus: function RUI_checkMenus() { - this.chromeDoc.getElementById("Tools:ResponsiveUI").setAttribute("checked", "true"); + this.chromeDoc.getElementById("menu_responsiveUI").setAttribute("checked", "true"); }, /** * Uncheck the menu items. */ unCheckMenus: function RUI_unCheckMenus() { - this.chromeDoc.getElementById("Tools:ResponsiveUI").setAttribute("checked", "false"); + this.chromeDoc.getElementById("menu_responsiveUI").setAttribute("checked", "false"); }, /** * Build the toolbar and the resizers. * * <vbox class="browserContainer"> From tabbrowser.xml * <toolbar class="devtools-responsiveui-toolbar"> * <menulist class="devtools-responsiveui-menulist"/> // presets
--- a/devtools/client/responsivedesign/test/browser_responsiveruleview.js +++ b/devtools/client/responsivedesign/test/browser_responsiveruleview.js @@ -76,20 +76,20 @@ function* testEscapeOpensSplitConsole(in let onSplit = inspector._toolbox.once("split-console"); EventUtils.synthesizeKey("VK_ESCAPE", {}); yield onSplit; ok(inspector._toolbox._splitConsole, "Console is split after pressing ESC."); } function* testMenuItem(rdm) { - is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"), + is(document.getElementById("menu_responsiveUI").getAttribute("checked"), "true", "The menu item is checked"); yield closeRDM(rdm); - is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"), + is(document.getElementById("menu_responsiveUI").getAttribute("checked"), "false", "The menu item is unchecked"); } function numberOfRules(ruleView) { return ruleView.element.querySelectorAll(".ruleview-code").length; }
--- a/devtools/client/responsivedesign/test/browser_responsiveui.js +++ b/devtools/client/responsivedesign/test/browser_responsiveui.js @@ -5,17 +5,17 @@ add_task(function*() { let tab = yield addTab("data:text/html,mop"); let {rdm, manager} = yield openRDM(tab, "menu"); let container = gBrowser.getBrowserContainer(); is(container.getAttribute("responsivemode"), "true", "Should be in responsive mode."); - is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"), + is(document.getElementById("menu_responsiveUI").getAttribute("checked"), "true", "Menu item should be checked"); ok(rdm, "An instance of the RDM should be attached to the tab."); let originalWidth = (yield getSizing()).width; let documentLoaded = waitForDocLoadComplete(); gBrowser.loadURI("data:text/html;charset=utf-8,mop" + @@ -55,26 +55,26 @@ add_task(function*() { yield resized; let currentSize = yield getSizing(); is(currentSize.width, widthBeforeClose, "width should be restored"); is(currentSize.height, heightBeforeClose, "height should be restored"); container = gBrowser.getBrowserContainer(); is(container.getAttribute("responsivemode"), "true", "In responsive mode."); - is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"), + is(document.getElementById("menu_responsiveUI").getAttribute("checked"), "true", "menu item should be checked"); let isWinXP = navigator.userAgent.indexOf("Windows NT 5.1") != -1; if (!isWinXP) { yield testScreenshot(rdm); } yield closeRDM(rdm); - is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"), + is(document.getElementById("menu_responsiveUI").getAttribute("checked"), "false", "menu item should be unchecked"); }); function* testPresets(rdm, manager) { // Starting from length - 4 because last 3 items are not presets : // the separator, the add button and the remove button for (let c = rdm.menulist.firstChild.childNodes.length - 4; c >= 0; c--) { let item = rdm.menulist.firstChild.childNodes[c];
--- a/devtools/client/responsivedesign/test/head.js +++ b/devtools/client/responsivedesign/test/head.js @@ -34,17 +34,17 @@ const { ResponsiveUIManager } = Cu.impor */ var openRDM = Task.async(function*(tab = gBrowser.selectedTab, method = "menu") { let manager = ResponsiveUIManager; let opened = once(manager, "on"); let resized = once(manager, "contentResize"); if (method == "menu") { - document.getElementById("Tools:ResponsiveUI").doCommand(); + document.getElementById("menu_responsiveUI").doCommand(); } else { synthesizeKeyFromKeyTag(document.getElementById("key_responsiveUI")); } yield opened; let rdm = manager.getResponsiveUIForTab(tab); rdm.transitionsEnabled = false; registerCleanupFunction(() => {
--- a/devtools/client/shared/developer-toolbar.js +++ b/devtools/client/shared/developer-toolbar.js @@ -24,16 +24,17 @@ loader.lazyGetter(this, "prefBranch", fu }); loader.lazyGetter(this, "toolboxStrings", function () { return Services.strings.createBundle("chrome://devtools/locale/toolbox.properties"); }); loader.lazyRequireGetter(this, "gcliInit", "devtools/shared/gcli/commands/index"); loader.lazyRequireGetter(this, "util", "gcli/util/util"); loader.lazyRequireGetter(this, "ConsoleServiceListener", "devtools/shared/webconsole/utils", true); +loader.lazyRequireGetter(this, "gDevToolsBrowser", "devtools/client/framework/devtools-browser", true); /** * A collection of utilities to help working with commands */ var CommandUtils = { /** * Utility to ensure that things are loaded in the correct order */ @@ -313,18 +314,21 @@ DeveloperToolbar.prototype.createToolbar 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"); - toolboxBtn.setAttribute("observes", "devtoolsMenuBroadcaster_DevToolbox"); toolboxBtn.setAttribute("tooltiptext", "devToolbarToolsButton.tooltip"); + toolboxBtn.addEventListener("command", function (event) { + let window = event.target.ownerDocument.defaultView; + gDevToolsBrowser.toggleToolboxCommand(window.gBrowser); + }); // 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 { @@ -427,17 +431,17 @@ DeveloperToolbar.prototype.show = functi // write to, so this needs to be done asynchronously. let panelPromises = [ TooltipPanel.create(this), OutputPanel.create(this) ]; return promise.all(panelPromises).then(panels => { [ this.tooltipPanel, this.outputPanel ] = panels; - this._doc.getElementById("Tools:DevToolbar").setAttribute("checked", "true"); + 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, }; return CommandUtils.createRequisition(this.target, options).then(requisition => { this.requisition = requisition; @@ -549,17 +553,17 @@ DeveloperToolbar.prototype.hide = functi // show() is async, so ensure we don't need to wait for show() to finish var waitPromise = this._showPromise || promise.resolve(); this._hidePromise = waitPromise.then(() => { this._element.hidden = true; Services.prefs.setBoolPref("devtools.toolbar.visible", false); - this._doc.getElementById("Tools:DevToolbar").setAttribute("checked", "false"); + this._doc.getElementById("menu_devToolbar").setAttribute("checked", "false"); this.destroy(); this._telemetry.toolClosed("developertoolbar"); this._notify(NOTIFICATIONS.HIDE); this._hidePromise = null; });
--- a/devtools/client/shared/test/browser_toolbar_basic.js +++ b/devtools/client/shared/test/browser_toolbar_basic.js @@ -15,17 +15,17 @@ add_task(function*() { document.getElementById("menu_devToolbar").doCommand(); yield shown; ok(DeveloperToolbar.visible, "DeveloperToolbar is visible in checkOpen"); let close = document.getElementById("developer-toolbar-closebutton"); ok(close, "Close button exists"); let toggleToolbox = - document.getElementById("devtoolsMenuBroadcaster_DevToolbox"); + document.getElementById("menu_devToolbox"); ok(!isChecked(toggleToolbox), "toggle toolbox button is not checked"); let target = TargetFactory.forTab(gBrowser.selectedTab); let toolbox = yield gDevTools.showToolbox(target, "inspector"); ok(isChecked(toggleToolbox), "toggle toolbox button is checked"); yield addTab("about:blank"); info("Opened a new tab");