Bug 1326937 - Provide HTML page when running new console frontend draft
authorBrian Grinstead <bgrinstead@mozilla.com>
Fri, 09 Jun 2017 09:42:34 -0700
changeset 591831 82d010215d155132f2cc05f4d73fa3c956c36f28
parent 591727 eca8d0ea03af1d2424550a037f714f14c0f7b1be
child 632639 9ca149501d52ee15f1295fa64aa1eb898d918ca6
push id63190
push userbgrinstead@mozilla.com
push dateFri, 09 Jun 2017 16:42:41 +0000
bugs1326937
milestone55.0a1
Bug 1326937 - Provide HTML page when running new console frontend MozReview-Commit-ID: JGuzrRNKEfZ
devtools/client/definitions.js
devtools/client/framework/toolbox-process-window.js
devtools/client/jar.mn
devtools/client/locales/en-US/webConsole.dtd
devtools/client/locales/en-US/webconsole.properties
devtools/client/webconsole/hudservice.js
devtools/client/webconsole/jsterm.js
devtools/client/webconsole/moz.build
devtools/client/webconsole/test/browser_console_open_or_focus.js
devtools/client/webconsole/webconsole-connection-proxy.js
devtools/client/webconsole/webconsole.js
devtools/client/webconsole/webconsole.xhtml
devtools/client/webconsole/webconsole.xul
testing/talos/talos/tests/devtools/addon/content/damp.js
--- a/devtools/client/definitions.js
+++ b/devtools/client/definitions.js
@@ -95,19 +95,20 @@ Tools.inspector = {
 };
 
 Tools.webConsole = {
   id: "webconsole",
   key: l10n("cmd.commandkey"),
   accesskey: l10n("webConsoleCmd.accesskey"),
   modifiers: Services.appinfo.OS == "Darwin" ? "accel,alt" : "accel,shift",
   ordinal: 2,
+  oldWebConsoleURL: "chrome://devtools/content/webconsole/webconsole.xul",
+  newWebConsoleURL: "chrome://devtools/content/webconsole/webconsole.xhtml",
   icon: "chrome://devtools/skin/images/tool-webconsole.svg",
   invertIconForDarkTheme: true,
-  url: "chrome://devtools/content/webconsole/webconsole.xul",
   label: l10n("ToolboxTabWebconsole.label"),
   menuLabel: l10n("MenuWebconsole.label"),
   panelLabel: l10n("ToolboxWebConsole.panelLabel"),
   get tooltip() {
     return l10n("ToolboxWebconsole.tooltip2",
     (osString == "Darwin" ? "Cmd+Opt+" : "Ctrl+Shift+") + this.key);
   },
   inMenu: true,
@@ -127,16 +128,31 @@ Tools.webConsole = {
     return true;
   },
 
   build: function (iframeWindow, toolbox) {
     return new WebConsolePanel(iframeWindow, toolbox);
   }
 };
 
