Bug 1256768 - Fix ESLint errors/warnings in devtools/client/webconsole/console-output.js r=nchevobbe
authorMichael Kohler <mkohler@picobudget.com>
Sat, 20 May 2017 22:54:41 +0200
changeset 361136 1e3fcd5eb06d42e39f80a3db242026c64c4485e2
parent 361135 54d7b5816adb8f926f0f0ae62f13380778e73f55
child 361137 99de7cf38c1289a33f92f848185a165eedb75880
push id90813
push usercbook@mozilla.com
push dateTue, 30 May 2017 09:53:44 +0000
treeherdermozilla-inbound@b5c3bb245c4e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnchevobbe
bugs1256768
milestone55.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 1256768 - Fix ESLint errors/warnings in devtools/client/webconsole/console-output.js r=nchevobbe MozReview-Commit-ID: 76jPTnoqWq7
.eslintignore
devtools/client/webconsole/console-output.js
--- a/.eslintignore
+++ b/.eslintignore
@@ -116,17 +116,16 @@ devtools/client/storage/test/*.html
 !devtools/client/storage/test/storage-cookies.html
 !devtools/client/storage/test/storage-overflow.html
 !devtools/client/storage/test/storage-search.html
 !devtools/client/storage/test/storage-unsecured-iframe.html
 !devtools/client/storage/test/storage-unsecured-iframe-usercontextid.html
 devtools/client/webaudioeditor/**
 devtools/client/webconsole/net/**
 devtools/client/webconsole/test/**
-devtools/client/webconsole/console-output.js
 devtools/client/webconsole/hudservice.js
 devtools/client/webconsole/webconsole-connection-proxy.js
 devtools/client/webconsole/webconsole.js
 devtools/client/webide/**
 !devtools/client/webide/components/webideCli.js
 devtools/server/tests/browser/storage-*.html
 !devtools/server/tests/browser/storage-unsecured-iframe.html
 devtools/server/tests/browser/stylesheets-nested-iframes.html
--- a/devtools/client/webconsole/console-output.js
+++ b/devtools/client/webconsole/console-output.js
@@ -1,29 +1,28 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* 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 {Ci, Cu} = require("chrome");
+const {Ci} = require("chrome");
 
 loader.lazyImporter(this, "VariablesView", "resource://devtools/client/shared/widgets/VariablesView.jsm");
 loader.lazyImporter(this, "escapeHTML", "resource://devtools/client/shared/widgets/VariablesView.jsm");
 
 loader.lazyRequireGetter(this, "promise");
 loader.lazyRequireGetter(this, "gDevTools", "devtools/client/framework/devtools", true);
 loader.lazyRequireGetter(this, "TableWidget", "devtools/client/shared/widgets/TableWidget", true);
 loader.lazyRequireGetter(this, "ObjectClient", "devtools/shared/client/main", true);
 
 const { extend } = require("sdk/core/heritage");
 const XHTML_NS = "http://www.w3.org/1999/xhtml";
-const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
 
 const WebConsoleUtils = require("devtools/client/webconsole/utils").Utils;
 const { getSourceNames } = require("devtools/client/shared/source-utils");
 const {Task} = require("devtools/shared/task");
 const l10n = require("devtools/client/webconsole/webconsole-l10n");
 const nodeConstants = require("devtools/shared/dom-node-constants");
 const {PluralForm} = require("devtools/shared/plural-form");
 
@@ -113,17 +112,21 @@ const CONSOLE_API_LEVELS_TO_SEVERITIES =
 // Array of known message source URLs we need to hide from output.
 const IGNORED_SOURCE_URLS = ["debugger eval code"];
 
 // The maximum length of strings to be displayed by the Web Console.
 const MAX_LONG_STRING_LENGTH = 200000;
 
 // Regular expression that matches the allowed CSS property names when using
 // the `window.console` API.
-const RE_ALLOWED_STYLES = /^(?:-moz-)?(?:background|border|box|clear|color|cursor|display|float|font|line|margin|padding|text|transition|outline|white-space|word|writing|(?:min-|max-)?width|(?:min-|max-)?height)/;
+const RE_ALLOWED_STYLES = new RegExp(["^(?:-moz-)?(?:background|border|box|clear|" +
+                                      "color|cursor|display|float|font|line|margin|" +
+                                      "padding|text|transition|outline|white-space|" +
+                                      "word|writing|(?:min-|max-)?width|" +
+                                      "(?:min-|max-)?height)"]);
 
 // Regular expressions to search and replace with 'notallowed' in the styles
 // given to the `window.console` API methods.
 const RE_CLEANUP_STYLES = [
   // url(), -moz-element()
   /\b(?:url|(?:-moz-)?element)[\s('"]+/gi,
 
   // various URL protocols
@@ -145,18 +148,17 @@ const TABLE_COLUMN_MAX_ITEMS = 10;
  *        The console output owner. This usually the WebConsoleFrame instance.
  *        Any other object can be used, as long as it has the following
  *        properties and methods:
  *          - window
  *          - document
  *          - outputMessage(category, methodOrNode[, methodArguments])
  *            TODO: this is needed temporarily, until bug 778766 is fixed.
  */
