Bug 1268447 - Convert webconsole to use new key shortcut module. r=bgrins
authorAlexandre Poirot <poirot.alex@gmail.com>
Tue, 31 May 2016 14:17:03 -0700
changeset 338666 d39456c7ccf19d98bb20c3de1dd88cb3c9513c55
parent 338665 3f1686cbca54bb830163dd7fbb0fb9048916ea8f
child 338667 616172b19ee126ed35aff44e0af5f0ec81d5b53b
push id6249
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 13:59:36 +0000
treeherdermozilla-beta@bad9d4f5bf7e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbgrins
bugs1268447
milestone49.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
Bug 1268447 - Convert webconsole to use new key shortcut module. r=bgrins
devtools/client/framework/test/browser_keybindings_02.js
devtools/client/framework/test/browser_toolbox_zoom.js
devtools/client/framework/toolbox.js
devtools/client/locales/en-US/webconsole.properties
devtools/client/preferences/devtools.js
devtools/client/shared/moz.build
devtools/client/shared/zoom-keys.js
devtools/client/webconsole/hudservice.js
devtools/client/webconsole/test/browser.ini
devtools/client/webconsole/test/browser_console_keyboard_accessibility.js
devtools/client/webconsole/test/browser_webconsole_change_font_size.js
devtools/client/webconsole/webconsole.js
devtools/client/webconsole/webconsole.xul
--- a/devtools/client/framework/test/browser_keybindings_02.js
+++ b/devtools/client/framework/test/browser_keybindings_02.js
@@ -8,16 +8,20 @@
 // Test that the toolbox keybindings still work after the host is changed.
 
 const URL = "data:text/html;charset=utf8,test page";
 
 var {Toolbox} = require("devtools/client/framework/toolbox");
 var strings = Services.strings.createBundle(
   "chrome://devtools/locale/toolbox.properties");
 