+function switchWebconsole() {
+  if (Services.prefs.getBoolPref("devtools.webconsole.new-frontend-enabled")) {
+    Tools.webConsole.url = Tools.webConsole.newWebConsoleURL;
+  } else {
+    Tools.webConsole.url = Tools.webConsole.oldWebConsoleURL;
+  }
+}
+switchWebconsole();
+
+Services.prefs.addObserver(
+  "devtools.webconsole.new-frontend-enabled",
+  { observe: switchWebconsole }
+);
+
+
 Tools.jsdebugger = {
   id: "jsdebugger",
   key: l10n("debuggerMenu.commandkey"),
   accesskey: l10n("debuggerMenu.accesskey"),
   modifiers: osString == "Darwin" ? "accel,alt" : "accel,shift",
   ordinal: 3,
   icon: "chrome://devtools/skin/images/tool-debugger.svg",
   invertIconForDarkTheme: true,
--- a/devtools/client/framework/toolbox-process-window.js
+++ b/devtools/client/framework/toolbox-process-window.js
@@ -61,16 +61,17 @@ function setPrefDefaults() {
   Services.prefs.setBoolPref("devtools.inspector.showAllAnonymousContent", true);
   Services.prefs.setBoolPref("browser.dom.window.dump.enabled", true);
   Services.prefs.setBoolPref("devtools.command-button-noautohide.enabled", true);
   Services.prefs.setBoolPref("devtools.scratchpad.enabled", true);
   // Bug 1225160 - Using source maps with browser debugging can lead to a crash
   Services.prefs.setBoolPref("devtools.debugger.source-maps-enabled", false);
   Services.prefs.setBoolPref("devtools.debugger.new-debugger-frontend", true);
   Services.prefs.setBoolPref("devtools.debugger.client-source-maps-enabled", true);
+  Services.prefs.setBoolPref("devtools.webconsole.new-frontend-enabled", false);
 }
 
 window.addEventListener("load", function() {
   let cmdClose = document.getElementById("toolbox-cmd-close");
   cmdClose.addEventListener("command", onCloseCommand);
   setPrefDefaults();
   connect().catch(e => {
     let errorMessageContainer = document.getElementById("error-message-container");
--- a/devtools/client/jar.mn
+++ b/devtools/client/jar.mn
@@ -5,16 +5,17 @@
 devtools.jar:
 %   content devtools %content/
     content/shared/vendor/d3.js (shared/vendor/d3.js)
     content/shared/vendor/dagre-d3.js (shared/vendor/dagre-d3.js)
     content/shared/widgets/widgets.css (shared/widgets/widgets.css)
     content/netmonitor/src/assets/styles/netmonitor.css (netmonitor/src/assets/styles/netmonitor.css)
     content/shared/widgets/VariablesView.xul (shared/widgets/VariablesView.xul)
     content/netmonitor/index.html (netmonitor/index.html)
+    content/webconsole/webconsole.xhtml (webconsole/webconsole.xhtml)
     content/webconsole/webconsole.xul (webconsole/webconsole.xul)
     content/scratchpad/scratchpad.xul (scratchpad/scratchpad.xul)
     content/scratchpad/scratchpad.js (scratchpad/scratchpad.js)
     content/shared/splitview.css (shared/splitview.css)
     content/shared/theme-switching.js (shared/theme-switching.js)
     content/shared/frame-script-utils.js (shared/frame-script-utils.js)
     content/styleeditor/styleeditor.xul (styleeditor/styleeditor.xul)
     content/storage/storage.xul (storage/storage.xul)
@@ -144,16 +145,17 @@ devtools.jar:
     skin/images/command-eyedropper.svg (themes/images/command-eyedropper.svg)
     skin/images/command-rulers.svg (themes/images/command-rulers.svg)
     skin/images/command-measure.svg (themes/images/command-measure.svg)
     skin/images/command-noautohide.svg (themes/images/command-noautohide.svg)
     skin/markup.css (themes/markup.css)
     skin/images/editor-error.png (themes/images/editor-error.png)
     skin/images/breakpoint.svg (themes/images/breakpoint.svg)
     skin/webconsole.css (themes/webconsole.css)
+    skin/new-webconsole.css (themes/new-webconsole.css)
     skin/images/webconsole.svg (themes/images/webconsole.svg)
     skin/images/breadcrumbs-scrollbutton.png (themes/images/breadcrumbs-scrollbutton.png)
     skin/images/breadcrumbs-scrollbutton@2x.png (themes/images/breadcrumbs-scrollbutton@2x.png)
     skin/animationinspector.css (themes/animationinspector.css)
     skin/canvasdebugger.css (themes/canvasdebugger.css)
     skin/debugger.css (themes/debugger.css)
     skin/performance.css (themes/performance.css)
     skin/memory.css (themes/memory.css)
--- a/devtools/client/locales/en-US/webConsole.dtd
+++ b/devtools/client/locales/en-US/webConsole.dtd
@@ -4,17 +4,16 @@
 
 <!-- LOCALIZATION NOTE : FILE The correct localization of this file might be to
   - keep it in English, or another language commonly spoken among web developers.
   - You want to make that choice consistent across the developer tools.
   - A good criteria is the language in which you'd find the best
   - documentation on web development on the web. -->
 
 <!ENTITY window.title "Web Console">
-<!ENTITY browserConsole.title "Browser Console">
 
 <!-- LOCALIZATION NOTE (openURL.label): You can see this string in the Web
    - Console context menu. -->
 <!ENTITY openURL.label     "Open URL in New Tab">
 <!ENTITY openURL.accesskey "T">
 
 <!-- LOCALIZATION NOTE (btnPageNet.label): This string is used for the menu
   -  button that allows users to toggle the network logging output.
--- a/devtools/client/locales/en-US/webconsole.properties
+++ b/devtools/client/locales/en-US/webconsole.properties
@@ -4,16 +4,19 @@
 
 # LOCALIZATION NOTE
 # The correct localization of this file might be to keep it in
 # English, or another language commonly spoken among web developers.
 # You want to make that choice consistent across the developer tools.
 # A good criteria is the language in which you'd find the best
 # documentation on web development on the web.
 
+# LOCALIZATION NOTE (browserConsole.title): shown as the
+# title when opening the browser console popup
+browserConsole.title=Browser Console
 
 # LOCALIZATION NOTE (timestampFormat): %1$02S = hours (24-hour clock),
 # %2$02S = minutes, %3$02S = seconds, %4$03S = milliseconds.
 timestampFormat=%02S:%02S:%02S.%03S
 
 helperFuncUnsupportedTypeError=Can’t call pprint on this type of object.
 
 # LOCALIZATION NOTE (NetworkPanel.deltaDurationMS): this string is used to
--- a/devtools/client/webconsole/hudservice.js
+++ b/devtools/client/webconsole/hudservice.js
@@ -11,16 +11,17 @@ var { extend } = require("sdk/core/herit
 var {TargetFactory} = require("devtools/client/framework/target");
 var {Tools} = require("devtools/client/definitions");
 const { Task } = require("devtools/shared/task");
 var promise = require("promise");
 var Services = require("Services");
 
 loader.lazyRequireGetter(this, "Telemetry", "devtools/client/shared/telemetry");
 loader.lazyRequireGetter(this, "WebConsoleFrame", "devtools/client/webconsole/webconsole", true);
+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/main", true);
 loader.lazyRequireGetter(this, "showDoorhanger", "devtools/client/shared/doorhanger", true);
 loader.lazyRequireGetter(this, "viewSource", "devtools/client/shared/view-source");
 
 const l10n = require("devtools/client/webconsole/webconsole-l10n");
 
@@ -205,23 +206,23 @@ HUD_SERVICE.prototype =
     }
 
     function openWindow(aTarget)
     {
       target = aTarget;
 
       let deferred = promise.defer();
 
-      let win = Services.ww.openWindow(null, Tools.webConsole.url, "_blank",
+      // Using the old frontend for now in the browser console.  This can be switched to
+      // Tools.webConsole.url to use whatever is preffed on.
+      let url = Tools.webConsole.oldWebConsoleURL;
+      let win = Services.ww.openWindow(null, url, "_blank",
                                        BROWSER_CONSOLE_WINDOW_FEATURES, null);
       win.addEventListener("DOMContentLoaded", function () {
-        // Set the correct Browser Console title.
-        let root = win.document.documentElement;
-        root.setAttribute("title", root.getAttribute("browserConsoleTitle"));
-
+          win.document.title = l10n.getStr("browserConsole.title");
         deferred.resolve(win);
       }, {once: true});
 
       return deferred.promise;
     }
 
     connect().then(getTarget).then(openWindow).then((aWindow) => {
       return this.openBrowserConsole(target, aWindow, aWindow)
@@ -289,17 +290,21 @@ function WebConsole(aTarget, aIframeWind
 
   this.browserWindow = this.chromeWindow.top;
 
   let element = this.browserWindow.document.documentElement;
   if (element.getAttribute("windowtype") != gDevTools.chromeWindowType) {
     this.browserWindow = HUDService.currentContext();
   }
 
-  this.ui = new WebConsoleFrame(this);
+  if (aIframeWindow.location.href === Tools.webConsole.newWebConsoleURL) {
+    this.ui = new NewWebConsoleFrame(this);
+  } else {
+    this.ui = new WebConsoleFrame(this);
+  }
 }
 
 WebConsole.prototype = {
   iframeWindow: null,
   chromeWindow: null,
   browserWindow: null,
   hudId: null,
   target: null,
--- a/devtools/client/webconsole/jsterm.js
+++ b/devtools/client/webconsole/jsterm.js
@@ -256,16 +256,20 @@ JSTerm.prototype = {
     // The popup will be attached to the toolbox document or HUD document in the case
     // such as the browser console which doesn't have a toolbox.
     this.autocompletePopup = new AutocompletePopup(tooltipDoc, autocompleteOptions);
 
     let inputContainer = doc.querySelector(".jsterm-input-container");
     this.completeNode = doc.querySelector(".jsterm-complete-node");
     this.inputNode = doc.querySelector(".jsterm-input-node");
 
+    // Update the character width and height needed for the popup offset
+    // calculations.
+    this._updateCharSize();
+
     if (this.hud.isBrowserConsole &&
         !Services.prefs.getBoolPref("devtools.chrome.enabled")) {
       inputContainer.style.display = "none";
     } else {
       let okstring = l10n.getStr("selfxss.okstring");
       let msg = l10n.getFormatStr("selfxss.msg", [okstring]);
       this._onPaste = WebConsoleUtils.pasteHandlerGen(
         this.inputNode, doc.getElementById("webconsole-notificationbox"),
@@ -935,38 +939,40 @@ JSTerm.prototype = {
    * This method emits the "messages-cleared" notification.
    *
    * @param boolean clearStorage
    *        True if you want to clear the console messages storage associated to
    *        this Web Console.
    */
   clearOutput: function (clearStorage) {
     let hud = this.hud;
-    let outputNode = hud.outputNode;
-    let node;
-    while ((node = outputNode.firstChild)) {
-      hud.removeOutputMessage(node);
+
+    if (hud.NEW_CONSOLE_OUTPUT_ENABLED) {
+      hud.newConsoleOutput.dispatchMessagesClear();
+    } else {
+      let outputNode = hud.outputNode;
+      let node;
+      while ((node = outputNode.firstChild)) {
+        hud.removeOutputMessage(node);
+      }
+
+      hud.groupDepth = 0;
+      hud._outputQueue.forEach(hud._destroyItem, hud);
+      hud._outputQueue = [];
+      hud._repeatNodes = {};
     }
 
-    hud.groupDepth = 0;
-    hud._outputQueue.forEach(hud._destroyItem, hud);
-    hud._outputQueue = [];
     this.webConsoleClient.clearNetworkRequests();
-    hud._repeatNodes = {};
 
     if (clearStorage) {
       this.webConsoleClient.clearMessagesCache();
     }
 
     this._sidebarDestroy();
 
-    if (hud.NEW_CONSOLE_OUTPUT_ENABLED) {
-      hud.newConsoleOutput.dispatchMessagesClear();
-    }
-
     this.emit("messages-cleared");
   },
 
   /**
    * Remove all of the private messages from the Web Console output.
    *
    * This method emits the "private-messages-cleared" notification.
    */
@@ -1583,18 +1589,18 @@ JSTerm.prototype = {
     this.lastCompletion = {
       value: inputValue,
       matchProp: lastPart,
     };
 
     if (items.length > 1 && !popup.isOpen) {
       let str = this.getInputValue().substr(0, this.inputNode.selectionStart);
       let offset = str.length - (str.lastIndexOf("\n") + 1) - lastPart.length;
-      let x = offset * this.hud._inputCharWidth;
-      popup.openPopup(inputNode, x + this.hud._chevronWidth);
+      let x = offset * this._inputCharWidth;
+      popup.openPopup(inputNode, x + this._chevronWidth);
       this._autocompletePopupNavigated = false;
     } else if (items.length < 2 && popup.isOpen) {
       popup.hidePopup();
       this._autocompletePopupNavigated = false;
     }
 
     if (items.length == 1) {
       popup.selectedIndex = 0;
@@ -1686,16 +1692,42 @@ JSTerm.prototype = {
    */
   updateCompleteNode: function (suffix) {
     // completion prefix = input, with non-control chars replaced by spaces
     let prefix = suffix ? this.getInputValue().replace(/[\S]/g, " ") : "";
     this.completeNode.value = prefix + suffix;
   },
 
   /**
+   * 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.hud.document;
+    let tempLabel = doc.createElementNS(XHTML_NS, "span");
+    let style = tempLabel.style;
+    style.position = "fixed";
+    style.padding = "0";
+    style.margin = "0";
+    style.width = "auto";
+    style.color = "transparent";
+    WebConsoleUtils.copyTextStyles(this.inputNode, tempLabel);
+    tempLabel.textContent = "x";
+    doc.documentElement.appendChild(tempLabel);
+    this._inputCharWidth = tempLabel.offsetWidth;
+    tempLabel.remove();
+    // Calculate the width of the chevron placed at the beginning of the input
+    // box. Remove 4 more pixels to accomodate the padding of the popup.
+    this._chevronWidth = +doc.defaultView.getComputedStyle(this.inputNode)
+                             .paddingLeft.replace(/[^0-9.]/g, "") - 4;
+  },
+
+  /**
    * Destroy the sidebar.
    * @private
    */
   _sidebarDestroy: function () {
     if (this._variablesView) {
       this._variablesView.controller.releaseActors();
       this._variablesView = null;
     }
--- a/devtools/client/webconsole/moz.build
+++ b/devtools/client/webconsole/moz.build
@@ -11,16 +11,17 @@ DIRS += [
     'new-console-output',
 ]
 
 DevToolsModules(
     'console-commands.js',
     'console-output.js',
     'hudservice.js',
     'jsterm.js',
+    'new-webconsole.js',
     'panel.js',
     'utils.js',
     'webconsole-connection-proxy.js',
     'webconsole-l10n.js',
     'webconsole.js',
 )
 
 with Files('**'):
--- a/devtools/client/webconsole/test/browser_console_open_or_focus.js
+++ b/devtools/client/webconsole/test/browser_console_open_or_focus.js
@@ -23,24 +23,24 @@ add_task(function* () {
   yield waitForMessages({
     webconsole: hud,
     messages: [{
       text: "testmessage"
     }],
   });
 
   currWindow = Services.wm.getMostRecentWindow(null);
-  is(currWindow.document.documentURI, Tools.webConsole.url,
+  is(currWindow.document.documentURI, Tools.webConsole.oldWebConsoleURL,
      "The Browser Console is open and has focus");
 
   mainWindow.focus();
 
   yield HUDService.openBrowserConsoleOrFocus();
 
   currWindow = Services.wm.getMostRecentWindow(null);
-  is(currWindow.document.documentURI, Tools.webConsole.url,
+  is(currWindow.document.documentURI, Tools.webConsole.oldWebConsoleURL,
      "The Browser Console is open and has focus");
 
   yield HUDService.toggleBrowserConsole();
 
   hud = HUDService.getBrowserConsole();
   ok(!hud, "Browser Console has been closed");
 });
--- a/devtools/client/webconsole/webconsole-connection-proxy.js
+++ b/devtools/client/webconsole/webconsole-connection-proxy.js
@@ -282,21 +282,22 @@ WebConsoleConnectionProxy.prototype = {
    *
    * @private
    * @param string type
    *        Message type.
    * @param object packet
    *        The message received from the server.
    */
   _onPageError: function (type, packet) {
-    if (this.webConsoleFrame && packet.from == this._consoleActor) {
-      if (this.webConsoleFrame.NEW_CONSOLE_OUTPUT_ENABLED) {
-        this.dispatchMessageAdd(packet);
-        return;
-      }
+    if (!this.webConsoleFrame || packet.from != this._consoleActor) {
+      return;
+    }
+    if (this.webConsoleFrame.NEW_CONSOLE_OUTPUT_ENABLED) {
+      this.dispatchMessageAdd(packet);
+    } else {
       this.webConsoleFrame.handlePageError(packet.pageError);
     }
   },
 
   /**
    * The "logMessage" message type handler. We redirect any message to the UI
    * for displaying.
    *
@@ -305,17 +306,16 @@ WebConsoleConnectionProxy.prototype = {
    *        Message type.
    * @param object packet
    *        The message received from the server.
    */
   _onLogMessage: function (type, packet) {
     if (!this.webConsoleFrame || packet.from != this._consoleActor) {
       return;
     }
-
     if (this.webConsoleFrame.NEW_CONSOLE_OUTPUT_ENABLED) {
       this.dispatchMessageAdd(packet);
     } else {
       this.webConsoleFrame.handleLogMessage(packet);
     }
   },
 
   /**
@@ -324,99 +324,118 @@ WebConsoleConnectionProxy.prototype = {
    *
    * @private
    * @param string type
    *        Message type.
    * @param object packet
    *        The message received from the server.
    */
   _onConsoleAPICall: function (type, packet) {
-    if (this.webConsoleFrame && packet.from == this._consoleActor) {
-      if (this.webConsoleFrame.NEW_CONSOLE_OUTPUT_ENABLED) {
-        this.dispatchMessageAdd(packet);
-      } else {
-        this.webConsoleFrame.handleConsoleAPICall(packet.message);
-      }
+    if (!this.webConsoleFrame || packet.from != this._consoleActor) {
+      return;
+    }
+    if (this.webConsoleFrame.NEW_CONSOLE_OUTPUT_ENABLED) {
+      this.dispatchMessageAdd(packet);
+    } else {
+      this.webConsoleFrame.handleConsoleAPICall(packet.message);
     }
   },
 
   /**
    * The "networkEvent" message type handler. We redirect any message to
    * the UI for displaying.
    *
    * @private
    * @param string type
    *        Message type.
    * @param object networkInfo
    *        The network request information.
    */
   _onNetworkEvent: function (type, networkInfo) {
-    if (this.webConsoleFrame) {
-      if (this.webConsoleFrame.NEW_CONSOLE_OUTPUT_ENABLED) {
-        this.dispatchMessageAdd(networkInfo);
-      } else {
-        this.webConsoleFrame.handleNetworkEvent(networkInfo);
-      }
+    if (!this.webConsoleFrame) {
+      return;
+    }
+    if (this.webConsoleFrame.NEW_CONSOLE_OUTPUT_ENABLED) {
+      this.dispatchMessageAdd(networkInfo);
+    } else {
+      this.webConsoleFrame.handleNetworkEvent(networkInfo);
     }
   },
 
   /**
    * The "networkEventUpdate" message type handler. We redirect any message to
    * the UI for displaying.
    *
    * @private
    * @param string type
    *        Message type.
    * @param object response
    *        The update response received from the server.
    */
   _onNetworkEventUpdate: function (type, response) {
+    if (!this.webConsoleFrame) {
+      return;
+    }
     let { packet, networkInfo } = response;
-    if (this.webConsoleFrame) {
-      if (this.webConsoleFrame.NEW_CONSOLE_OUTPUT_ENABLED) {
-        this.dispatchMessageUpdate(networkInfo, response);
-      }
+    if (this.webConsoleFrame.NEW_CONSOLE_OUTPUT_ENABLED) {
+      this.dispatchMessageUpdate(networkInfo, response);
+    } else {
       this.webConsoleFrame.handleNetworkEventUpdate(networkInfo, packet);
     }
   },
 
   /**
    * The "fileActivity" message type handler. We redirect any message to
    * the UI for displaying.
    *
    * @private
    * @param string type
    *        Message type.
    * @param object packet
    *        The message received from the server.
    */
   _onFileActivity: function (type, packet) {
-    if (this.webConsoleFrame && packet.from == this._consoleActor) {
+    if (!this.webConsoleFrame || packet.from != this._consoleActor) {
+      return;
+    }
+    if (this.webConsoleFrame.NEW_CONSOLE_OUTPUT_ENABLED) {
+      // TODO: Implement for new console
+    } else {
       this.webConsoleFrame.handleFileActivity(packet.uri);
     }
   },
 
   _onReflowActivity: function (type, packet) {
-    if (this.webConsoleFrame && packet.from == this._consoleActor) {
+    if (!this.webConsoleFrame || packet.from != this._consoleActor) {
+      return;
+    }
+    if (this.webConsoleFrame.NEW_CONSOLE_OUTPUT_ENABLED) {
+      // TODO: Implement for new console
+    } else {
       this.webConsoleFrame.handleReflowActivity(packet);
     }
   },
 
   /**
    * The "serverLogCall" message type handler. We redirect any message to
    * the UI for displaying.
    *
    * @private
    * @param string type
    *        Message type.
    * @param object packet
    *        The message received from the server.
    */
   _onServerLogCall: function (type, packet) {
-    if (this.webConsoleFrame && packet.from == this._consoleActor) {
+    if (!this.webConsoleFrame || packet.from != this._consoleActor) {
+      return;
+    }
+    if (this.webConsoleFrame.NEW_CONSOLE_OUTPUT_ENABLED) {
+      // TODO: Implement for new console
+    } else {
       this.webConsoleFrame.handleConsoleAPICall(packet.message);
     }
   },
 
   /**
    * The "lastPrivateContextExited" message type handler. When this message is
    * received the Web Console UI is cleared.
    *
--- a/devtools/client/webconsole/webconsole.js
+++ b/devtools/client/webconsole/webconsole.js
@@ -543,20 +543,16 @@ WebConsoleFrame.prototype = {
     this.outputWrapper = this.document.getElementById("output-wrapper");
     this.completeNode = this.document.querySelector(".jsterm-complete-node");
     this.inputNode = this.document.querySelector(".jsterm-input-node");
 
     // In the old frontend, the area that scrolls is outputWrapper, but in the new
     // frontend this will be reassigned.
     this.outputScroller = this.outputWrapper;
 
-    // Update the character width and height needed for the popup offset
-    // calculations.
-    this._updateCharSize();
-
     this.jsterm = new JSTerm(this);
     this.jsterm.init();
 
     let toolbox = gDevTools.getToolbox(this.owner.target);
 
     if (this.NEW_CONSOLE_OUTPUT_ENABLED) {
       // @TODO Remove this once JSTerm is handled with React/Redux.
       this.window.jsterm = this.jsterm;
@@ -840,42 +836,16 @@ WebConsoleFrame.prototype = {
 
       let serverLogging =
         this.document.querySelector("toolbarbutton[category=server]");
       serverLogging.removeAttribute("accesskey");
     }
   },
 
   /**
-   * 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");
-    let style = tempLabel.style;
-    style.position = "fixed";
-    style.padding = "0";
-    style.margin = "0";
-    style.width = "auto";
-    style.color = "transparent";
-    WebConsoleUtils.copyTextStyles(this.inputNode, tempLabel);
-    tempLabel.textContent = "x";
-    doc.documentElement.appendChild(tempLabel);
-    this._inputCharWidth = tempLabel.offsetWidth;
-    tempLabel.remove();
-    // Calculate the width of the chevron placed at the beginning of the input
-    // box. Remove 4 more pixels to accomodate the padding of the popup.
-    this._chevronWidth = +doc.defaultView.getComputedStyle(this.inputNode)
-                             .paddingLeft.replace(/[^0-9.]/g, "") - 4;
-  },
-
-  /**
    * The event handler that is called whenever a user switches a filter on or
    * off.
    *
    * @private
    * @param nsIDOMEvent event
    *        The event that triggered the filter change.
    */
   _toggleFilter: function (event) {
new file mode 100644
--- /dev/null
+++ b/devtools/client/webconsole/webconsole.xhtml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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/. -->
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" dir="">
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+    <link rel="stylesheet" href="chrome://devtools/skin/new-webconsole.css"/>
+    <script src="chrome://devtools/content/shared/theme-switching.js"></script>
+    <script type="application/javascript"
+            src="resource://devtools/client/webconsole/new-console-output/main.js"/>
+  </head>
+  <body class="theme-sidebar" role="application">
+    <div id="app-wrapper" class="theme-body">
+      <div id="output-container" role="document" aria-live="polite" />
+      <div id="jsterm-wrapper">
+        <xul:notificationbox id="webconsole-notificationbox">
+          <div class="jsterm-input-container" style="direction:ltr">
+            <xul:stack class="jsterm-stack-node" flex="1">
+              <xul:textbox class="jsterm-complete-node devtools-monospace"
+                       multiline="true" rows="1" tabindex="-1"/>
+              <xul:textbox class="jsterm-input-node devtools-monospace"
+                       multiline="true" rows="1" tabindex="0"
+                       aria-autocomplete="list"/>
+            </xul:stack>
+          </div>
+        </xul:notificationbox>
+      </div>
+    </div>
+  </body>
+</html>
--- a/devtools/client/webconsole/webconsole.xul
+++ b/devtools/client/webconsole/webconsole.xul
@@ -14,17 +14,16 @@
 <?xml-stylesheet href="chrome://devtools/skin/components-frame.css"
                  type="text/css"?>
 <?xul-overlay href="chrome://global/content/editMenuOverlay.xul"?>
 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         id="devtools-webconsole"
         macanimationtype="document"
         fullscreenbutton="true"
         title="&window.title;"
-        browserConsoleTitle="&browserConsole.title;"
         windowtype="devtools:webconsole"
         width="900" height="350"
         persist="screenX screenY width height sizemode">
 
   <script type="application/javascript"
           src="chrome://devtools/content/shared/theme-switching.js"/>
   <script type="application/javascript"
           src="resource://devtools/client/webconsole/new-console-output/main.js"/>
--- a/testing/talos/talos/tests/devtools/addon/content/damp.js
+++ b/testing/talos/talos/tests/devtools/addon/content/damp.js
@@ -17,17 +17,17 @@ const COMPLICATED_URL = webserver + "/te
 function Damp() {
   // Path to the temp file where the heap snapshot file is saved. Set by
   // saveHeapSnapshot and read by readHeapSnapshot.
   this._heapSnapshotFilePath = null;
   // HeapSnapshot instance. Set by readHeapSnapshot, used by takeCensus.
   this._snapshot = null;
 
   // Use the old console for now: https://bugzilla.mozilla.org/show_bug.cgi?id=1306780
-  Services.prefs.setBoolPref("devtools.webconsole.new-frontend-enabled", false);
+  // Services.prefs.setBoolPref("devtools.webconsole.new-frontend-enabled", false);
 }
 
 Damp.prototype = {
 
   addTab: function(url) {
     return new Promise((resolve, reject) => {
       let tab = this._win.gBrowser.selectedTab = this._win.gBrowser.addTab(url);
       let browser = tab.linkedBrowser;