-function ConsoleOutput(owner)
-{
+function ConsoleOutput(owner) {
   this.owner = owner;
   this._onFlushOutputMessage = this._onFlushOutputMessage.bind(this);
 }
 
 ConsoleOutput.prototype = {
   _dummyElement: null,
 
   /**
@@ -201,30 +203,28 @@ ConsoleOutput.prototype = {
 
   /**
    * Release an actor.
    *
    * @private
    * @param string actorId
    *        The actor ID you want to release.
    */
-  _releaseObject: function (actorId)
-  {
+  _releaseObject: function (actorId) {
     this.owner._releaseObject(actorId);
   },
 
   /**
    * Add a message to output.
    *
    * @param object ...args
    *        Any number of Message objects.
    * @return this
    */
-  addMessage: function (...args)
-  {
+  addMessage: function (...args) {
     for (let msg of args) {
       msg.init(this);
       this.owner.outputMessage(msg._categoryCompat, this._onFlushOutputMessage,
                                [msg]);
     }
     return this;
   },
 
@@ -237,33 +237,31 @@ ConsoleOutput.prototype = {
    * TODO: remove this method once bug 778766 is fixed.
    *
    * @private
    * @param object message
    *        The message object to render.
    * @return DOMElement
    *         The message DOM element that can be added to the console output.
    */
-  _onFlushOutputMessage: function (message)
-  {
+  _onFlushOutputMessage: function (message) {
     return message.render().element;
   },
 
   /**
    * Get an array of selected messages. This list is based on the text selection
    * start and end points.
    *
    * @param number [limit]
    *        Optional limit of selected messages you want. If no value is given,
    *        all of the selected messages are returned.
    * @return array
    *         Array of DOM elements for each message that is currently selected.
    */
-  getSelectedMessages: function (limit)
-  {
+  getSelectedMessages: function (limit) {
     let selection = this.window.getSelection();
     if (selection.isCollapsed) {
       return [];
     }
 
     if (selection.containsNode(this.element, true)) {
       return Array.slice(this.element.children);
     }
@@ -298,81 +296,75 @@ ConsoleOutput.prototype = {
   /**
    * Find the DOM element of a message for any given descendant.
    *
    * @param DOMElement elem
    *        The element to start the search from.
    * @return DOMElement|null
    *         The DOM element of the message, if any.
    */
-  getMessageForElement: function (elem)
-  {
+  getMessageForElement: function (elem) {
     while (elem && elem.parentNode) {
       if (elem.classList && elem.classList.contains("message")) {
         return elem;
       }
       elem = elem.parentNode;
     }
     return null;
   },
 
   /**
    * Select all messages.
    */
-  selectAllMessages: function ()
-  {
+  selectAllMessages: function () {
     let selection = this.window.getSelection();
     selection.removeAllRanges();
     let range = this.document.createRange();
     range.selectNodeContents(this.element);
     selection.addRange(range);
   },
 
   /**
    * Add a message to the selection.
    *
    * @param DOMElement elem
    *        The message element to select.
    */
-  selectMessage: function (elem)
-  {
+  selectMessage: function (elem) {
     let selection = this.window.getSelection();
     selection.removeAllRanges();
     let range = this.document.createRange();
     range.selectNodeContents(elem);
     selection.addRange(range);
   },
 
   /**
    * Open an URL in a new tab.
    * @see WebConsole.openLink() in hudservice.js
    */
-  openLink: function ()
-  {
+  openLink: function () {
     this.owner.owner.openLink.apply(this.owner.owner, arguments);
   },
 
   openLocationInDebugger: function ({url, line}) {
     return this.owner.owner.viewSourceInDebugger(url, line);
   },
 
   /**
    * Open the variables view to inspect an object actor.
    * @see JSTerm.openVariablesView() in webconsole.js
    */
-  openVariablesView: function ()
-  {
+  openVariablesView: function () {
     this.owner.jsterm.openVariablesView.apply(this.owner.jsterm, arguments);
   },
 
   /**
    * Destroy this ConsoleOutput instance.
    */
-  destroy: function ()
-  {
+  destroy: function () {
     this._dummyElement = null;
     this.owner = null;
   },
 }; // ConsoleOutput.prototype
 
 /**
  * Message objects container.
  * @type object
@@ -380,18 +372,17 @@ ConsoleOutput.prototype = {
 var Messages = {};
 
 /**
  * The BaseMessage object is used for all types of messages. Every kind of
  * message should use this object as its base.
  *
  * @constructor
  */
-Messages.BaseMessage = function ()
-{
+Messages.BaseMessage = function () {
   this.widgets = new Set();
   this._onClickAnchor = this._onClickAnchor.bind(this);
   this._repeatID = { uid: gSequenceId() };
   this.textContent = "";
 };
 
 Messages.BaseMessage.prototype = {
   /**
@@ -466,58 +457,54 @@ Messages.BaseMessage.prototype = {
    * Initialize the message.
    *
    * @param object output
    *        The ConsoleOutput owner.
    * @param object [parent=null]
    *        Optional: a different message object that owns this instance.
    * @return this
    */
-  init: function (output, parent = null)
-  {
+  init: function (output, parent = null) {
     this.output = output;
     this.parent = parent;
     return this;
   },
 
   /**
    * Non-unique ID for this message object used for tracking duplicate messages.
    * Different message kinds can identify themselves based their own criteria.
    *
    * @return string
    */
-  getRepeatID: function ()
-  {
+  getRepeatID: function () {
     return JSON.stringify(this._repeatID);
   },
 
   /**
    * Render the message. After this method is invoked the |element| property
    * will point to the DOM element of this message.
    * @return this
    */
-  render: function ()
-  {
+  render: function () {
     if (!this.element) {
       this.element = this._renderCompat();
     }
     return this;
   },
 
   /**
    * Prepare the message container for the Web Console, such that it is
    * compatible with the current implementation.
    * TODO: remove this once bug 778766 is fixed.
    *
    * @private
    * @return Element
    *         The DOM element that wraps the message.
    */
-  _renderCompat: function ()
-  {
+  _renderCompat: function () {
     let doc = this.output.document;
     let container = doc.createElementNS(XHTML_NS, "div");
     container.id = "console-msg-" + gSequenceId();
     container.className = "message";
     if (this.category == "input") {
       // Assistive technology tools shouldn't echo input to the user,
       // as the user knows what they've just typed.
       container.setAttribute("aria-live", "off");
@@ -539,41 +526,38 @@ Messages.BaseMessage.prototype = {
    *
    * @private
    * @param Element element
    *        The DOM element to which you want to add a click event handler.
    * @param function [callback=this._onClickAnchor]
    *        Optional click event handler. The default event handler is
    *        |this._onClickAnchor|.
    */
-  _addLinkCallback: function (element, callback = this._onClickAnchor)
-  {
+  _addLinkCallback: function (element, callback = this._onClickAnchor) {
     // This is going into the WebConsoleFrame object instance that owns
     // the ConsoleOutput object. The WebConsoleFrame owner is the WebConsole
     // object instance from hudservice.js.
     // TODO: move _addMessageLinkCallback() into ConsoleOutput once bug 778766
     // is fixed.
     this.output.owner._addMessageLinkCallback(element, callback);
   },
 
   /**
    * The default |click| event handler for links in the output. This function
    * opens the anchor's link in a new tab.
    *
    * @private
    * @param Event event
    *        The DOM event that invoked this function.
    */
-  _onClickAnchor: function (event)
-  {
+  _onClickAnchor: function (event) {
     this.output.openLink(event.target.href);
   },
 
-  destroy: function ()
-  {
+  destroy: function () {
     // Destroy all widgets that have registered themselves in this.widgets
     for (let widget of this.widgets) {
       widget.destroy();
     }
     this.widgets.clear();
   }
 };
 
@@ -816,18 +800,17 @@ Messages.Simple.prototype = extend(Messa
   },
 
   get _filterKeyCompat() {
     return this._categoryCompat !== null && this._severityCompat !== null ?
            COMPAT.PREFERENCE_KEYS[this._categoryCompat][this._severityCompat] :
            null;
   },
 
-  init: function ()
-  {
+  init: function () {
     Messages.BaseMessage.prototype.init.apply(this, arguments);
     this._groupDepthCompat = this.output.owner.groupDepth;
     this._initRepeatID();
     return this;
   },
 
   /**
    * Tells if the message can be expanded/collapsed.
@@ -838,18 +821,17 @@ Messages.Simple.prototype = extend(Messa
   /**
    * Getter that tells if this message is collapsed - no details are shown.
    * @type boolean
    */
   get collapsed() {
     return this.collapsible && this.element && !this.element.hasAttribute("open");
   },
 
-  _initRepeatID: function ()
-  {
+  _initRepeatID: function () {
     if (!this._filterDuplicates) {
       return;
     }
 
     // Add the properties we care about for identifying duplicate messages.
     let rid = this._repeatID;
     delete rid.uid;
 
@@ -860,29 +842,27 @@ Messages.Simple.prototype = extend(Messa
     rid.location = this.location;
     rid.link = this._link;
     rid.linkCallback = this._linkCallback + "";
     rid.className = this._className;
     rid.groupDepth = this._groupDepthCompat;
     rid.textContent = "";
   },
 
-  getRepeatID: function ()
-  {
+  getRepeatID: function () {
     // No point in returning a string that includes other properties when there
     // is a unique ID.
     if (this._repeatID.uid) {
       return JSON.stringify({ uid: this._repeatID.uid });
     }
 
     return JSON.stringify(this._repeatID);
   },
 
-  render: function ()
-  {
+  render: function () {
     if (this.element) {
       return this;
     }
 
     let timestamp = new Widgets.MessageTimestamp(this, this.timestamp).render();
 
     let icon = this.document.createElementNS(XHTML_NS, "span");
     icon.className = "icon";
@@ -946,18 +926,17 @@ Messages.Simple.prototype = extend(Messa
     return this;
   },
 
   /**
    * Render the message body DOM element.
    * @private
    * @return Element
    */
-  _renderBody: function ()
-  {
+  _renderBody: function () {
     let bodyWrapper = this.document.createElementNS(XHTML_NS, "span");
     bodyWrapper.className = "message-body-wrapper";
 
     let bodyFlex = this.document.createElementNS(XHTML_NS, "span");
     bodyFlex.className = "message-flex-body";
     bodyWrapper.appendChild(bodyFlex);
 
     let body = this.document.createElementNS(XHTML_NS, "span");
@@ -1009,18 +988,17 @@ Messages.Simple.prototype = extend(Messa
     return bodyWrapper;
   },
 
   /**
    * Render the repeat bubble DOM element part of the message.
    * @private
    * @return Element
    */
-  _renderRepeatNode: function ()
-  {
+  _renderRepeatNode: function () {
     if (!this._filterDuplicates) {
       return null;
     }
 
     let repeatNode = this.document.createElementNS(XHTML_NS, "span");
     repeatNode.setAttribute("value", "1");
     repeatNode.className = "message-repeats";
     repeatNode.textContent = 1;
@@ -1028,18 +1006,17 @@ Messages.Simple.prototype = extend(Messa
     return repeatNode;
   },
 
   /**
    * Render the message source location DOM element.
    * @private
    * @return Element
    */
-  _renderLocation: function ()
-  {
+  _renderLocation: function () {
     if (!this.location) {
       return null;
     }
 
     let {url, line, column} = this.location;
     if (IGNORED_SOURCE_URLS.indexOf(url) != -1) {
       return null;
     }
@@ -1053,55 +1030,51 @@ Messages.Simple.prototype = extend(Messa
    * The click event handler for the message expander arrow element. This method
    * toggles the display of message details.
    *
    * @private
    * @param nsIDOMEvent ev
    *        The DOM event object.
    * @see this.toggleDetails()
    */
-  _onClickCollapsible: function (ev)
-  {
+  _onClickCollapsible: function (ev) {
     ev.preventDefault();
     this.toggleDetails();
   },
 
   /**
    * Expand/collapse message details.
    */
-  toggleDetails: function ()
-  {
+  toggleDetails: function () {
     let twisty = this.element.querySelector(".theme-twisty");
     if (this.element.hasAttribute("open")) {
       this.element.removeAttribute("open");
       twisty.removeAttribute("open");
     } else {
       this.element.setAttribute("open", true);
       twisty.setAttribute("open", true);
     }
   },
 }); // Messages.Simple.prototype
 
-
 /**
  * The Extended message.
  *
  * @constructor
  * @extends Messages.Simple
  * @param array messagePieces
  *        The message to display given as an array of elements. Each array
  *        element can be a DOM node, function, ObjectActor, LongString or
  *        a string.
  * @param object [options]
  *        Options for rendering this message:
  *        - quoteStrings: boolean that tells if you want strings to be wrapped
  *        in quotes or not.
  */
-Messages.Extended = function (messagePieces, options = {})
-{
+Messages.Extended = function (messagePieces, options = {}) {
   Messages.Simple.call(this, null, options);
 
   this._messagePieces = messagePieces;
 
   if ("quoteStrings" in options) {
     this._quoteStrings = options.quoteStrings;
   }
 
@@ -1120,32 +1093,30 @@ Messages.Extended.prototype = extend(Mes
 
   /**
    * Boolean that tells if the strings displayed in this message are wrapped.
    * @private
    * @type boolean
    */
   _quoteStrings: true,
 
-  getRepeatID: function ()
-  {
+  getRepeatID: function () {
     if (this._repeatID.uid) {
       return JSON.stringify({ uid: this._repeatID.uid });
     }
 
     // Sets are not stringified correctly. Temporarily switching to an array.
     let actors = this._repeatID.actors;
     this._repeatID.actors = [...actors];
     let result = JSON.stringify(this._repeatID);
     this._repeatID.actors = actors;
     return result;
   },
 
-  render: function ()
-  {
+  render: function () {
     let result = this.document.createDocumentFragment();
 
     for (let i = 0; i < this._messagePieces.length; i++) {
       let separator = i > 0 ? this._renderBodyPieceSeparator() : null;
       if (separator) {
         result.appendChild(separator);
       }
 
@@ -1159,29 +1130,30 @@ Messages.Extended.prototype = extend(Mes
   },
 
   /**
    * Render the separator between the pieces of the message.
    *
    * @private
    * @return Element
    */
-  _renderBodyPieceSeparator: function () { return null; },
+  _renderBodyPieceSeparator: function () {
+    return null;
+  },
 
   /**
    * Render one piece/element of the message array.
    *
    * @private
    * @param mixed piece
    *        Message element to display - this can be a LongString, ObjectActor,
    *        DOM node or a function to invoke.
    * @return Element
    */
-  _renderBodyPiece: function (piece, options = {})
-  {
+  _renderBodyPiece: function (piece, options = {}) {
     if (piece instanceof Ci.nsIDOMNode) {
       return piece;
     }
     if (typeof piece == "function") {
       return piece(this);
     }
 
     return this._renderValueGrip(piece, options);
@@ -1202,18 +1174,17 @@ Messages.Extended.prototype = extend(Mes
    *        grip. This is typically set to true when the object needs to be
    *        displayed in an array preview, or as a property value in object
    *        previews, etc.
    *        - shorten - boolean that tells the renderer to display a truncated
    *        grip.
    * @return DOMElement
    *         The DOM element that displays the given grip.
    */
-  _renderValueGrip: function (grip, options = {})
-  {
+  _renderValueGrip: function (grip, options = {}) {
     let isPrimitive = VariablesView.isPrimitive({ value: grip });
     let isActorGrip = WebConsoleUtils.isActorGrip(grip);
     let noStringQuotes = !this._quoteStrings;
     if ("noStringQuotes" in options) {
       noStringQuotes = options.noStringQuotes;
     }
 
     if (isActorGrip) {
@@ -1230,17 +1201,17 @@ Messages.Extended.prototype = extend(Mes
 
     let unshortenedGrip = grip;
     if (options.shorten) {
       grip = this.shortenValueGrip(grip);
     }
 
     let result = this.document.createElementNS(XHTML_NS, "span");
     if (isPrimitive) {
-      if (Widgets.URLString.prototype.containsURL.call(Widgets.URLString.prototype, grip)) {
+      if (Widgets.URLString.prototype.containsURL(grip)) {
         let widget = new Widgets.URLString(this, grip, unshortenedGrip).render();
         return widget.element;
       }
 
       let className = this.getClassNameForValueGrip(grip);
       if (className) {
         result.className = className;
       }
@@ -1261,18 +1232,17 @@ Messages.Extended.prototype = extend(Mes
    *
    * @param object grip
    *        Value grip from the server.
    * @return object
    *        Possible values of object:
    *        - A shortened string, if original grip was of string type.
    *        - The unmodified input grip, if it wasn't of string type.
    */
-  shortenValueGrip: function (grip)
-  {
+  shortenValueGrip: function (grip) {
     let shortVal = grip;
     if (typeof (grip) == "string") {
       shortVal = grip.replace(/(\r\n|\n|\r)/gm, " ");
       if (shortVal.length > MAX_STRING_GRIP_LENGTH) {
         shortVal = shortVal.substring(0, MAX_STRING_GRIP_LENGTH - 1) + ELLIPSIS;
       }
     }
 
@@ -1282,18 +1252,17 @@ Messages.Extended.prototype = extend(Mes
   /**
    * Get a CodeMirror-compatible class name for a given value grip.
    *
    * @param object grip
    *        Value grip from the server.
    * @return string
    *         The class name for the grip.
    */
-  getClassNameForValueGrip: function (grip)
-  {
+  getClassNameForValueGrip: function (grip) {
     let map = {
       "number": "cm-number",
       "longstring": "console-string",
       "string": "console-string",
       "regexp": "cm-string-2",
       "boolean": "cm-atom",
       "-infinity": "cm-atom",
       "infinity": "cm-atom",
@@ -1320,52 +1289,48 @@ Messages.Extended.prototype = extend(Mes
    * @param object objectActor
    *        The ObjectActor to display.
    * @param object options
    *        Options to use for displaying the ObjectActor.
    * @see this._renderValueGrip for the available options.
    * @return DOMElement
    *         The DOM element that displays the object actor.
    */
-  _renderObjectActor: function (objectActor, options = {})
-  {
-    let widget = Widgets.ObjectRenderers.byClass[objectActor.class];
+  _renderObjectActor: function (objectActor, options = {}) {
+    let Widget = Widgets.ObjectRenderers.byClass[objectActor.class];
 
     let { preview } = objectActor;
-    if ((!widget || (widget.canRender && !widget.canRender(objectActor)))
+    if ((!Widget || (Widget.canRender && !Widget.canRender(objectActor)))
         && preview
         && preview.kind) {
-      widget = Widgets.ObjectRenderers.byKind[preview.kind];
+      Widget = Widgets.ObjectRenderers.byKind[preview.kind];
     }
 
-    if (!widget || (widget.canRender && !widget.canRender(objectActor))) {
-      widget = Widgets.JSObject;
+    if (!Widget || (Widget.canRender && !Widget.canRender(objectActor))) {
+      Widget = Widgets.JSObject;
     }
 
-    let instance = new widget(this, objectActor, options).render();
+    let instance = new Widget(this, objectActor, options).render();
     return instance.element;
   },
 }); // Messages.Extended.prototype
 
-
-
 /**
  * The JavaScriptEvalOutput message.
  *
  * @constructor
  * @extends Messages.Extended
  * @param object evalResponse
  *        The evaluation response packet received from the server.
  * @param string [errorMessage]
  *        Optional error message to display.
  * @param string [errorDocLink]
  * Optional error doc URL to link to.
  */
-Messages.JavaScriptEvalOutput = function (evalResponse, errorMessage, errorDocLink)
-{
+Messages.JavaScriptEvalOutput = function (evalResponse, errorMessage, errorDocLink) {
   let severity = "log", msg, quoteStrings = true;
 
   // Store also the response packet from the back end. It might
   // be useful to extensions customizing the console output.
   this.response = evalResponse;
 
   if (typeof (errorMessage) !== "undefined") {
     severity = "error";
@@ -1396,18 +1361,17 @@ Messages.JavaScriptEvalOutput.prototype 
 /**
  * The ConsoleGeneric message is used for console API calls.
  *
  * @constructor
  * @extends Messages.Extended
  * @param object packet
  *        The Console API call packet received from the server.
  */
-Messages.ConsoleGeneric = function (packet)
-{
+Messages.ConsoleGeneric = function (packet) {
   let options = {
     className: "cm-s-mozilla",
     timestamp: packet.timeStamp,
     category: packet.category || "webdev",
     severity: CONSOLE_API_LEVELS_TO_SEVERITIES[packet.level],
     prefix: packet.prefix,
     private: packet.private,
     filterDuplicates: true,
@@ -1436,36 +1400,33 @@ Messages.ConsoleGeneric = function (pack
   this._repeatID.styles = packet.styles;
   this.stack = this._repeatID.stacktrace = packet.stacktrace;
   this._styles = packet.styles || [];
 };
 
 Messages.ConsoleGeneric.prototype = extend(Messages.Extended.prototype, {
   _styles: null,
 
-  _renderBodyPieceSeparator: function ()
-  {
+  _renderBodyPieceSeparator: function () {
     return this.document.createTextNode(" ");
   },
 
-  render: function ()
-  {
+  render: function () {
     let result = this.document.createDocumentFragment();
     this._renderBodyPieces(result);
 
     this._message = result;
     this._stacktrace = null;
 
     Messages.Simple.prototype.render.call(this);
 
     return this;
   },
 
-  _renderBodyPieces: function (container)
-  {
+  _renderBodyPieces: function (container) {
     let lastStyle = null;
     let stylePieces = this._styles.length > 0 ? this._styles.length : 1;
 
     for (let i = 0; i < this._messagePieces.length; i++) {
       // Pieces with an associated style definition come from "%c" formatting.
       // For body pieces beyond that, add a separator before each one.
       if (i >= stylePieces) {
         container.appendChild(this._renderBodyPieceSeparator());
@@ -1480,18 +1441,17 @@ Messages.ConsoleGeneric.prototype = exte
 
       container.appendChild(this._renderBodyPiece(piece, lastStyle));
     }
 
     this._messagePieces = null;
     this._styles = null;
   },
 
-  _renderBodyPiece: function (piece, style)
-  {
+  _renderBodyPiece: function (piece, style) {
     // Skip quotes for top-level strings.
     let options = { noStringQuotes: true };
     let elem = Messages.Extended.prototype._renderBodyPiece.call(this, piece, options);
     let result = elem;
 
     if (style) {
       if (elem.nodeType == nodeConstants.ELEMENT_NODE) {
         elem.style = style;
@@ -1514,18 +1474,17 @@ Messages.ConsoleGeneric.prototype = exte
    * - only some of the properties are allowed, based on a whitelist. See
    *   RE_ALLOWED_STYLES.
    *
    * @param string style
    *        The style string to cleanup.
    * @return string
    *         The style value after cleanup.
    */
-  cleanupStyle: function (style)
-  {
+  cleanupStyle: function (style) {
     for (let r of RE_CLEANUP_STYLES) {
       style = style.replace(r, "notallowed");
     }
 
     let dummy = this.output._dummyElement;
     if (!dummy) {
       dummy = this.output._dummyElement =
         this.document.createElementNS(XHTML_NS, "div");
@@ -1555,18 +1514,17 @@ Messages.ConsoleGeneric.prototype = exte
 /**
  * The ConsoleTrace message is used for console.trace() calls.
  *
  * @constructor
  * @extends Messages.Simple
  * @param object packet
  *        The Console API call packet received from the server.
  */
-Messages.ConsoleTrace = function (packet)
-{
+Messages.ConsoleTrace = function (packet) {
   let options = {
     className: "cm-s-mozilla",
     timestamp: packet.timeStamp,
     category: packet.category || "webdev",
     severity: CONSOLE_API_LEVELS_TO_SEVERITIES[packet.level],
     private: packet.private,
     filterDuplicates: true,
     location: {
@@ -1596,18 +1554,17 @@ Messages.ConsoleTrace.prototype = extend
    * method. This array is cleared when the message is initialized, and
    * associated actors are released.
    *
    * @private
    * @type array
    */
   _arguments: null,
 
-  init: function ()
-  {
+  init: function () {
     let result = Messages.Simple.prototype.init.apply(this, arguments);
 
     // We ignore console.trace() arguments. Release object actors.
     if (Array.isArray(this._arguments)) {
       for (let arg of this._arguments) {
         if (WebConsoleUtils.isActorGrip(arg)) {
           this.output._releaseObject(arg.actor);
         }
@@ -1662,18 +1619,17 @@ Messages.ConsoleTrace.prototype = extend
 /**
  * The ConsoleTable message is used for console.table() calls.
  *
  * @constructor
  * @extends Messages.Extended
  * @param object packet
  *        The Console API call packet received from the server.
  */
-Messages.ConsoleTable = function (packet)
-{
+Messages.ConsoleTable = function (packet) {
   let options = {
     className: "cm-s-mozilla",
     timestamp: packet.timeStamp,
     category: packet.category || "webdev",
     severity: CONSOLE_API_LEVELS_TO_SEVERITIES[packet.level],
     private: packet.private,
     filterDuplicates: false,
     location: {
@@ -1721,18 +1677,17 @@ Messages.ConsoleTable.prototype = extend
    * A promise that resolves when the table data is ready or null if invalid
    * arguments are provided.
    *
    * @private
    * @type promise|null
    */
   _populatePromise: null,
 
-  init: function ()
-  {
+  init: function () {
     let result = Messages.Extended.prototype.init.apply(this, arguments);
     this._data = [];
     this._columns = {};
 
     this._populatePromise = this._populateTableData();
 
     return result;
   },
@@ -1741,18 +1696,17 @@ Messages.ConsoleTable.prototype = extend
    * Sets the key value pair of the id and display name for the columns in the
    * table.
    *
    * @private
    * @param array|string columns
    *        Either a string or array containing the names for the columns in
    *        the output table.
    */
-  _setColumns: function (columns)
-  {
+  _setColumns: function (columns) {
     if (columns.class == "Array") {
       let items = columns.preview.items;
 
       for (let item of items) {
         if (typeof item == "string") {
           this._columns[item] = item;
         }
       }
@@ -1764,67 +1718,66 @@ Messages.ConsoleTable.prototype = extend
   /**
    * Retrieves the table data and columns from the arguments received from the
    * server.
    *
    * @return Promise|null
    *         Returns a promise that resolves when the table data is ready or
    *         null if the arguments are invalid.
    */
-  _populateTableData: function ()
-  {
+  _populateTableData: function () {
     let deferred = promise.defer();
 
     if (this._arguments.length <= 0) {
-      return;
+      return deferred.reject();
     }
 
     let data = this._arguments[0];
     if (data.class != "Array" && data.class != "Object" &&
         data.class != "Map" && data.class != "Set" &&
         data.class != "WeakMap" && data.class != "WeakSet") {
-      return;
+      return deferred.reject();
     }
 
     let hasColumnsArg = false;
     if (this._arguments.length > 1) {
       if (data.class == "Object" || data.class == "Array") {
-        this._columns["_index"] = l10n.getStr("table.index");
+        this._columns._index = l10n.getStr("table.index");
       } else {
-        this._columns["_index"] = l10n.getStr("table.iterationIndex");
+        this._columns._index = l10n.getStr("table.iterationIndex");
       }
 
       this._setColumns(this._arguments[1]);
       hasColumnsArg = true;
     }
 
     if (data.class == "Object" || data.class == "Array") {
       // Get the object properties, and parse the key and value properties into
       // the table data and columns.
       this.client = new ObjectClient(this.output.owner.jsterm.hud.proxy.client,
           data);
-      this.client.getPrototypeAndProperties(aResponse => {
-        let {ownProperties} = aResponse;
+      this.client.getPrototypeAndProperties(response => {
+        let {ownProperties} = response;
         let rowCount = 0;
         let columnCount = 0;
 
         for (let index of Object.keys(ownProperties || {})) {
           // Avoid outputting the length property if the data argument provided
           // is an array
           if (data.class == "Array" && index == "length") {
             continue;
           }
 
           if (!hasColumnsArg) {
-            this._columns["_index"] = l10n.getStr("table.index");
+            this._columns._index = l10n.getStr("table.index");
           }
 
           if (data.class == "Array") {
-            if (index == parseInt(index)) {
-              index = parseInt(index);
+            if (index == parseInt(index, 10)) {
+              index = parseInt(index, 10);
             }
           }
 
           let property = ownProperties[index].value;
           let item = { _index: index };
 
           if (property.class == "Object" || property.class == "Array") {
             let {preview} = property;
@@ -1839,39 +1792,39 @@ Messages.ConsoleTable.prototype = extend
 
               if (!hasColumnsArg && !(key in this._columns) &&
                   (++columnCount <= TABLE_COLUMN_MAX_ITEMS)) {
                 this._columns[key] = key;
               }
             }
           } else {
             // Display the value for any non-object data input.
-            item["_value"] = this._renderValueGrip(property, { concise: true });
+            item._value = this._renderValueGrip(property, { concise: true });
 
             if (!hasColumnsArg && !("_value" in this._columns)) {
-              this._columns["_value"] = l10n.getStr("table.value");
+              this._columns._value = l10n.getStr("table.value");
             }
           }
 
           this._data.push(item);
 
           if (++rowCount == TABLE_ROW_MAX_ITEMS) {
             break;
           }
         }
 
         deferred.resolve();
       });
     } else if (data.class == "Map" || data.class == "WeakMap") {
       let entries = data.preview.entries;
 
       if (!hasColumnsArg) {
-        this._columns["_index"] = l10n.getStr("table.iterationIndex");
-        this._columns["_key"] = l10n.getStr("table.key");
-        this._columns["_value"] = l10n.getStr("table.value");
+        this._columns._index = l10n.getStr("table.iterationIndex");
+        this._columns._key = l10n.getStr("table.key");
+        this._columns._value = l10n.getStr("table.value");
       }
 
       let rowCount = 0;
       for (let [key, value] of entries) {
         let item = {
           _index: rowCount,
           _key: this._renderValueGrip(key, { concise: true }),
           _value: this._renderValueGrip(value, { concise: true })
@@ -1884,42 +1837,41 @@ Messages.ConsoleTable.prototype = extend
         }
       }
 
       deferred.resolve();
     } else if (data.class == "Set" || data.class == "WeakSet") {
       let entries = data.preview.items;
 
       if (!hasColumnsArg) {
-        this._columns["_index"] = l10n.getStr("table.iterationIndex");
-        this._columns["_value"] = l10n.getStr("table.value");
+        this._columns._index = l10n.getStr("table.iterationIndex");
+        this._columns._value = l10n.getStr("table.value");
       }
 
       let rowCount = 0;
       for (let entry of entries) {
         let item = {
-          _index : rowCount,
+          _index: rowCount,
           _value: this._renderValueGrip(entry, { concise: true })
         };
 
         this._data.push(item);
 
         if (++rowCount == TABLE_ROW_MAX_ITEMS) {
           break;
         }
       }
 
       deferred.resolve();
     }
 
     return deferred.promise;
   },
 
-  render: function ()
-  {
+  render: function () {
     this._attachment = this._renderTable();
     Messages.Extended.prototype.render.apply(this, arguments);
     this.element.setAttribute("open", true);
     return this;
   },
 
   _renderMessage: function () {
     let cmvar = this.document.createElementNS(XHTML_NS, "span");
@@ -1978,18 +1930,17 @@ var Widgets = {};
 
 /**
  * The base widget class.
  *
  * @constructor
  * @param object message
  *        The owning message.
  */
-Widgets.BaseWidget = function (message)
-{
+Widgets.BaseWidget = function (message) {
   this.message = message;
 };
 
 Widgets.BaseWidget.prototype = {
   /**
    * The owning message object.
    * @type object
    */
@@ -2052,18 +2003,17 @@ Widgets.BaseWidget.prototype = {
    *        of the new DOM element. Otherwise, the value becomes the
    *        .textContent of the new DOM element.
    * @param string [textContent]
    *        If this argument is provided the value is used as the textContent of
    *        the new DOM element.
    * @return DOMElement
    *         The new DOM element.
    */
-  el: function (tagNameIdAndClasses)
-  {
+  el: function (tagNameIdAndClasses) {
     let attrs, text;
     if (typeof arguments[1] == "object") {
       attrs = arguments[1];
       text = arguments[2];
     } else {
       text = arguments[1];
     }
 
@@ -2094,72 +2044,67 @@ Widgets.BaseWidget.prototype = {
  * The timestamp widget.
  *
  * @constructor
  * @param object message
  *        The owning message.
  * @param number timestamp
  *        The UNIX timestamp to display.
  */
-Widgets.MessageTimestamp = function (message, timestamp)
-{
+Widgets.MessageTimestamp = function (message, timestamp) {
   Widgets.BaseWidget.call(this, message);
   this.timestamp = timestamp;
 };
 
 Widgets.MessageTimestamp.prototype = extend(Widgets.BaseWidget.prototype, {
   /**
    * The UNIX timestamp.
    * @type number
    */
   timestamp: 0,
 
-  render: function ()
-  {
+  render: function () {
     if (this.element) {
       return this;
     }
 
     this.element = this.document.createElementNS(XHTML_NS, "span");
     this.element.className = "timestamp devtools-monospace";
     this.element.textContent = l10n.timestampString(this.timestamp) + " ";
 
     return this;
   },
 }); // Widgets.MessageTimestamp.prototype
 
-
 /**
  * The URLString widget, for rendering strings where at least one token is a
  * URL.
  *
  * @constructor
  * @param object message
  *        The owning message.
  * @param string str
  *        The string, which contains at least one valid URL.
  * @param string unshortenedStr
  *        The unshortened form of the string, if it was shortened.
  */
-Widgets.URLString = function (message, str, unshortenedStr)
-{
+Widgets.URLString = function (message, str, unshortenedStr) {
   Widgets.BaseWidget.call(this, message);
   this.str = str;
   this.unshortenedStr = unshortenedStr;
 };
 
 Widgets.URLString.prototype = extend(Widgets.BaseWidget.prototype, {
   /**
    * The string to format, which contains at least one valid URL.
    * @type string
    */
   str: "",
 
-  render: function ()
-  {
+  render: function () {
     if (this.element) {
       return this;
     }
 
     // The rendered URLString will be a <span> containing a number of text
     // <spans> for non-URL tokens and <a>'s for URL tokens.
     this.element = this.el("span", {
       class: "console-string"
@@ -2183,32 +2128,32 @@ Widgets.URLString.prototype = extend(Wid
         }
         this.element.appendChild(this._renderText(this.str.slice(textStart, tokenStart)));
         textStart = tokenStart + token.length;
         this.element.appendChild(this._renderURL(token, unshortenedToken));
       }
     }
 
     // Clean up any non-URL text at the end of the source string.
-    this.element.appendChild(this._renderText(this.str.slice(textStart, this.str.length)));
+    const rendered = this._renderText(this.str.slice(textStart, this.str.length));
+    this.element.appendChild(rendered);
     this.element.appendChild(this._renderText("\""));
 
     return this;
   },
 
   /**
    * Determines whether a grip is a string containing a URL.
    *
    * @param string grip
    *        The grip, which may contain a URL.
    * @return boolean
    *         Whether the grip is a string containing a URL.
    */
-  containsURL: function (grip)
-  {
+  containsURL: function (grip) {
     if (typeof grip != "string") {
       return false;
     }
 
     let tokens = grip.split(/\s+/);
     return tokens.some(this._isURL);
   },
 
@@ -2237,18 +2182,17 @@ Widgets.URLString.prototype = extend(Wid
    *
    * @param string url
    *        The string to be rendered as a url.
    * @param string fullUrl
    *        The unshortened form of the URL, if it was shortened.
    * @return DOMElement
    *         An element containing the rendered string.
    */
-  _renderURL: function (url, fullUrl)
-  {
+  _renderURL: function (url, fullUrl) {
     let unshortened = fullUrl || url;
     let result = this.el("a", {
       class: "url",
       title: unshortened,
       href: unshortened,
       draggable: false
     }, url);
     this.message._addLinkCallback(result);
@@ -2268,76 +2212,70 @@ Widgets.URLString.prototype = extend(Wid
  *        The owning message.
  * @param object objectActor
  *        The ObjectActor to display.
  * @param object [options]
  *        Options for displaying the given ObjectActor. See
  *        Messages.Extended.prototype._renderValueGrip for the available
  *        options.
  */
-Widgets.JSObject = function (message, objectActor, options = {})
-{
+Widgets.JSObject = function (message, objectActor, options = {}) {
   Widgets.BaseWidget.call(this, message);
   this.objectActor = objectActor;
   this.options = options;
   this._onClick = this._onClick.bind(this);
 };
 
 Widgets.JSObject.prototype = extend(Widgets.BaseWidget.prototype, {
   /**
    * The ObjectActor displayed by the widget.
    * @type object
    */
   objectActor: null,
 
-  render: function ()
-  {
+  render: function () {
     if (!this.element) {
       this._render();
     }
 
     return this;
   },
 
-  _render: function ()
-  {
+  _render: function () {
     let str = VariablesView.getString(this.objectActor, this.options);
     let className = this.message.getClassNameForValueGrip(this.objectActor);
     if (!className && this.objectActor.class == "Object") {
       className = "cm-variable";
     }
 
     this.element = this._anchor(str, { className: className });
   },
 
   /**
    * Render a concise representation of an object.
    */
-  _renderConciseObject: function ()
-  {
+  _renderConciseObject: function () {
     this.element = this._anchor(this.objectActor.class,
                                 { className: "cm-variable" });
   },
 
   /**
    * Render the `<class> { ` prefix of an object.
    */
-  _renderObjectPrefix: function ()
-  {
+  _renderObjectPrefix: function () {
     let { kind } = this.objectActor.preview;
     this.element = this.el("span.kind-" + kind);
     this._anchor(this.objectActor.class, { className: "cm-variable" });
     this._text(" { ");
   },
 
   /**
    * Render the ` }` suffix of an object.
    */
-  _renderObjectSuffix: function ()
-  {
+  _renderObjectSuffix: function () {
     this._text(" }");
   },
 
   /**
    * Render an object property.
    *
    * @param String key
    *        The property name.
@@ -2347,57 +2285,63 @@ Widgets.JSObject.prototype = extend(Widg
    *        The container node to render to.
    * @param Boolean needsComma
    *        True if there was another property before this one and we need to
    *        separate them with a comma.
    * @param Boolean valueIsText
    *        Add the value as is, don't treat it as a grip and pass it to
    *        `_renderValueGrip`.
    */
-  _renderObjectProperty: function (key, value, container, needsComma, valueIsText = false)
-  {
+  _renderObjectProperty: function (
+    key,
+    value,
+    container,
+    needsComma,
+    valueIsText = false
+  ) {
     if (needsComma) {
       this._text(", ");
     }
 
     container.appendChild(this.el("span.cm-property", key));
     this._text(": ");
 
     if (valueIsText) {
       this._text(value);
     } else {
-      let valueElem = this.message._renderValueGrip(value, { concise: true, shorten: true });
+      let valueElem = this.message._renderValueGrip(value, {
+        concise: true,
+        shorten: true
+      });
       container.appendChild(valueElem);
     }
   },
 
   /**
    * Render this object's properties.
    *
    * @param nsIDOMNode container
    *        The container node to render to.
    * @param Boolean needsComma
    *        True if there was another property before this one and we need to
    *        separate them with a comma.
    */
-  _renderObjectProperties: function (container, needsComma)
-  {
+  _renderObjectProperties: function (container, needsComma) {
     let { preview } = this.objectActor;
     let { ownProperties, safeGetterValues } = preview;
 
     let shown = 0;
 
     let getValue = desc => {
       if (desc.get) {
         return "Getter";
       } else if (desc.set) {
         return "Setter";
-      } else {
-        return desc.value;
       }
+      return desc.value;
     };
 
     for (let key of Object.keys(ownProperties || {})) {
       this._renderObjectProperty(key, getValue(ownProperties[key]), container,
                                  shown > 0 || needsComma,
                                  ownProperties[key].get || ownProperties[key].set);
       shown++;
     }
@@ -2435,18 +2379,17 @@ Widgets.JSObject.prototype = extend(Widg
    *        on the anchor open the link in a new tab.
    *        - appendTo (DOMElement): append the element to the given DOM
    *        element. If not provided, the anchor is appended to |this.element|
    *        if it is available. If |appendTo| is provided and if it is a falsy
    *        value, the anchor is not appended to any element.
    * @return DOMElement
    *         The DOM element of the new anchor.
    */
-  _anchor: function (text, options = {})
-  {
+  _anchor: function (text, options = {}) {
     if (!options.onClick) {
       // If the anchor has an URL, open it in a new tab. If not, show the
       // current object actor.
       options.onClick = options.href ? this._onClickAnchor : this._onClick;
     }
 
     options.onContextMenu = options.onContextMenu || this._onContextMenu;
 
@@ -2464,27 +2407,25 @@ Widgets.JSObject.prototype = extend(Widg
       options.appendTo.appendChild(anchor);
     } else if (!("appendTo" in options) && this.element) {
       this.element.appendChild(anchor);
     }
 
     return anchor;
   },
 
-  openObjectInVariablesView: function ()
-  {
+  openObjectInVariablesView: function () {
     this.output.openVariablesView({
       label: VariablesView.getString(this.objectActor, { concise: true }),
       objectActor: this.objectActor,
       autofocus: true,
     });
   },
 
-  storeObjectInWindow: function ()
-  {
+  storeObjectInWindow: function () {
     let evalString = `{ let i = 0;
       while (this.hasOwnProperty("temp" + i) && i < 1000) {
         i++;
       }
       this["temp" + i] = _self;
       "temp" + i;
     }`;
     let options = {
@@ -2496,18 +2437,17 @@ Widgets.JSObject.prototype = extend(Widg
       this.output.owner.jsterm.setInputValue(res.result);
     });
   },
 
   /**
    * The click event handler for objects shown inline.
    * @private
    */
-  _onClick: function ()
-  {
+  _onClick: function () {
     this.openObjectInVariablesView();
   },
 
   _onContextMenu: function (ev) {
     // TODO offer a nice API for the context menu.
     // Probably worth to take a look at Firebug's way
     // https://github.com/firebug/firebug/blob/master/extension/content/firebug/chrome/menu.js
     let doc = ev.target.ownerDocument;
@@ -2543,18 +2483,17 @@ Widgets.JSObject.prototype = extend(Widg
    *
    * @private
    * @param string str
    *        String to add.
    * @param DOMElement [target = this.element]
    *        Optional DOM element to append the string to. The default is
    *        this.element.
    */
-  _text: function (str, target = this.element)
-  {
+  _text: function (str, target = this.element) {
     target.appendChild(this.document.createTextNode(str));
   },
 }); // Widgets.JSObject.prototype
 
 Widgets.ObjectRenderers = {};
 Widgets.ObjectRenderers.byKind = {};
 Widgets.ObjectRenderers.byClass = {};
 
@@ -2579,18 +2518,17 @@ Widgets.ObjectRenderers.byClass = {};
  *        - initialize (function, optional): the constructor of the renderer
  *        widget. This function is invoked with the following arguments: the
  *        owner message object instance, the object actor grip to display, and
  *        an options object. See Messages.Extended.prototype._renderValueGrip()
  *        for details about the options object.
  *        - render (function, required): the method that displays the given
  *        object actor.
  */
-Widgets.ObjectRenderers.add = function (obj)
-{
+Widgets.ObjectRenderers.add = function (obj) {
   let extendObj = obj.extends || Widgets.JSObject;
 
   let constructor = function () {
     if (obj.initialize) {
       obj.initialize.apply(this, arguments);
     } else {
       extendObj.apply(this, arguments);
     }
@@ -2616,25 +2554,23 @@ Widgets.ObjectRenderers.add = function (
   } else if (obj.byKind) {
     Widgets.ObjectRenderers.byKind[obj.byKind] = constructor;
   } else {
     throw new Error("You are adding an object renderer without any byClass or " +
                     "byKind property.");
   }
 };
 
-
 /**
  * The widget used for displaying Date objects.
  */
 Widgets.ObjectRenderers.add({
   byClass: "Date",
 
-  render: function ()
-  {
+  render: function () {
     let {preview} = this.objectActor;
     this.element = this.el("span.class-" + this.objectActor.class);
 
     let anchorText = this.objectActor.class;
     let anchorClass = "cm-variable";
     if (preview && "timestamp" in preview && typeof preview.timestamp != "number") {
       anchorText = new Date(preview.timestamp).toString(); // invalid date
       anchorClass = "";
@@ -2654,27 +2590,24 @@ Widgets.ObjectRenderers.add({
 });
 
 /**
  * The widget used for displaying Function objects.
  */
 Widgets.ObjectRenderers.add({
   byClass: "Function",
 
-  render: function ()
-  {
+  render: function () {
     let grip = this.objectActor;
     this.element = this.el("span.class-" + this.objectActor.class);
 
     // TODO: Bug 948484 - support arrow functions and ES6 generators
     let name = grip.userDisplayName || grip.displayName || grip.name || "";
     name = VariablesView.getString(name, { noStringQuotes: true });
 
-    let str = this.options.concise ? name || "function " : "function " + name;
-
     if (this.options.concise) {
       this._anchor(name || "function", {
         className: name ? "cm-variable" : "cm-keyword",
       });
       if (!name) {
         this._text(" ");
       }
     } else if (name) {
@@ -2715,18 +2648,17 @@ Widgets.ObjectRenderers.add({
 }); // Widgets.ObjectRenderers.byClass.Function
 
 /**
  * The widget used for displaying ArrayLike objects.
  */
 Widgets.ObjectRenderers.add({
   byKind: "ArrayLike",
 
-  render: function ()
-  {
+  render: function () {
     let {preview} = this.objectActor;
     let {items} = preview;
     this.element = this.el("span.kind-" + preview.kind);
 
     this._anchor(this.objectActor.class, { className: "cm-variable" });
 
     if (!items || this.options.concise) {
       this._text("[");
@@ -2740,18 +2672,17 @@ Widgets.ObjectRenderers.add({
     let isFirst = true;
     let emptySlots = 0;
     // A helper that renders a comma between items if isFirst == false.
     let renderSeparator = () => !isFirst && this._text(", ");
 
     for (let item of items) {
       if (item === null) {
         emptySlots++;
-      }
-      else {
+      } else {
         renderSeparator();
         isFirst = false;
 
         if (emptySlots) {
           this._renderEmptySlots(emptySlots);
           emptySlots = 0;
         }
 
@@ -2770,37 +2701,38 @@ Widgets.ObjectRenderers.add({
       this._text(", ");
 
       let n = preview.length - shown;
       let str = VariablesView.stringifiers._getNMoreString(n);
       this._anchor(str);
     }
 
     this._text(" ]");
+
+    return this;
   },
 
-  _renderEmptySlots: function (aNumSlots, aAppendComma = true) {
+  _renderEmptySlots: function (numSlots, appendComma = true) {
     let slotLabel = l10n.getStr("emptySlotLabel");
-    let slotText = PluralForm.get(aNumSlots, slotLabel);
-    this._text("<" + slotText.replace("#1", aNumSlots) + ">");
-    if (aAppendComma) {
+    let slotText = PluralForm.get(numSlots, slotLabel);
+    this._text("<" + slotText.replace("#1", numSlots) + ">");
+    if (appendComma) {
       this._text(", ");
     }
   },
 
 }); // Widgets.ObjectRenderers.byKind.ArrayLike
 
 /**
  * The widget used for displaying MapLike objects.
  */
 Widgets.ObjectRenderers.add({
   byKind: "MapLike",
 
-  render: function ()
-  {
+  render: function () {
     let {preview} = this.objectActor;
     let {entries} = preview;
 
     let container = this.element = this.el("span.kind-" + preview.kind);
     this._anchor(this.objectActor.class, { className: "cm-variable" });
 
     if (!entries || this.options.concise) {
       if (typeof preview.size == "number") {
@@ -2853,24 +2785,22 @@ Widgets.ObjectRenderers.add({
 }); // Widgets.ObjectRenderers.byKind.MapLike
 
 /**
  * The widget used for displaying objects with a URL.
  */
 Widgets.ObjectRenderers.add({
   byKind: "ObjectWithURL",
 
-  render: function ()
-  {
+  render: function () {
     this.element = this._renderElement(this.objectActor,
                                        this.objectActor.preview.url);
   },
 
-  _renderElement: function (objectActor, url)
-  {
+  _renderElement: function (objectActor, url) {
     let container = this.el("span.kind-" + objectActor.preview.kind);
 
     this._anchor(objectActor.class, {
       className: "cm-variable",
       appendTo: container,
     });
 
     if (!VariablesView.isFalsy({ value: url })) {
@@ -2884,18 +2814,17 @@ Widgets.ObjectRenderers.add({
 }); // Widgets.ObjectRenderers.byKind.ObjectWithURL
 
 /**
  * The widget used for displaying objects with a string next to them.
  */
 Widgets.ObjectRenderers.add({
   byKind: "ObjectWithText",
 
-  render: function ()
-  {
+  render: function () {
     let {preview} = this.objectActor;
     this.element = this.el("span.kind-" + preview.kind);
 
     this._anchor(this.objectActor.class, { className: "cm-variable" });
 
     if (!this.options.concise) {
       this._text(" ");
       this.element.appendChild(this.el("span.theme-fg-color6",
@@ -2905,18 +2834,17 @@ Widgets.ObjectRenderers.add({
 });
 
 /**
  * The widget used for displaying DOM event previews.
  */
 Widgets.ObjectRenderers.add({
   byKind: "DOMEvent",
 
-  render: function ()
-  {
+  render: function () {
     let {preview} = this.objectActor;
 
     let container = this.element = this.el("span.kind-" + preview.kind);
 
     this._anchor(preview.type || this.objectActor.class,
                  { className: "cm-variable" });
 
     if (this.options.concise) {
@@ -2987,24 +2915,24 @@ Widgets.ObjectRenderers.add({
       case nodeConstants.DOCUMENT_FRAGMENT_NODE:
       case nodeConstants.ELEMENT_NODE:
         return true;
       default:
         return false;
     }
   },
 
-  render: function ()
-  {
-    switch (this.objectActor.preview.nodeType) {
+  render: function () {
+    const {preview} = this.objectActor;
+
+    switch (preview.nodeType) {
       case nodeConstants.DOCUMENT_NODE:
         this._renderDocumentNode();
         break;
       case nodeConstants.ATTRIBUTE_NODE: {
-        let {preview} = this.objectActor;
         this.element = this.el("span.attributeNode.kind-" + preview.kind);
         let attr = this._renderAttributeNode(preview.nodeName, preview.value, true);
         this.element.appendChild(attr);
         break;
       }
       case nodeConstants.TEXT_NODE:
         this._renderTextNode();
         break;
@@ -3017,69 +2945,64 @@ Widgets.ObjectRenderers.add({
       case nodeConstants.ELEMENT_NODE:
         this._renderElementNode();
         break;
       default:
         throw new Error("Unsupported nodeType: " + preview.nodeType);
     }
   },
 
-  _renderDocumentNode: function ()
-  {
+  _renderDocumentNode: function () {
     let fn =
       Widgets.ObjectRenderers.byKind.ObjectWithURL.prototype._renderElement;
     this.element = fn.call(this, this.objectActor,
                            this.objectActor.preview.location);
     this.element.classList.add("documentNode");
   },
 
-  _renderAttributeNode: function (nodeName, nodeValue, addLink)
-  {
+  _renderAttributeNode: function (nodeName, nodeValue, addLink) {
     let value = VariablesView.getString(nodeValue, { noStringQuotes: true });
 
     let fragment = this.document.createDocumentFragment();
     if (addLink) {
       this._anchor(nodeName, { className: "cm-attribute", appendTo: fragment });
     } else {
       fragment.appendChild(this.el("span.cm-attribute", nodeName));
     }
 
     this._text("=\"", fragment);
     fragment.appendChild(this.el("span.theme-fg-color6", escapeHTML(value)));
     this._text("\"", fragment);
 
     return fragment;
   },
 
-  _renderTextNode: function ()
-  {
+  _renderTextNode: function () {
     let {preview} = this.objectActor;
     this.element = this.el("span.textNode.kind-" + preview.kind);
 
     this._anchor(preview.nodeName, { className: "cm-variable" });
     this._text(" ");
 
     let text = VariablesView.getString(preview.textContent);
     this.element.appendChild(this.el("span.console-string", text));
   },
 
-  _renderCommentNode: function ()
-  {
+  _renderCommentNode: function () {
     let {preview} = this.objectActor;
     let comment = "<!-- " + VariablesView.getString(preview.textContent, {
       noStringQuotes: true,
     }) + " -->";
 
     this.element = this._anchor(comment, {
       className: "kind-" + preview.kind + " commentNode cm-comment",
     });
   },
 
-  _renderDocumentFragmentNode: function ()
-  {
+  _renderDocumentFragmentNode: function () {
     let {preview} = this.objectActor;
     let {childNodes} = preview;
     let container = this.element = this.el("span.documentFragmentNode.kind-" +
                                            preview.kind);
 
     this._anchor(this.objectActor.class, { className: "cm-variable" });
 
     if (!childNodes || this.options.concise) {
@@ -3108,38 +3031,38 @@ Widgets.ObjectRenderers.add({
       let n = preview.childNodesLength - shown;
       let str = VariablesView.stringifiers._getNMoreString(n);
       this._anchor(str);
     }
 
     this._text(" ]");
   },
 
-  _renderElementNode: function ()
-  {
-    let doc = this.document;
+  _renderElementNode: function () {
     let {attributes, nodeName} = this.objectActor.preview;
 
-    this.element = this.el("span." + "kind-" + this.objectActor.preview.kind + ".elementNode");
+    this.element = this.el("span." + "kind-" + this.objectActor.preview.kind +
+                           ".elementNode");
 
     this._text("<");
     let openTag = this.el("span.cm-tag");
     this.element.appendChild(openTag);
 
     let tagName = this._anchor(nodeName, {
       className: "cm-tag",
       appendTo: openTag
     });
 
     if (this.options.concise) {
       if (attributes.id) {
         tagName.appendChild(this.el("span.cm-attribute", "#" + attributes.id));
       }
       if (attributes.class) {
-        tagName.appendChild(this.el("span.cm-attribute", "." + attributes.class.split(/\s+/g).join(".")));
+        const joinedClasses = "." + attributes.class.split(/\s+/g).join(".");
+        tagName.appendChild(this.el("span.cm-attribute", joinedClasses));
       }
     } else {
       for (let name of Object.keys(attributes)) {
         let attr = this._renderAttributeNode(" " + name, attributes[name]);
         this.element.appendChild(attr);
       }
     }
 
@@ -3157,18 +3080,17 @@ Widgets.ObjectRenderers.add({
    * will attach mouseover/out event listeners to do so, and the inspector icon
    * to open the node in the inspector.
    * @return a promise that resolves when the node has been linked to the
    * inspector, or rejects if it wasn't (either if no toolbox could be found to
    * access the inspector, or if the node isn't present in the inspector, i.e.
    * if the node is in a DocumentFragment or not part of the tree, or not of
    * type nodeConstants.ELEMENT_NODE).
    */
-  linkToInspector: Task.async(function* ()
-  {
+  linkToInspector: Task.async(function* () {
     if (this._linkedToInspector) {
       return;
     }
 
     // Checking the node type
     if (this.objectActor.preview.nodeType !== nodeConstants.ELEMENT_NODE) {
       throw new Error("The object cannot be linked to the inspector as it " +
         "isn't an element node");
@@ -3179,17 +3101,18 @@ Widgets.ObjectRenderers.add({
     this.toolbox = gDevTools.getToolbox(target);
     if (!this.toolbox) {
       // In cases like the browser console, there is no toolbox.
       return;
     }
 
     // Checking that the inspector supports the node
     yield this.toolbox.initInspector();
-    this._nodeFront = yield this.toolbox.walker.getNodeActorFromObjectActor(this.objectActor.actor);
+    this._nodeFront = yield this.toolbox.walker.getNodeActorFromObjectActor(
+      this.objectActor.actor);
     if (!this._nodeFront) {
       throw new Error("The object cannot be linked to the inspector, the " +
         "corresponding nodeFront could not be found");
     }
 
     // At this stage, the message may have been cleared already
     if (!this.document) {
       throw new Error("The object cannot be linked to the inspector, the " +
@@ -3214,68 +3137,66 @@ Widgets.ObjectRenderers.add({
     this._openInspectorNode.title = l10n.getStr("openNodeInInspector");
   }),
 
   /**
    * Highlight the DOMNode corresponding to the ObjectActor in the page.
    * @return a promise that resolves when the node has been highlighted, or
    * rejects if the node cannot be highlighted (detached from the DOM)
    */
-  highlightDomNode: Task.async(function* ()
-  {
+  highlightDomNode: Task.async(function* () {
     yield this.linkToInspector();
     let isAttached = yield this.toolbox.walker.isInDOMTree(this._nodeFront);
     if (isAttached) {
       yield this.toolbox.highlighterUtils.highlightNodeFront(this._nodeFront);
     } else {
-      throw null;
+      throw new Error("Node is not attached.");
     }
   }),
 
   /**
    * Unhighlight a previously highlit node
    * @see highlightDomNode
    * @return a promise that resolves when the highlighter has been hidden
    */
-  unhighlightDomNode: function ()
-  {
+  unhighlightDomNode: function () {
     return this.linkToInspector().then(() => {
       return this.toolbox.highlighterUtils.unhighlight();
     }).then(null, e => console.error(e));
   },
 
   /**
    * Open the DOMNode corresponding to the ObjectActor in the inspector panel
    * @return a promise that resolves when the inspector has been switched to
    * and the node has been selected, or rejects if the node cannot be selected
    * (detached from the DOM). Note that in any case, the inspector panel will
    * be switched to.
    */
-  openNodeInInspector: Task.async(function* ()
-  {
+  openNodeInInspector: Task.async(function* () {
     yield this.linkToInspector();
     yield this.toolbox.selectTool("inspector");
 
     let isAttached = yield this.toolbox.walker.isInDOMTree(this._nodeFront);
     if (isAttached) {
       let onReady = promise.defer();
       this.toolbox.inspector.once("inspector-updated", onReady.resolve);
       yield this.toolbox.selection.setNodeFront(this._nodeFront, "console");
       yield onReady.promise;
     } else {
-      throw null;
+      throw new Error("Node is not attached.");
     }
   }),
 
-  destroy: function ()
-  {
+  destroy: function () {
     if (this.toolbox && this._nodeFront) {
       this.element.removeEventListener("mouseover", this.highlightDomNode);
       this.element.removeEventListener("mouseout", this.unhighlightDomNode);
-      this._openInspectorNode.removeEventListener("mousedown", this.openNodeInInspector, true);
+      this._openInspectorNode.removeEventListener("mousedown",
+                                                  this.openNodeInInspector,
+                                                  true);
 
       if (this._linkedToInspector) {
         this.unhighlightDomNode().then(() => {
           this.toolbox = null;
           this._nodeFront = null;
         });
       } else {
         this.toolbox = null;
@@ -3286,18 +3207,17 @@ Widgets.ObjectRenderers.add({
 }); // Widgets.ObjectRenderers.byKind.DOMNode
 
 /**
  * The widget user for displaying Promise objects.
  */
 Widgets.ObjectRenderers.add({
   byClass: "Promise",
 
-  render: function ()
-  {
+  render: function () {
     let { ownProperties, safeGetterValues } = this.objectActor.preview || {};
     if ((!ownProperties && !safeGetterValues) || this.options.concise) {
       this._renderConciseObject();
       return;
     }
 
     this._renderObjectPrefix();
     let container = this.element;
@@ -3370,18 +3290,17 @@ Widgets.ObjectRenderers.add({
 });
 
 /**
  * The widget used for displaying generic JS object previews.
  */
 Widgets.ObjectRenderers.add({
   byKind: "Object",
 
-  render: function ()
-  {
+  render: function () {
     let { ownProperties, safeGetterValues } = this.objectActor.preview || {};
     if ((!ownProperties && !safeGetterValues) || this.options.concise) {
       this._renderConciseObject();
       return;
     }
 
     this._renderObjectPrefix();
     this._renderObjectProperties(this.element, false);
@@ -3395,36 +3314,34 @@ Widgets.ObjectRenderers.add({
  * @constructor
  * @param object message
  *        The owning message.
  * @param object longStringActor
  *        The LongStringActor to display.
  * @param object options
  *        Options, such as noStringQuotes
  */
-Widgets.LongString = function (message, longStringActor, options)
-{
+Widgets.LongString = function (message, longStringActor, options) {
   Widgets.BaseWidget.call(this, message);
   this.longStringActor = longStringActor;
   this.noStringQuotes = (options && "noStringQuotes" in options) ?
     options.noStringQuotes : !this.message._quoteStrings;
 
   this._onClick = this._onClick.bind(this);
   this._onSubstring = this._onSubstring.bind(this);
 };
 
 Widgets.LongString.prototype = extend(Widgets.BaseWidget.prototype, {
   /**
    * The LongStringActor displayed by the widget.
    * @type object
    */
   longStringActor: null,
 
-  render: function ()
-  {
+  render: function () {
     if (this.element) {
       return this;
     }
 
     let result = this.element = this.document.createElementNS(XHTML_NS, "span");
     result.className = "longString console-string";
     this._renderString(this.longStringActor.initial);
     result.appendChild(this._renderEllipsis());
@@ -3433,64 +3350,60 @@ Widgets.LongString.prototype = extend(Wi
   },
 
   /**
    * Render the long string in the widget element.
    * @private
    * @param string str
    *        The string to display.
    */
-  _renderString: function (str)
-  {
+  _renderString: function (str) {
     this.element.textContent = VariablesView.getString(str, {
       noStringQuotes: this.noStringQuotes,
       noEllipsis: true,
     });
   },
 
   /**
    * Render the anchor ellipsis that allows the user to expand the long string.
    *
    * @private
    * @return Element
    */
-  _renderEllipsis: function ()
-  {
+  _renderEllipsis: function () {
     let ellipsis = this.document.createElementNS(XHTML_NS, "a");
     ellipsis.className = "longStringEllipsis";
     ellipsis.textContent = l10n.getStr("longStringEllipsis");
     ellipsis.href = "#";
     ellipsis.draggable = false;
     this.message._addLinkCallback(ellipsis, this._onClick);
 
     return ellipsis;
   },
 
   /**
    * The click event handler for the ellipsis shown after the short string. This
    * function expands the element to show the full string.
    * @private
    */
-  _onClick: function ()
-  {
+  _onClick: function () {
     let longString = this.output.webConsoleClient.longString(this.longStringActor);
     let toIndex = Math.min(longString.length, MAX_LONG_STRING_LENGTH);
 
     longString.substring(longString.initial.length, toIndex, this._onSubstring);
   },
 
   /**
    * The longString substring response callback.
    *
    * @private
    * @param object response
    *        Response packet.
    */
-  _onSubstring: function (response)
-  {
+  _onSubstring: function (response) {
     if (response.error) {
       console.error("LongString substring failure: " + response.error);
       return;
     }
 
     this.element.lastChild.remove();
     this.element.classList.remove("longString");
 
@@ -3507,27 +3420,25 @@ Widgets.LongString.prototype = extend(Wi
       this._logWarningAboutStringTooLong();
     }
   },
 
   /**
    * Inform user that the string he tries to view is too long.
    * @private
    */
-  _logWarningAboutStringTooLong: function ()
-  {
+  _logWarningAboutStringTooLong: function () {
     let msg = new Messages.Simple(l10n.getStr("longStringTooLong"), {
       category: "output",
       severity: "warning",
     });
     this.output.addMessage(msg);
   },
 }); // Widgets.LongString.prototype
 
-
 /**
  * The stacktrace widget.
  *
  * @constructor
  * @extends Widgets.BaseWidget
  * @param object message
  *        The owning message.
  * @param array stacktrace
@@ -3576,18 +3487,17 @@ Widgets.Stacktrace.prototype = extend(Wi
  * @param object message
  *        The owning message.
  * @param array data
  *        Array of objects that holds the data to log in the table.
  * @param object columns
  *        Object containing the key value pair of the id and display name for
  *        the columns in the table.
  */
-Widgets.Table = function (message, data, columns)
-{
+Widgets.Table = function (message, data, columns) {
   Widgets.BaseWidget.call(this, message);
   this.data = data;
   this.columns = columns;
 };
 
 Widgets.Table.prototype = extend(Widgets.BaseWidget.prototype, {
   /**
    * Array of objects that holds the data to output in the table.
@@ -3620,17 +3530,16 @@ Widgets.Table.prototype = extend(Widgets
     for (let row of this.data) {
       this.table.push(row);
     }
 
     return this;
   }
 }); // Widgets.Table.prototype
 
-function gSequenceId()
-{
+function gSequenceId() {
   return gSequenceId.n++;
 }
 gSequenceId.n = 0;
 
 exports.ConsoleOutput = ConsoleOutput;
 exports.Messages = Messages;
 exports.Widgets = Widgets;