+function getZoomValue() {
+  return parseFloat(Services.prefs.getCharPref("devtools.toolbox.zoomValue"));
+}
+
 add_task(function* () {
   info("Create a test tab and open the toolbox");
   let tab = yield addTab(URL);
   let target = TargetFactory.forTab(tab);
   let toolbox = yield gDevTools.showToolbox(target, "webconsole");
 
   let {SIDE, BOTTOM} = Toolbox.HostType;
   for (let type of [SIDE, BOTTOM, SIDE]) {
@@ -36,19 +40,19 @@ add_task(function* () {
 
 function zoomWithKey(toolbox, key) {
   let shortcut = strings.GetStringFromName(key);
   if (!shortcut) {
     info("Key was empty, skipping zoomWithKey");
     return;
   }
   info("Zooming with key: " + key);
-  let currentZoom = toolbox.zoomValue;
-  synthesizeKeyShortcut(shortcut);
-  isnot(toolbox.zoomValue, currentZoom, "The zoom level was changed in the toolbox");
+  let currentZoom = getZoomValue();
+  synthesizeKeyShortcut(shortcut, toolbox.win);
+  isnot(getZoomValue(), currentZoom, "The zoom level was changed in the toolbox");
 }
 
 function* checkKeyBindings(toolbox) {
   zoomWithKey(toolbox, "toolbox.zoomIn.key");
   zoomWithKey(toolbox, "toolbox.zoomIn2.key");
   zoomWithKey(toolbox, "toolbox.zoomIn3.key");
 
   zoomWithKey(toolbox, "toolbox.zoomReset.key");
--- a/devtools/client/framework/test/browser_toolbox_zoom.js
+++ b/devtools/client/framework/test/browser_toolbox_zoom.js
@@ -35,17 +35,19 @@ function testZoom() {
 }
 
 function testZoomLevel(type, times, expected) {
   sendZoomKey("toolbox.zoom" + type + ".key", times);
 
   let zoom = getCurrentZoom(toolbox);
   is(zoom.toFixed(2), expected, "zoom level correct after zoom " + type);
 
-  is(toolbox.zoomValue.toFixed(2), expected,
+  let savedZoom = parseFloat(Services.prefs.getCharPref(
+    "devtools.toolbox.zoomValue"));
+  is(savedZoom.toFixed(2), expected,
      "saved zoom level is correct after zoom " + type);
 }
 
 function sendZoomKey(shortcut, times) {
   for (let i = 0; i < times; i++) {
     synthesizeKeyShortcut(strings.GetStringFromName(shortcut));
   }
 }
--- a/devtools/client/framework/toolbox.js
+++ b/devtools/client/framework/toolbox.js
@@ -2,21 +2,18 @@
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* 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 MAX_ORDINAL = 99;
-const ZOOM_PREF = "devtools.toolbox.zoomValue";
 const SPLITCONSOLE_ENABLED_PREF = "devtools.toolbox.splitconsoleEnabled";
 const SPLITCONSOLE_HEIGHT_PREF = "devtools.toolbox.splitconsoleHeight";
-const MIN_ZOOM = 0.5;
-const MAX_ZOOM = 2;
 const OS_HISTOGRAM = "DEVTOOLS_OS_ENUMERATED_PER_USER";
 const OS_IS_64_BITS = "DEVTOOLS_OS_IS_64_BITS_PER_USER";
 const SCREENSIZE_HISTOGRAM = "DEVTOOLS_SCREEN_RESOLUTION_ENUMERATED_PER_USER";
 const HTML_NS = "http://www.w3.org/1999/xhtml";
 
 var {Cc, Ci, Cu} = require("chrome");
 var promise = require("promise");
 var Services = require("Services");
@@ -68,16 +65,18 @@ loader.lazyRequireGetter(this, "showDoor
 loader.lazyRequireGetter(this, "createPerformanceFront",
   "devtools/server/actors/performance", true);
 loader.lazyRequireGetter(this, "system",
   "devtools/shared/system");
 loader.lazyRequireGetter(this, "getPreferenceFront",
   "devtools/server/actors/preference", true);
 loader.lazyRequireGetter(this, "KeyShortcuts",
   "devtools/client/shared/key-shortcuts", true);
+loader.lazyRequireGetter(this, "ZoomKeys",
+  "devtools/client/shared/zoom-keys");
 
 loader.lazyGetter(this, "osString", () => {
   return Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).OS;
 });
 loader.lazyGetter(this, "registerHarOverlay", () => {
   return require("devtools/client/netmonitor/har/toolbox-overlay").register;
 });
 
@@ -299,23 +298,16 @@ Toolbox.prototype = {
   /**
    * Shortcut to the document containing the toolbox UI
    */
   get doc() {
     return this.frame.contentDocument;
   },
 
   /**
-   * Get current zoom level of toolbox
-   */
-  get zoomValue() {
-    return parseFloat(Services.prefs.getCharPref(ZOOM_PREF));
-  },
-
-  /**
    * Get the toolbox highlighter front. Note that it may not always have been
    * initialized first. Use `initInspector()` if needed.
    * Consider using highlighterUtils instead, it exposes the highlighter API in
    * a useful way for the toolbox panels
    */
   get highlighter() {
     return this._highlighter;
   },
@@ -435,18 +427,17 @@ Toolbox.prototype = {
       this._buildTabs();
       this._applyCacheSettings();
       this._applyServiceWorkersTestingSettings();
       this._addKeysToWindow();
       this._addReloadKeys(shortcuts);
       this._addHostListeners(shortcuts);
       this._registerOverlays();
       if (!this._hostOptions || this._hostOptions.zoom === true) {
-        this._addZoomKeys(shortcuts);
-        this._loadInitialZoom();
+        ZoomKeys.register(this.win);
       }
       this._setToolbarKeyboardNavigation();
 
       this.webconsolePanel = this.doc.querySelector("#toolbox-panel-webconsole");
       this.webconsolePanel.height = Services.prefs.getIntPref(SPLITCONSOLE_HEIGHT_PREF);
       this.webconsolePanel.addEventListener("resize", this._saveSplitConsoleHeight);
 
       let buttonsPromise = this._buildButtons();
@@ -655,98 +646,16 @@ Toolbox.prototype = {
       } else {
         webconsolePanel.setAttribute("collapsed", "true");
         splitter.setAttribute("hidden", "true");
       }
     }
   },
 
   /**
-   * Wire up the listeners for the zoom keys.
-   */
-  _addZoomKeys: function (shortcuts) {
-    shortcuts.on(toolboxStrings("toolbox.zoomIn.key"),
-                 this.zoomIn.bind(this));
-    let zoomIn2 = toolboxStrings("toolbox.zoomIn2.key");
-    if (zoomIn2) {
-      shortcuts.on(zoomIn2, this.zoomIn.bind(this));
-    }
-    let zoomIn3 = toolboxStrings("toolbox.zoomIn2.key");
-    if (zoomIn3) {
-      shortcuts.on(zoomIn3, this.zoomIn.bind(this));
-    }
-
-    shortcuts.on(toolboxStrings("toolbox.zoomOut.key"),
-                 this.zoomOut.bind(this));
-    let zoomOut2 = toolboxStrings("toolbox.zoomOut2.key");
-    if (zoomOut2) {
-      shortcuts.on(zoomOut2, this.zoomOut.bind(this));
-    }
-
-    shortcuts.on(toolboxStrings("toolbox.zoomReset.key"),
-                 this.zoomReset.bind(this));
-    let zoomReset2 = toolboxStrings("toolbox.zoomReset2.key");
-    if (zoomReset2) {
-      shortcuts.on(zoomReset2, this.zoomReset.bind(this));
-    }
-  },
-
-  /**
-   * Set zoom on toolbox to whatever the last setting was.
-   */
-  _loadInitialZoom: function () {
-    this.setZoom(this.zoomValue);
-  },
-
-  /**
-   * Increase zoom level of toolbox window - make things bigger.
-   */
-  zoomIn: function (name, event) {
-    this.setZoom(this.zoomValue + 0.1);
-    event.preventDefault();
-  },
-
-  /**
-   * Decrease zoom level of toolbox window - make things smaller.
-   */
-  zoomOut: function (name, event) {
-    this.setZoom(this.zoomValue - 0.1);
-    event.preventDefault();
-  },
-
-  /**
-   * Reset zoom level of the toolbox window.
-   */
-  zoomReset: function (name, event) {
-    this.setZoom(1);
-    event.preventDefault();
-  },
-
-  /**
-   * Set zoom level of the toolbox window.
-   *
-   * @param {number} zoomValue
-   *        Zoom level e.g. 1.2
-   */
-  setZoom: function (zoomValue) {
-    // cap zoom value
-    zoomValue = Math.max(zoomValue, MIN_ZOOM);
-    zoomValue = Math.min(zoomValue, MAX_ZOOM);
-
-    let docShell = this.win.QueryInterface(Ci.nsIInterfaceRequestor)
-      .getInterface(Ci.nsIWebNavigation)
-      .QueryInterface(Ci.nsIDocShell);
-    let contViewer = docShell.contentViewer;
-
-    contViewer.fullZoom = zoomValue;
-
-    Services.prefs.setCharPref(ZOOM_PREF, zoomValue);
-  },
-
-  /**
    * Adds the keys and commands to the Toolbox Window in window mode.
    */
   _addKeysToWindow: function () {
     if (this.hostType != Toolbox.HostType.WINDOW) {
       return;
     }
 
     let doc = this.win.parent.document;
--- a/devtools/client/locales/en-US/webconsole.properties
+++ b/devtools/client/locales/en-US/webconsole.properties
@@ -253,8 +253,21 @@ table.key=Key
 table.value=Values
 
 # LOCALIZATION NOTE (severity.error, severity.warn, severity.info, severity.log):
 # tooltip for icons next to console output
 severity.error=Error
 severity.warn=Warning
 severity.info=Info
 severity.log=Log
+
+# LOCALIZATION NOTE (webconsole.find.key)
+# Key shortcut used to focus the search box on upper right of the console
+webconsole.find.key=CmdOrCtrl+F
+
+# LOCALIZATION NOTE (webconsole.close.key)
+# Key shortcut used to close the Browser console (doesn't work in regular web console)
+webconsole.close.key=CmdOrCtrl+W
+
+# LOCALIZATION NOTE (webconsole.clear.key*)
+# Key shortcut used to clear the console output
+webconsole.clear.key=Ctrl+Shift+L
+webconsole.clear.keyOSX=Ctrl+L
--- a/devtools/client/preferences/devtools.js
+++ b/devtools/client/preferences/devtools.js
@@ -271,19 +271,16 @@ pref("devtools.browserconsole.filter.sec
 pref("devtools.browserconsole.filter.serviceworkers", true);
 pref("devtools.browserconsole.filter.sharedworkers", true);
 pref("devtools.browserconsole.filter.windowlessworkers", true);
 pref("devtools.browserconsole.filter.servererror", false);
 pref("devtools.browserconsole.filter.serverwarn", false);
 pref("devtools.browserconsole.filter.serverinfo", false);
 pref("devtools.browserconsole.filter.serverlog", false);
 
-// Text size in the Web Console. Use 0 for the system default size.
-pref("devtools.webconsole.fontSize", 0);
-
 // Max number of inputs to store in web console history.
 pref("devtools.webconsole.inputHistoryCount", 50);
 
 // Persistent logging: |true| if you want the Web Console to keep all of the
 // logged messages after reloading the page, |false| if you want the output to
 // be cleared each time page navigation happens.
 pref("devtools.webconsole.persistlog", false);
 
--- a/devtools/client/shared/moz.build
+++ b/devtools/client/shared/moz.build
@@ -48,9 +48,10 @@ DevToolsModules(
     'SplitView.jsm',
     'suggestion-picker.js',
     'telemetry.js',
     'theme-switching.js',
     'theme.js',
     'undo.js',
     'view-source.js',
     'webgl-utils.js',
+    'zoom-keys.js',
 )
new file mode 100644
--- /dev/null
+++ b/devtools/client/shared/zoom-keys.js
@@ -0,0 +1,88 @@
+/* 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 { Ci } = require("chrome");
+const Services = require("Services");
+const { KeyShortcuts } = require("devtools/client/shared/key-shortcuts");
+
+const ZOOM_PREF = "devtools.toolbox.zoomValue";
+const MIN_ZOOM = 0.5;
+const MAX_ZOOM = 2;
+
+const properties = "chrome://devtools/locale/toolbox.properties";
+const bundle = Services.strings.createBundle(properties);
+function l10n(key) {
+  return bundle.GetStringFromName(key);
+}
+
+/**
+ * Register generic keys to control zoom level of the given document.
+ * Used by both the toolboxes and the browser console.
+ *
+ * @param {DOMWindow} The window on which we should listent to key strokes and
+ *                    modify the zoom factor.
+ */
+exports.register = function (window) {
+  let shortcuts = new KeyShortcuts({
+    window
+  });
+  let docShell = window.QueryInterface(Ci.nsIInterfaceRequestor)
+    .getInterface(Ci.nsIWebNavigation)
+    .QueryInterface(Ci.nsIDocShell);
+  let contViewer = docShell.contentViewer;
+  let zoomValue = parseFloat(Services.prefs.getCharPref(ZOOM_PREF));
+  let zoomIn = function (name, event) {
+    setZoom(zoomValue + 0.1);
+    event.preventDefault();
+  };
+
+  let zoomOut = function (name, event) {
+    setZoom(zoomValue - 0.1);
+    event.preventDefault();
+  };
+
+  let zoomReset = function (name, event) {
+    setZoom(1);
+    event.preventDefault();
+  };
+
+  let setZoom = function (newValue) {
+    // cap zoom value
+    zoomValue = Math.max(newValue, MIN_ZOOM);
+    zoomValue = Math.min(zoomValue, MAX_ZOOM);
+
+    contViewer.fullZoom = zoomValue;
+
+    Services.prefs.setCharPref(ZOOM_PREF, zoomValue);
+  };
+
+  // Set zoom to whatever the last setting was.
+  setZoom(zoomValue);
+
+  shortcuts.on(l10n("toolbox.zoomIn.key"), zoomIn);
+  let zoomIn2 = l10n("toolbox.zoomIn2.key");
+  if (zoomIn2) {
+    shortcuts.on(zoomIn2, zoomIn);
+  }
+  let zoomIn3 = l10n("toolbox.zoomIn2.key");
+  if (zoomIn3) {
+    shortcuts.on(zoomIn3, zoomIn);
+  }
+
+  shortcuts.on(l10n("toolbox.zoomOut.key"),
+               zoomOut);
+  let zoomOut2 = l10n("toolbox.zoomOut2.key");
+  if (zoomOut2) {
+    shortcuts.on(zoomOut2, zoomOut);
+  }
+
+  shortcuts.on(l10n("toolbox.zoomReset.key"),
+               zoomReset);
+  let zoomReset2 = l10n("toolbox.zoomReset2.key");
+  if (zoomReset2) {
+    shortcuts.on(zoomReset2, zoomReset);
+  }
+};
--- a/devtools/client/webconsole/hudservice.js
+++ b/devtools/client/webconsole/hudservice.js
@@ -664,19 +664,16 @@ BrowserConsole.prototype = extend(WebCon
     // instance.
     let onClose = () => {
       window.removeEventListener("unload", onClose);
       window.removeEventListener("focus", onFocus);
       this.destroy();
     };
     window.addEventListener("unload", onClose);
 
-    // Make sure Ctrl-W closes the Browser Console window.
-    window.document.getElementById("cmd_close").removeAttribute("disabled");
-
     this._telemetry.toolOpened("browserconsole");
 
     // Create an onFocus handler just to display the dev edition promo.
     // This is to prevent race conditions in some environments.
     // Hook to display promotional Developer Edition doorhanger. Only displayed once.
     let onFocus = () => showDoorhanger({ window, type: "deveditionpromo" });
     window.addEventListener("focus", onFocus);
 
--- a/devtools/client/webconsole/test/browser.ini
+++ b/devtools/client/webconsole/test/browser.ini
@@ -295,17 +295,16 @@ skip-if = os != "mac"
 skip-if = e10s # Bug 1042253 - webconsole e10s tests (Linux debug intermittent)
 [browser_webconsole_bug_1010953_cspro.js]
 skip-if = e10s && (os == 'win' || os == 'mac') # Bug 1243967
 [browser_webconsole_certificate_messages.js]
 skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
 [browser_webconsole_show_subresource_security_errors.js]
 skip-if = e10s && (os == 'win' || os == 'mac') # Bug 1243987
 [browser_webconsole_cached_autocomplete.js]
-[browser_webconsole_change_font_size.js]
 [browser_webconsole_chrome.js]
 [browser_webconsole_clickable_urls.js]
 [browser_webconsole_closure_inspection.js]
 [browser_webconsole_completion.js]
 [browser_webconsole_console_extras.js]
 [browser_webconsole_console_logging_api.js]
 [browser_webconsole_console_logging_workers_api.js]
 [browser_webconsole_console_trace_async.js]
--- a/devtools/client/webconsole/test/browser_console_keyboard_accessibility.js
+++ b/devtools/client/webconsole/test/browser_console_keyboard_accessibility.js
@@ -48,28 +48,32 @@ add_task(function* () {
   EventUtils.synthesizeKey("VK_END", {});
 
   let scrollTop = hud.ui.outputWrapper.scrollTop;
   ok(scrollTop > 0 && Math.abs(scrollTop - bottom) <= 5,
      "scroll position now at bottom");
 
   info("try ctrl-l to clear output");
   executeSoon(() => {
-    let selector = "key[command=consoleCmd_clearOutput]:not([disabled])";
-    let clearKey = hud.ui.window.document.querySelector(selector);
-    synthesizeKeyFromKeyTag(clearKey);
+    let clearShortcut;
+    if (Services.appinfo.OS === "Darwin") {
+      clearShortcut = WCUL10n.getStr("webconsole.clear.keyOSX");
+    } else {
+      clearShortcut = WCUL10n.getStr("webconsole.clear.key");
+    }
+    synthesizeKeyShortcut(clearShortcut);
   });
   yield hud.jsterm.once("messages-cleared");
 
   is(hud.outputNode.textContent.indexOf("foobarz1"), -1, "output cleared");
   is(hud.jsterm.inputNode.getAttribute("focused"), "true",
      "jsterm input is focused");
 
   info("try ctrl-f to focus filter");
-  EventUtils.synthesizeKey("F", { accelKey: true });
+  synthesizeKeyShortcut(WCUL10n.getStr("webconsole.find.key"));
   ok(!hud.jsterm.inputNode.getAttribute("focused"),
      "jsterm input is not focused");
   is(hud.ui.filterBox.getAttribute("focused"), "true",
      "filter input is focused");
 
   if (Services.appinfo.OS == "Darwin") {
     ok(hud.ui.getFilterState("network"), "network category is enabled");
     EventUtils.synthesizeKey("t", { ctrlKey: true });
deleted file mode 100644
--- a/devtools/client/webconsole/test/browser_webconsole_change_font_size.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/* -*- 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/ */
-
-"use strict";
-
-const TEST_URI = "http://example.com/";
-
-add_task(function* () {
-  yield loadTab(TEST_URI);
-  Services.prefs.setIntPref("devtools.webconsole.fontSize", 10);
-  let hud = yield HUDService.toggleBrowserConsole();
-
-  let inputNode = hud.jsterm.inputNode;
-  let outputNode = hud.jsterm.outputNode;
-  outputNode.focus();
-
-  EventUtils.synthesizeKey("-", { accelKey: true }, hud.iframeWindow);
-  is(inputNode.style.fontSize, "10px",
-     "input font stays at same size with ctrl+-");
-  is(outputNode.style.fontSize, inputNode.style.fontSize,
-     "output font stays at same size with ctrl+-");
-
-  EventUtils.synthesizeKey("=", { accelKey: true }, hud.iframeWindow);
-  is(inputNode.style.fontSize, "11px", "input font increased with ctrl+=");
-  is(outputNode.style.fontSize, inputNode.style.fontSize,
-     "output font stays at same size with ctrl+=");
-
-  EventUtils.synthesizeKey("-", { accelKey: true }, hud.iframeWindow);
-  is(inputNode.style.fontSize, "10px", "font decreased with ctrl+-");
-  is(outputNode.style.fontSize, inputNode.style.fontSize,
-     "output font stays at same size with ctrl+-");
-
-  EventUtils.synthesizeKey("0", { accelKey: true }, hud.iframeWindow);
-  is(inputNode.style.fontSize, "", "font reset with ctrl+0");
-  is(outputNode.style.fontSize, inputNode.style.fontSize,
-     "output font stays at same size with ctrl+0");
-});
--- a/devtools/client/webconsole/webconsole.js
+++ b/devtools/client/webconsole/webconsole.js
@@ -31,16 +31,18 @@ loader.lazyRequireGetter(this, "Environm
 loader.lazyRequireGetter(this, "ObjectClient", "devtools/shared/client/main", true);
 loader.lazyRequireGetter(this, "system", "devtools/shared/system");
 loader.lazyRequireGetter(this, "JSTerm", "devtools/client/webconsole/jsterm", true);
 loader.lazyRequireGetter(this, "gSequenceId", "devtools/client/webconsole/jsterm", true);
 loader.lazyImporter(this, "VariablesView", "resource://devtools/client/shared/widgets/VariablesView.jsm");
 loader.lazyImporter(this, "VariablesViewController", "resource://devtools/client/shared/widgets/VariablesViewController.jsm");
 loader.lazyRequireGetter(this, "gDevTools", "devtools/client/framework/devtools", true);
 loader.lazyImporter(this, "PluralForm", "resource://gre/modules/PluralForm.jsm");
+loader.lazyRequireGetter(this, "KeyShortcuts", "devtools/client/shared/key-shortcuts", true);
+loader.lazyRequireGetter(this, "ZoomKeys", "devtools/client/shared/zoom-keys");
 
 const STRINGS_URI = "chrome://devtools/locale/webconsole.properties";
 var l10n = new WebConsoleUtils.L10n(STRINGS_URI);
 
 const XHTML_NS = "http://www.w3.org/1999/xhtml";
 
 const MIXED_CONTENT_LEARN_MORE = "https://developer.mozilla.org/docs/Security/MixedContent";
 
@@ -516,51 +518,26 @@ WebConsoleFrame.prototype = {
     // Register the controller to handle "select all" properly.
     this._commandController = new CommandController(this);
     this.window.controllers.insertControllerAt(0, this._commandController);
 
     this._contextMenuHandler = new ConsoleContextMenu(this);
 
     let doc = this.document;
 
-    if (system.constants.platform === "macosx") {
-      doc.querySelector("#key_clearOSX").removeAttribute("disabled");
-    } else {
-      doc.querySelector("#key_clear").removeAttribute("disabled");
-    }
-
     this.filterBox = doc.querySelector(".hud-filter-box");
     this.outputNode = doc.getElementById("output-container");
     this.outputWrapper = doc.getElementById("output-wrapper");
 
     this.completeNode = doc.querySelector(".jsterm-complete-node");
     this.inputNode = doc.querySelector(".jsterm-input-node");
 
     this._setFilterTextBoxEvents();
     this._initFilterButtons();
 
-    let fontSize = this.owner._browserConsole ?
-                   Services.prefs.getIntPref("devtools.webconsole.fontSize") :
-                   0;
-
-    if (fontSize != 0) {
-      fontSize = Math.max(MIN_FONT_SIZE, fontSize);
-
-      this.outputNode.style.fontSize = fontSize + "px";
-      this.completeNode.style.fontSize = fontSize + "px";
-      this.inputNode.style.fontSize = fontSize + "px";
-    }
-
-    if (this.owner._browserConsole) {
-      for (let id of ["Enlarge", "Reduce", "Reset"]) {
-        this.document.getElementById("cmd_fullZoom" + id)
-                     .removeAttribute("disabled");
-      }
-    }
-
     // Update the character width and height needed for the popup offset
     // calculations.
     this._updateCharSize();
 
     let clearButton =
       doc.getElementsByClassName("webconsole-clear-console-button")[0];
     clearButton.addEventListener("command", () => {
       this.owner._onClearButton();
@@ -622,16 +599,18 @@ WebConsoleFrame.prototype = {
 
     // Toggle the timestamp on preference change
     gDevTools.on("pref-changed", this._onToolboxPrefChanged);
     this._onToolboxPrefChanged("pref-changed", {
       pref: PREF_MESSAGE_TIMESTAMP,
       newValue: Services.prefs.getBoolPref(PREF_MESSAGE_TIMESTAMP),
     });
 
+    this._initShortcuts();
+
     // focus input node
     this.jsterm.focus();
   },
 
   /**
    * Resizes the output node to fit the output wrapped.
    * We need this because it makes the layout a lot faster than
    * using -moz-box-flex and 100% width.  See Bug 1237368.
@@ -666,16 +645,44 @@ WebConsoleFrame.prototype = {
                  "serverwarn", "serverinfo", "serverlog"];
 
     for (let pref of prefs) {
       this.filterPrefs[pref] = Services.prefs.getBoolPref(
         this._filterPrefsPrefix + pref);
     }
   },
 
+  _initShortcuts: function() {
+    var shortcuts = new KeyShortcuts({
+      window: this.window
+    });
+
+    shortcuts.on(l10n.getStr("webconsole.find.key"),
+                 (name, event) => {
+                   this.filterBox.focus();
+                   event.preventDefault();
+                 });
+
+    let clearShortcut;
+    if (system.constants.platform === "macosx") {
+      clearShortcut = l10n.getStr("webconsole.clear.keyOSX");
+    } else {
+      clearShortcut = l10n.getStr("webconsole.clear.key");
+    }
+    shortcuts.on(clearShortcut,
+                 () => this.jsterm.clearOutput(true));
+
+    if (this.owner._browserConsole) {
+      shortcuts.on(l10n.getStr("webconsole.close.key"),
+                   this.window.close.bind(this.window));
+
+      ZoomKeys.register(this.window);
+    }
+  },
+
   /**
    * Attach / detach reflow listeners depending on the checked status
    * of the `CSS > Log` menuitem.
    *
    * @param function [callback=null]
    *        Optional function to invoke when the listener has been
    *        added/removed.
    */
@@ -794,60 +801,16 @@ WebConsoleFrame.prototype = {
 
       let serverLogging =
         this.document.querySelector("toolbarbutton[category=server]");
       serverLogging.removeAttribute("accesskey");
     }
   },
 
   /**
-   * Increase, decrease or reset the font size.
-   *
-   * @param string size
-   *        The size of the font change. Accepted values are "+" and "-".
-   *        An unmatched size assumes a font reset.
-   */
-  changeFontSize: function (size) {
-    let fontSize = this.window
-                   .getComputedStyle(this.outputNode, null)
-                   .getPropertyValue("font-size").replace("px", "");
-
-    if (this.outputNode.style.fontSize) {
-      fontSize = this.outputNode.style.fontSize.replace("px", "");
-    }
-
-    if (size == "+" || size == "-") {
-      fontSize = parseInt(fontSize, 10);
-
-      if (size == "+") {
-        fontSize += 1;
-      } else {
-        fontSize -= 1;
-      }
-
-      if (fontSize < MIN_FONT_SIZE) {
-        fontSize = MIN_FONT_SIZE;
-      }
-
-      Services.prefs.setIntPref("devtools.webconsole.fontSize", fontSize);
-      fontSize = fontSize + "px";
-
-      this.completeNode.style.fontSize = fontSize;
-      this.inputNode.style.fontSize = fontSize;
-      this.outputNode.style.fontSize = fontSize;
-    } else {
-      this.completeNode.style.fontSize = "";
-      this.inputNode.style.fontSize = "";
-      this.outputNode.style.fontSize = "";
-      Services.prefs.clearUserPref("devtools.webconsole.fontSize");
-    }
-    this._updateCharSize();
-  },
-
-  /**
    * Calculates the width and height of a single character of the input box.
    * This will be used in opening the popup at the correct offset.
    *
    * @private
    */
   _updateCharSize: function () {
     let doc = this.document;
     let tempLabel = doc.createElementNS(XHTML_NS, "span");
@@ -3044,61 +3007,36 @@ CommandController.prototype = {
       }
       case "cmd_copy": {
         // Only copy if we right-clicked the console and there's no selected
         // text. With text selected, we want to fall back onto the default
         // copy behavior.
         return this.owner._contextMenuHandler.lastClickedMessage &&
               !this.owner.output.getSelectedMessages(1)[0];
       }
-      case "consoleCmd_clearOutput":
       case "cmd_selectAll":
-      case "cmd_find":
         return true;
-      case "cmd_fontSizeEnlarge":
-      case "cmd_fontSizeReduce":
-      case "cmd_fontSizeReset":
-      case "cmd_close":
-        return this.owner.owner._browserConsole;
     }
     return false;
   },
 
   doCommand: function (command) {
     switch (command) {
       case "consoleCmd_openURL":
         this.openURL();
         break;
       case "consoleCmd_copyURL":
         this.copyURL();
         break;
-      case "consoleCmd_clearOutput":
-        this.owner.jsterm.clearOutput(true);
-        break;
       case "cmd_copy":
         this.copyLastClicked();
         break;
-      case "cmd_find":
-        this.owner.filterBox.focus();
-        break;
       case "cmd_selectAll":
         this.selectAll();
         break;
-      case "cmd_fontSizeEnlarge":
-        this.owner.changeFontSize("+");
-        break;
-      case "cmd_fontSizeReduce":
-        this.owner.changeFontSize("-");
-        break;
-      case "cmd_fontSizeReset":
-        this.owner.changeFontSize("");
-        break;
-      case "cmd_close":
-        this.owner.window.close();
-        break;
     }
   }
 };
 
 // ////////////////////////////////////////////////////////////////////////////
 // Web Console connection proxy
 // ////////////////////////////////////////////////////////////////////////////
 
--- a/devtools/client/webconsole/webconsole.xul
+++ b/devtools/client/webconsole/webconsole.xul
@@ -42,39 +42,18 @@ function goUpdateConsoleCommands() {
   <commandset id="consoleCommands"
               commandupdater="true"
               events="focus,select"
               oncommandupdate="goUpdateConsoleCommands();">
     <command id="consoleCmd_openURL"
              oncommand="goDoCommand('consoleCmd_openURL');"/>
     <command id="consoleCmd_copyURL"
              oncommand="goDoCommand('consoleCmd_copyURL');"/>
-    <command id="consoleCmd_clearOutput"
-             oncommand="goDoCommand('consoleCmd_clearOutput');"/>
-    <command id="cmd_find" oncommand="goDoCommand('cmd_find');"/>
-    <command id="cmd_fullZoomEnlarge" oncommand="goDoCommand('cmd_fontSizeEnlarge');" disabled="true"/>
-    <command id="cmd_fullZoomReduce" oncommand="goDoCommand('cmd_fontSizeReduce');" disabled="true"/>
-    <command id="cmd_fullZoomReset" oncommand="goDoCommand('cmd_fontSizeReset');" disabled="true"/>
-    <command id="cmd_close" oncommand="goDoCommand('cmd_close');" disabled="true"/>
   </commandset>
   <keyset id="consoleKeys">
-    <key id="key_fullZoomReduce" key="&fullZoomReduceCmd.commandkey;" command="cmd_fullZoomReduce" modifiers="accel"/>
-    <key key="&fullZoomReduceCmd.commandkey2;" command="cmd_fullZoomReduce" modifiers="accel"/>
-    <key id="key_fullZoomEnlarge" key="&fullZoomEnlargeCmd.commandkey;" command="cmd_fullZoomEnlarge" modifiers="accel"/>
-    <key key="&fullZoomEnlargeCmd.commandkey2;" command="cmd_fullZoomEnlarge" modifiers="accel"/>
-    <key key="&fullZoomEnlargeCmd.commandkey3;" command="cmd_fullZoomEnlarge" modifiers="accel"/>
-    <key id="key_fullZoomReset" key="&fullZoomResetCmd.commandkey;" command="cmd_fullZoomReset" modifiers="accel"/>
-    <key key="&fullZoomResetCmd.commandkey2;" command="cmd_fullZoomReset" modifiers="accel"/>
-    <key key="&findCmd.key;" command="cmd_find" modifiers="accel"/>
-    <key key="&closeCmd.key;" command="cmd_close" modifiers="accel"/>
-
-    <!-- The 'clear' key differs by plaform, so the correct one becomes
-         enabled in JS -->
-    <key id="key_clear" disabled="true" key="&clearOutputCtrl.key;" command="consoleCmd_clearOutput" modifiers="control shift"/>
-    <key id="key_clearOSX" disabled="true" key="&clearOutputCtrl.key;" command="consoleCmd_clearOutput" modifiers="control"/>
   </keyset>
   <keyset id="editMenuKeys"/>
 
   <popupset id="mainPopupSet">
     <menupopup id="output-contextmenu" onpopupshowing="goUpdateGlobalEditMenuItems()">
       <menuitem id="menu_openURL" label="&openURL.label;"
                 accesskey="&openURL.accesskey;" command="consoleCmd_openURL"
                 selection="network" selectionType="single"/>