Bug 1278733: Turn on JSDoc validation, and fix basic errors in existing comments. r?aswan draft
authorKris Maglione <maglione.k@gmail.com>
Tue, 07 Jun 2016 18:36:19 -0700
changeset 376469 2fd4c9ff0bbe10915c0e68e5e7950d38433fa5fb
parent 376468 a7b31be0a19ae5413db3e10ad4e5251cac84b08d
child 523158 43bee6f44b576696fe1784186a65b42eb25c5d59
push id20583
push usermaglione.k@gmail.com
push dateWed, 08 Jun 2016 01:36:56 +0000
reviewersaswan
bugs1278733
milestone50.0a1
Bug 1278733: Turn on JSDoc validation, and fix basic errors in existing comments. r?aswan MozReview-Commit-ID: EZpOyvoi2h0
browser/components/extensions/ext-commands.js
browser/components/extensions/ext-pageAction.js
browser/components/extensions/test/browser/browser_ext_tabs_onHighlighted.js
toolkit/components/extensions/.eslintrc
toolkit/components/extensions/Extension.jsm
toolkit/components/extensions/ExtensionStorage.jsm
toolkit/components/extensions/ExtensionUtils.jsm
toolkit/components/extensions/MessageChannel.jsm
toolkit/components/extensions/Schemas.jsm
toolkit/components/extensions/test/mochitest/test_ext_content_security_policy.html
toolkit/modules/addons/WebNavigation.jsm
toolkit/modules/addons/WebNavigationFrames.jsm
--- a/browser/components/extensions/ext-commands.js
+++ b/browser/components/extensions/ext-commands.js
@@ -60,17 +60,19 @@ CommandList.prototype = {
       }
     }
 
     WindowListManager.removeOpenListener(this.windowOpenListener);
   },
 
   /**
    * Creates a Map from commands for each command in the manifest.commands object.
+   *
    * @param {Object} manifest The manifest JSON object.
+   * @returns {Map<string, object>}
    */
   loadCommandsFromManifest(manifest) {
     let commands = new Map();
     // For Windows, chrome.runtime expects 'win' while chrome.commands
     // expects 'windows'.  We can special case this for now.
     let os = PlatformInfo.os == "win" ? "windows" : PlatformInfo.os;
     for (let name of Object.keys(manifest.commands)) {
       let command = manifest.commands[name];
@@ -99,18 +101,18 @@ CommandList.prototype = {
     this.keysetsMap.set(window, keyset);
   },
 
   /**
    * Builds a XUL Key element and attaches an onCommand listener which
    * emits a command event with the provided name when fired.
    *
    * @param {Document} doc The XUL document.
-   * @param {String} name The name of the command.
-   * @param {String} shortcut The shortcut provided in the manifest.
+   * @param {string} name The name of the command.
+   * @param {string} shortcut The shortcut provided in the manifest.
    * @see https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XUL/key
    *
    * @returns {Document} The newly created Key element.
    */
   buildKey(doc, name, shortcut) {
     let keyElement = this.buildKeyFromShortcut(doc, shortcut);
 
     // We need to have the attribute "oncommand" for the "command" listener to fire,
@@ -132,18 +134,17 @@ CommandList.prototype = {
 
     return keyElement;
   },
 
   /**
    * Builds a XUL Key element from the provided shortcut.
    *
    * @param {Document} doc The XUL document.
-   * @param {String} name The name of the command.
-   * @param {String} shortcut The shortcut provided in the manifest.
+   * @param {string} shortcut The shortcut provided in the manifest.
    *
    * @see https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XUL/key
    * @returns {Document} The newly created Key element.
    */
   buildKeyFromShortcut(doc, shortcut) {
     let keyElement = doc.createElementNS(XUL_NS, "key");
 
     let parts = shortcut.split("+");
@@ -169,35 +170,35 @@ CommandList.prototype = {
    *
    * For example:
    *
    *    input     |  output
    *    ---------------------------------------
    *    "PageUP"  |  "VK_PAGE_UP"
    *    "Delete"  |  "VK_DELETE"
    *
-   * @param {String} key The chrome key (e.g. "PageUp", "Space", ...)
-   * @return The constructed value for the Key's 'keycode' attribute.
+   * @param {string} chromeKey The chrome key (e.g. "PageUp", "Space", ...)
+   * @returns {string} The constructed value for the Key's 'keycode' attribute.
    */
   getKeycodeAttribute(chromeKey) {
     return `VK${chromeKey.replace(/([A-Z])/g, "_$&").toUpperCase()}`;
   },
 
   /**
    * Determines the corresponding XUL modifiers from the chrome modifiers.
    *
    * For example:
    *
    *    input             |   output
    *    ---------------------------------------
    *    ["Ctrl", "Shift"] |   "accel shift"
    *    ["MacCtrl"]       |   "control"
    *
    * @param {Array} chromeModifiers The array of chrome modifiers.
-   * @return The constructed value for the Key's 'modifiers' attribute.
+   * @returns {string} The constructed value for the Key's 'modifiers' attribute.
    */
   getModifiersAttribute(chromeModifiers) {
     let modifiersMap = {
       "Alt": "alt",
       "Command": "accel",
       "Ctrl": "accel",
       "MacCtrl": "control",
       "Shift": "shift",
--- a/browser/components/extensions/ext-pageAction.js
+++ b/browser/components/extensions/ext-pageAction.js
@@ -129,16 +129,18 @@ PageAction.prototype = {
     return this.buttons.get(window);
   },
 
   /**
    * Triggers this page action for the given window, with the same effects as
    * if it were clicked by a user.
    *
    * This has no effect if the page action is hidden for the selected tab.
+   *
+   * @param {Window} window
    */
   triggerAction(window) {
     let pageAction = pageActionMap.get(this.extension);
     if (pageAction.getProperty(window.gBrowser.selectedTab, "show")) {
       pageAction.handleClick(window);
     }
   },
 
--- a/browser/components/extensions/test/browser/browser_ext_tabs_onHighlighted.js
+++ b/browser/components/extensions/test/browser/browser_ext_tabs_onHighlighted.js
@@ -31,16 +31,20 @@ add_task(function* testTabEvents() {
       } else {
         events[info.tabIds[0]] = ["onHighlighted"];
       }
     });
 
     /**
      * Asserts that the expected events are fired for the tab with id = tabId.
      * The events associated to the specified tab are removed after this check is made.
+     *
+     * @param {number} tabId
+     * @param {Array<string>} expectedEvents
+     * @returns {Promise}
      */
     function expectEvents(tabId, expectedEvents) {
       browser.test.log(`Expecting events: ${expectedEvents.join(", ")}`);
 
       return new Promise(resolve => {
         setTimeout(resolve, 0);
       }).then(() => {
         browser.test.assertEq(expectedEvents.length, events[tabId].length,
@@ -50,30 +54,36 @@ add_task(function* testTabEvents() {
                                 `Got expected ${name} event`);
         }
         delete events[tabId];
       });
     }
 
     /**
      * Opens a new tab and asserts that the correct events are fired.
+     *
+     * @param {number} windowId
+     * @returns {Promise}
      */
     function openTab(windowId) {
       return browser.tabs.create({windowId}).then(tab => {
         tabIds.push(tab.id);
         browser.test.log(`Opened tab ${tab.id}`);
         return expectEvents(tab.id, [
           "onActivated",
           "onHighlighted",
         ]);
       });
     }
 
     /**
      * Highlights an existing tab and asserts that the correct events are fired.
+     *
+     * @param {number} tabId
+     * @returns {Promise}
      */
     function highlightTab(tabId) {
       browser.test.log(`Highlighting tab ${tabId}`);
       return browser.tabs.update(tabId, {active: true}).then(tab => {
         browser.test.assertEq(tab.id, tabId, `Tab ${tab.id} highlighted`);
         return expectEvents(tab.id, [
           "onActivated",
           "onHighlighted",
--- a/toolkit/components/extensions/.eslintrc
+++ b/toolkit/components/extensions/.eslintrc
@@ -30,16 +30,31 @@
   "rules": {
     // Rules from the mozilla plugin
     "mozilla/balanced-listeners": 2,
     "mozilla/mark-test-function-used": 1,
     "mozilla/no-aArgs": 1,
     "mozilla/no-cpows-in-tests": 1,
     "mozilla/var-only-at-top-level": 1,
 
+    "valid-jsdoc": [2, {
+      "prefer": {
+        "return": "returns",
+      },
+      "preferType": {
+        "Boolean": "boolean",
+        "Number": "number",
+        "String": "string",
+        "bool": "boolean",
+      },
+      "requireParamDescription": false,
+      "requireReturn": false,
+      "requireReturnDescription": false,
+    }],
+
     // Braces only needed for multi-line arrow function blocks
     // "arrow-body-style": [2, "as-needed"],
 
     // Require spacing around =>
     "arrow-spacing": 2,
 
     // Always require spacing around a single line block
     "block-spacing": 1,
@@ -441,19 +456,16 @@
     "sort-vars": 0,
 
     // Require a space immediately following the // in a line comment.
     "spaced-comment": [2, "always"],
 
     // Require "use strict" to be defined globally in the script.
     "strict": [2, "global"],
 
-    // Warn about invalid JSDoc comments.
-    "valid-jsdoc": 0,
-
     // Allow vars to be declared anywhere in the scope.
     "vars-on-top": 0,
 
     // Don't require immediate function invocation to be wrapped in parentheses.
     "wrap-iife": 0,
 
     // Don't require regex literals to be wrapped in parentheses (which
     // supposedly prevent them from being mistaken for division operators).
--- a/toolkit/components/extensions/Extension.jsm
+++ b/toolkit/components/extensions/Extension.jsm
@@ -1073,16 +1073,20 @@ this.Extension = function(addonData) {
  *     Directories should appear here only implicitly (as a prefix
  *     to file names)
  *
  * To make things easier, the value of "background" and "files"[] can
  * be a function, which is converted to source that is run.
  *
  * The generated extension is stored in the system temporary directory,
  * and an nsIFile object pointing to it is returned.
+ *
+ * @param {string} id
+ * @param {object} data
+ * @returns {nsIFile}
  */
 this.Extension.generateXPI = function(id, data) {
   let manifest = data.manifest;
   if (!manifest) {
     manifest = {};
   }
 
   let files = data.files;
@@ -1166,16 +1170,20 @@ this.Extension.generateXPI = function(id
 
   return file;
 };
 
 /**
  * A skeleton Extension-like object, used for testing, which installs an
  * add-on via the add-on manager when startup() is called, and
  * uninstalles it on shutdown().
+ *
+ * @param {string} id
+ * @param {nsIFile} file
+ * @param {nsIURI} rootURI
  */
 function MockExtension(id, file, rootURI) {
   this.id = id;
   this.file = file;
   this.rootURI = rootURI;
 
   this._extension = null;
   this._extensionPromise = new Promise(resolve => {
@@ -1224,16 +1232,20 @@ MockExtension.prototype = {
     flushJarCache(this.file);
     return OS.File.remove(this.file.path);
   },
 };
 
 /**
  * Generates a new extension using |Extension.generateXPI|, and initializes a
  * new |Extension| instance which will execute it.
+ *
+ * @param {string} id
+ * @param {object} data
+ * @returns {Extension}
  */
 this.Extension.generate = function(id, data) {
   let file = this.generateXPI(id, data);
 
   flushJarCache(file);
   Services.ppmm.broadcastAsyncMessage("Extension:FlushJarCache", {path: file.path});
 
   let fileURI = Services.io.newFileURI(file);
--- a/toolkit/components/extensions/ExtensionStorage.jsm
+++ b/toolkit/components/extensions/ExtensionStorage.jsm
@@ -63,16 +63,23 @@ this.ExtensionStorage = {
   cache: new Map(),
   listeners: new Map(),
 
   extensionDir: Path.join(profileDir, "browser-extension-data"),
 
   /**
    * Sanitizes the given value, and returns a JSON-compatible
    * representation of it, based on the privileges of the given global.
+   *
+   * @param {value} value
+   *        The value to sanitize.
+   * @param {object} global
+   *        The global for which to sanitize the value.
+   * @returns {value}
+   *        The sanitized value.
    */
   sanitize(value, global) {
     // We can't trust that the global has privileges to access this
     // value enough to clone it using a privileged JSON object.
     let JSON_ = Cu.waiveXrays(global.JSON);
 
     let json = JSON_.stringify(value, jsonReplacer);
     return JSON.parse(json);
--- a/toolkit/components/extensions/ExtensionUtils.jsm
+++ b/toolkit/components/extensions/ExtensionUtils.jsm
@@ -203,16 +203,25 @@ class BaseContext {
   forgetOnClose(obj) {
     this.onClose.delete(obj);
   }
 
   /**
    * A wrapper around MessageChannel.sendMessage which adds the extension ID
    * to the recipient object, and ensures replies are not processed after the
    * context has been unloaded.
+   *
+   * @param {nsIMessageManager} target
+   * @param {string} messageName
+   * @param {object} data
+   * @param {object} [options]
+   * @param {object} [options.sender]
+   * @param {object} [options.recipient]
+   *
+   * @returns {Promise}
    */
   sendMessage(target, messageName, data, options = {}) {
     options.recipient = options.recipient || {};
     options.sender = options.sender || {};
 
     options.recipient.extensionId = this.extension.id;
     options.sender.extensionId = this.extension.id;
     options.sender.contextId = this.contextId;
@@ -233,16 +242,19 @@ class BaseContext {
   /**
    * Normalizes the given error object for use by the target scope. If
    * the target is an error object which belongs to that scope, it is
    * returned as-is. If it is an ordinary object with a `message`
    * property, it is converted into an error belonging to the target
    * scope. If it is an Error object which does *not* belong to the
    * clone scope, it is reported, and converted to an unexpected
    * exception error.
+   *
+   * @param {Error|object} error
+   * @returns {Error}
    */
   normalizeError(error) {
     if (error instanceof this.cloneScope.Error) {
       return error;
     }
     if (!instanceOf(error, "Object")) {
       Cu.reportError(error);
       error = {message: "An unexpected error occurred"};
--- a/toolkit/components/extensions/MessageChannel.jsm
+++ b/toolkit/components/extensions/MessageChannel.jsm
@@ -133,16 +133,17 @@ class FilteringMessageManager {
    *         An object containing either a `handler` or an `error` property.
    *         If no error occurs, `handler` will be a matching handler that
    *         was registered by `addHandler`. Otherwise, the `error` property
    *         will contain an object describing the error.
    *
    *        data:
    *          An object describing the message, as defined in
    *          `MessageChannel.addListener`.
+   * @param {nsIMessageManager} messageManager
    */
   constructor(messageName, callback, messageManager) {
     this.messageName = messageName;
     this.callback = callback;
     this.messageManager = messageManager;
 
     this.messageManager.addMessageListener(this.messageName, this);
 
@@ -346,17 +347,17 @@ this.MessageChannel = {
    *    The filter object to match against.
    * @param {object} data
    *    The data object being matched.
    * @param {boolean} [strict=false]
    *    If true, all properties in the `filter` object have a
    *    corresponding property in `data` with the same value. If
    *    false, properties present in both objects must have the same
    *    balue.
-   * @returns {bool} True if the objects match.
+   * @returns {boolean} True if the objects match.
    */
   matchesFilter(filter, data, strict = true) {
     if (strict) {
       return Object.keys(filter).every(key => {
         return key in data && data[key] === filter[key];
       });
     }
     return Object.keys(filter).every(key => {
@@ -424,18 +425,17 @@ this.MessageChannel = {
     for (let target of [].concat(targets)) {
       this.messageManagers.get(target).addHandler(messageName, handler);
     }
   },
 
   /**
    * Removes a message listener from the given message manager.
    *
-   * @param {nsIMessageSender} target
-   * @param {nsIMessageSender|[nsIMessageSender]} targets
+   * @param {nsIMessageSender|Array<nsIMessageSender>} targets
    *    The message managers on which to stop listening.
    * @param {string|number} messageName
    *    The name of the message to stop listening for.
    * @param {MessageReceiver} handler
    *    The handler to stop dispatching to.
    */
   removeListener(targets, messageName, handler) {
     for (let target of [].concat(targets)) {
@@ -469,17 +469,17 @@ this.MessageChannel = {
    * @param {object} [options.sender]
    *    A structured-clone-compatible object to identify the message
    *    sender. This object may also be used as a filter to prematurely
    *    abort responses when the sender is being destroyed.
    *    @see `abortResponses`.
    * @param {integer} [options.responseType=RESPONSE_SINGLE]
    *    Specifies the type of response expected. See the `RESPONSE_*`
    *    contents for details.
-   * @returns Promise
+   * @returns {Promise}
    */
   sendMessage(target, messageName, data, options = {}) {
     let sender = options.sender || {};
     let recipient = options.recipient || {};
     let responseType = options.responseType || this.RESPONSE_SINGLE;
 
     let channelId = gChannelId++;
     let message = {messageName, channelId, sender, recipient, data, responseType};
@@ -555,16 +555,20 @@ this.MessageChannel = {
 
   /**
    * Handles dispatching message callbacks from the message brokers to their
    * appropriate `MessageReceivers`, and routing the responses back to the
    * original senders.
    *
    * Each handler object is a `MessageReceiver` object as passed to
    * `addListener`.
+   *
+   * @param {Array<MessageHandler>} handlers
+   * @param {object} data
+   * @param {nsIMessageSender|nsIMessageManagerOwner} data.target
    */
   _handleMessage(handlers, data) {
     // The target passed to `receiveMessage` is sometimes a message manager
     // owner instead of a message manager, so make sure to convert it to a
     // message manager first if necessary.
     let {target} = data;
     if (!(target instanceof Ci.nsIMessageSender)) {
       target = target.messageManager;
@@ -617,16 +621,20 @@ this.MessageChannel = {
     this._addPendingResponse(deferred);
   },
 
   /**
    * Handles message callbacks from the response brokers.
    *
    * Each handler object is a deferred object created by `sendMessage`, and
    * should be resolved or rejected based on the contents of the response.
+   *
+   * @param {Array<MessageHandler>} handlers
+   * @param {object} data
+   * @param {nsIMessageSender|nsIMessageManagerOwner} data.target
    */
   _handleResponse(handlers, data) {
     // If we have an error at this point, we have handler to report it to,
     // so just log it.
     if (handlers.length == 0) {
       Cu.reportError(`No matching message response handler for ${data.messageName}`);
     } else if (handlers.length > 1) {
       Cu.reportError(`Multiple matching response handlers for ${data.messageName}`);
@@ -657,16 +665,18 @@ this.MessageChannel = {
    *  messageManager:
    *    The message manager the response will be sent or received on.
    *
    * When the promise resolves or rejects, it will be removed from the
    * list.
    *
    * These values are used to clear pending responses when execution
    * contexts are destroyed.
+   *
+   * @param {Deferred} deferred
    */
   _addPendingResponse(deferred) {
     let cleanup = () => {
       this.pendingResponses.delete(deferred);
     };
     this.pendingResponses.add(deferred);
     deferred.promise.then(cleanup, cleanup);
   },
--- a/toolkit/components/extensions/Schemas.jsm
+++ b/toolkit/components/extensions/Schemas.jsm
@@ -140,43 +140,51 @@ class Context {
   }
 
   /**
    * Returns an error result object with the given message, for return
    * by Type normalization functions.
    *
    * If the context has a `currentTarget` value, this is prepended to
    * the message to indicate the location of the error.
+   *
+   * @param {string} message
+   * @returns {object}
    */
   error(message) {
     if (this.currentTarget) {
       return {error: `Error processing ${this.currentTarget}: ${message}`};
     }
     return {error: message};
   }
 
   /**
    * Creates an `Error` object belonging to the current unprivileged
    * scope. If there is no unprivileged scope associated with this
    * context, the message is returned as a string.
    *
    * If the context has a `currentTarget` value, this is prepended to
    * the message, in the same way as for the `error` method.
+   *
+   * @param {string} message
+   * @returns {Error}
    */
   makeError(message) {
     let {error} = this.error(message);
     if (this.cloneScope) {
       return new this.cloneScope.Error(error);
     }
     return error;
   }
 
   /**
    * Logs the given error to the console. May be overridden to enable
    * custom logging.
+   *
+   * @param {Error|string} error
    */
   logError(error) {
     Cu.reportError(error);
   }
 
   /**
    * Returns the name of the value currently being normalized. For a
    * nested object, this is usually approximately equivalent to the
@@ -193,16 +201,20 @@ class Context {
 
   /**
    * Appends the given component to the `currentTarget` path to indicate
    * that it is being processed, calls the given callback function, and
    * then restores the original path.
    *
    * This is used to identify the path of the property being processed
    * when reporting type errors.
+   *
+   * @param {string} component
+   * @param {function} callback
+   * @returns {*}
    */
   withPath(component, callback) {
     this.path.push(component);
     try {
       return callback();
     } finally {
       this.path.pop();
     }
@@ -304,37 +316,45 @@ class Entry {
      * message will be emitted.
      */
     this.deprecated = false;
     if ("deprecated" in schema) {
       this.deprecated = schema.deprecated;
     }
 
     /**
+     * @property {string} [preprocessor]
      * If set to a string value, and a preprocessor of the same is
      * defined in the validation context, it will be applied to this
      * value prior to any normalization.
      */
     this.preprocessor = schema.preprocess || null;
   }
 
   /**
    * Preprocess the given value with the preprocessor declared in
    * `preprocessor`.
+   *
+   * @param {*} value
+   * @param {Context} context
+   * @returns {*}
    */
   preprocess(value, context) {
     if (this.preprocessor) {
       return context.preprocessors[this.preprocessor](value, context);
     }
     return value;
   }
 
   /**
    * Logs a deprecation warning for this entry, based on the value of
    * its `deprecated` property.
+   *
+   * @param {Context} context
+   * @param {value} [value]
    */
   logDeprecation(context, value = null) {
     let message = "This property is deprecated";
     if (typeof(this.deprecated) == "string") {
       message = this.deprecated;
       if (message.includes("${value}")) {
         try {
           value = JSON.stringify(value);
@@ -346,16 +366,19 @@ class Entry {
     }
 
     context.logError(context.makeError(message));
   }
 
   /**
    * Checks whether the entry is deprecated and, if so, logs a
    * deprecation message.
+   *
+   * @param {Context} context
+   * @param {value} [value]
    */
   checkDeprecated(context, value = null) {
     if (this.deprecated) {
       this.logDeprecation(context, value);
     }
   }
 
   // Injects JS values for the entry into the extension API
--- a/toolkit/components/extensions/test/mochitest/test_ext_content_security_policy.html
+++ b/toolkit/components/extensions/test/mochitest/test_ext_content_security_policy.html
@@ -13,16 +13,18 @@
 <script type="text/javascript">
 "use strict";
 
 /**
  * Tests that content security policies for an add-on are actually applied to *
  * documents that belong to it. This tests both the base policies and add-on
  * specific policies, and ensures that the parsed policies applied to the
  * document's principal match what was specified in the policy string.
+ *
+ * @param {object} [customCSP]
  */
 function* testPolicy(customCSP = null) {
   let baseURL;
 
   let baseCSP = {
     "object-src": ["blob:", "filesystem:", "https://*", "moz-extension:", "'self'"],
     "script-src": ["'unsafe-eval'", "'unsafe-inline'", "blob:", "filesystem:", "https://*", "moz-extension:", "'self'"],
   };
--- a/toolkit/modules/addons/WebNavigation.jsm
+++ b/toolkit/modules/addons/WebNavigation.jsm
@@ -80,56 +80,62 @@ var Manager = {
     }
 
     if (this.listeners.size == 0) {
       this.uninit();
     }
   },
 
   /**
-   *  Support nsIObserver interface to observe the urlbar autocomplete events used
-   *  to keep track of the urlbar user interaction.
+   * Support nsIObserver interface to observe the urlbar autocomplete events used
+   * to keep track of the urlbar user interaction.
    */
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
 
   /**
-   *  Observe autocomplete-did-enter-text topic to track the user interaction with
-   *  the awesome bar.
+   * Observe autocomplete-did-enter-text topic to track the user interaction with
+   * the awesome bar.
+   *
+   * @param {nsIAutoCompleteInput} subject
+   * @param {string} topic
+   * @param {string} data
    */
   observe: function(subject, topic, data) {
     if (topic == "autocomplete-did-enter-text") {
       this.onURLBarAutoCompletion(subject, topic, data);
     }
   },
 
   /**
-   *  Recognize the type of urlbar user interaction (e.g. typing a new url,
-   *  clicking on an url generated from a searchengine or a keyword, or a
-   *  bookmark found by the urlbar autocompletion).
+   * Recognize the type of urlbar user interaction (e.g. typing a new url,
+   * clicking on an url generated from a searchengine or a keyword, or a
+   * bookmark found by the urlbar autocompletion).
+   *
+   * @param {nsIAutoCompleteInput} input
    */
-  onURLBarAutoCompletion(subject, topic, data) {
-    if (subject && subject instanceof Ci.nsIAutoCompleteInput) {
+  onURLBarAutoCompletion(input) {
+    if (input && input instanceof Ci.nsIAutoCompleteInput) {
       // We are only interested in urlbar autocompletion events
-      if (subject.id !== "urlbar") {
+      if (input.id !== "urlbar") {
         return;
       }
 
-      let controller = subject.popup.view.QueryInterface(Ci.nsIAutoCompleteController);
-      let idx = subject.popup.selectedIndex;
+      let controller = input.popup.view.QueryInterface(Ci.nsIAutoCompleteController);
+      let idx = input.popup.selectedIndex;
 
       let tabTransistionData = {
         from_address_bar: true,
       };
 
       if (idx < 0 || idx >= controller.matchCount) {
         // Recognize when no valid autocomplete results has been selected.
         tabTransistionData.typed = true;
       } else {
         let value = controller.getValueAt(idx);
-        let action = subject._parseActionUrl(value);
+        let action = input._parseActionUrl(value);
 
         if (action) {
           // Detect keywork and generated and more typed scenarios.
           switch (action.type) {
             case "keyword":
               tabTransistionData.keyword = true;
               break;
             case "searchengine":
@@ -169,18 +175,26 @@ var Manager = {
         }
       }
 
       this.setRecentTabTransitionData(tabTransistionData);
     }
   },
 
   /**
-   *  Keep track of a recent user interaction and cache it in a
-   *  map associated to the current selected tab.
+   * Keep track of a recent user interaction and cache it in a
+   * map associated to the current selected tab.
+   *
+   * @param {object} tabTransitionData
+   * @param {boolean} [tabTransitionData.auto_bookmark]
+   * @param {boolean} [tabTransitionData.from_address_bar]
+   * @param {boolean} [tabTransitionData.generated]
+   * @param {boolean} [tabTransitionData.keyword]
+   * @param {boolean} [tabTransitionData.link]
+   * @param {boolean} [tabTransitionData.typed]
    */
   setRecentTabTransitionData(tabTransitionData) {
     let window = RecentWindow.getMostRecentBrowserWindow();
     if (window && window.gBrowser && window.gBrowser.selectedTab &&
         window.gBrowser.selectedTab.linkedBrowser) {
       let browser = window.gBrowser.selectedTab.linkedBrowser;
 
       // Get recent tab transition data to update if any.
@@ -191,40 +205,43 @@ var Manager = {
         prevData,
         tabTransitionData
       );
       this.recentTabTransitionData.set(browser, newData);
     }
   },
 
   /**
-   *  Retrieve recent data related to a recent user interaction give a
-   *  given tab's linkedBrowser (only if is is more recent than the
-   *  `RECENT_DATA_THRESHOLD`).
+   * Retrieve recent data related to a recent user interaction give a
+   * given tab's linkedBrowser (only if is is more recent than the
+   * `RECENT_DATA_THRESHOLD`).
    *
-   *  NOTE: this method is used to retrieve the tab transition data
-   *  collected when one of the `onCommitted`, `onHistoryStateUpdated`
-   *  or `onReferenceFragmentUpdated` events has been received.
+   * NOTE: this method is used to retrieve the tab transition data
+   * collected when one of the `onCommitted`, `onHistoryStateUpdated`
+   * or `onReferenceFragmentUpdated` events has been received.
+   *
+   * @param {XULBrowserElement} browser
+   * @returns {object}
    */
   getAndForgetRecentTabTransitionData(browser) {
     let data = this.recentTabTransitionData.get(browser);
     this.recentTabTransitionData.delete(browser);
 
     // Return an empty object if there isn't any tab transition data
     // or if it's less recent than RECENT_DATA_THRESHOLD.
     if (!data || (data.time - Date.now()) > RECENT_DATA_THRESHOLD) {
       return {};
     }
 
     return data;
   },
 
   /**
-   *  Receive messages from the WebNavigationContent.js framescript
-   *  over message manager events.
+   * Receive messages from the WebNavigationContent.js framescript
+   * over message manager events.
    */
   receiveMessage({name, data, target}) {
     switch (name) {
       case "Extension:StateChange":
         this.onStateChange(target, data);
         break;
 
       case "Extension:DocumentChange":
--- a/toolkit/modules/addons/WebNavigationFrames.jsm
+++ b/toolkit/modules/addons/WebNavigationFrames.jsm
@@ -19,17 +19,17 @@ function getWindowId(window) {
 function getParentWindowId(window) {
   return getWindowId(window.parent);
 }
 
 /**
  * Retrieve the DOMWindow associated to the docShell passed as parameter.
  *
  * @param    {nsIDocShell}  docShell - the docShell that we want to get the DOMWindow from.
- * @return   {nsIDOMWindow}          - the DOMWindow associated to the docShell.
+ * @returns  {nsIDOMWindow}          - the DOMWindow associated to the docShell.
  */
 function docShellToWindow(docShell) {
   return docShell.QueryInterface(Ci.nsIInterfaceRequestor)
                  .getInterface(Ci.nsIDOMWindow);
 }
 
 /**
  * The FrameDetail object which represents a frame in WebExtensions APIs.
@@ -42,33 +42,33 @@ function docShellToWindow(docShell) {
  * @property {boolean} errorOccurred  - Indicates whether an error is occurred during the last load
  *                                      happened on this frame (NOT YET SUPPORTED).
  */
 
 /**
  * Convert a docShell object into its internal FrameDetail representation.
  *
  * @param    {nsIDocShell} docShell - the docShell object to be converted into a FrameDetail JSON object.
- * @return   {FrameDetail} the FrameDetail JSON object which represents the docShell.
+ * @returns  {FrameDetail} the FrameDetail JSON object which represents the docShell.
  */
 function convertDocShellToFrameDetail(docShell) {
   let window = docShellToWindow(docShell);
 
   return {
     windowId: getWindowId(window),
     parentWindowId: getParentWindowId(window),
     url: window.location.href,
   };
 }
 
 /**
  * A generator function which iterates over a docShell tree, given a root docShell.
  *
- * @param  {nsIDocShell} docShell - the root docShell object
- * @return {Iterator<DocShell>} the FrameDetail JSON object which represents the docShell.
+ * @param   {nsIDocShell} docShell - the root docShell object
+ * @returns {Iterator<DocShell>} the FrameDetail JSON object which represents the docShell.
  */
 function* iterateDocShellTree(docShell) {
   let docShellsEnum = docShell.getDocShellEnumerator(
     Ci.nsIDocShellTreeItem.typeContent,
     Ci.nsIDocShell.ENUMERATE_FORWARDS
   );
 
   while (docShellsEnum.hasMoreElements()) {
@@ -99,19 +99,19 @@ function getFrameId(window) {
 }
 
 /**
  * Search for a frame starting from the passed root docShell and
  * convert it to its related frame detail representation.
  *
  * @param  {number}      frameId - the frame ID of the frame to retrieve, as
  *                                 described in getFrameId.
- * @param  {nsIDocShell} docShell - the root docShell object
- * @return {nsIDocShell?} the docShell with the given frameId, or null
- *                        if no match.
+ * @param   {nsIDocShell} rootDocShell - the root docShell object
+ * @returns {nsIDocShell?} the docShell with the given frameId, or null
+ *                         if no match.
  */
 function findDocShell(frameId, rootDocShell) {
   for (let docShell of iterateDocShellTree(rootDocShell)) {
     if (frameId == getFrameId(docShellToWindow(docShell))) {
       return docShell;
     }
   }