diff --git a/core/modules/ckeditor/js/ckeditor.admin.js b/core/modules/ckeditor/js/ckeditor.admin.js
index ff75541..24ebfb4 100644
--- a/core/modules/ckeditor/js/ckeditor.admin.js
+++ b/core/modules/ckeditor/js/ckeditor.admin.js
@@ -2,12 +2,16 @@
  * @file
  * CKEditor button and group configuration user interface.
  */
+
 (function ($, Drupal, _, CKEDITOR) {
 
   "use strict";
 
   Drupal.ckeditor = Drupal.ckeditor || {};
 
+  /**
+   * @type {Drupal~behavior}
+   */
   Drupal.behaviors.ckeditorAdmin = {
     attach: function (context) {
       // Process the CKEditor configuration fragment once.
@@ -69,13 +73,23 @@
 
   /**
    * CKEditor configuration UI methods of Backbone objects.
+   *
+   * @namespace
    */
   Drupal.ckeditor = {
 
-    // A hash of View instances.
+    /**
+     * A hash of View instances.
+     *
+     * @type {object}
+     */
     views: {},
 
-    // A hash of Model instances.
+    /**
+     * A hash of Model instances.
+     *
+     * @type {object}
+     */
     models: {},
 
     /**
@@ -86,11 +100,11 @@
      * placeholder, then a process is launched to name that group before the button
      * move is translated into configuration.
      *
-     * @param Backbone.View view
+     * @param {Backbone.View} view
      *   The Backbone View that invoked this function.
-     * @param jQuery $button
+     * @param {jQuery} $button
      *   A jQuery set that contains an li element that wraps a button element.
-     * @param function callback
+     * @param {function} callback
      *   A callback to invoke after the button group naming modal dialog has been
      *   closed.
      */
@@ -118,9 +132,9 @@
      * Each row has a placeholder group at the end of the row. A user may not move
      * an existing button group past the placeholder group at the end of a row.
      *
-     * @param Backbone.View view
+     * @param {Backbone.View} view
      *   The Backbone View that invoked this function.
-     * @param jQuery $group
+     * @param {jQuery} $group
      *   A jQuery set that contains an li element that wraps a group of buttons.
      */
     registerGroupMove: function (view, $group) {
@@ -143,11 +157,11 @@
     /**
      * Opens a Drupal dialog with a form for changing the title of a button group.
      *
-     * @param Backbone.View view
+     * @param {Backbone.View} view
      *   The Backbone View that invoked this function.
-     * @param jQuery $group
+     * @param {jQuery} $group
      *   A jQuery set that contains an li element that wraps a group of buttons.
-     * @param function callback
+     * @param {function} callback
      *   A callback to invoke after the button group naming modal dialog has been
      *   closed.
      */
@@ -157,10 +171,11 @@
       /**
        * Validates the string provided as a button group title.
        *
-       * @param DOM form
+       * @param {HTMLElement} form
        *   The form DOM element that contains the input with the new button group
        *   title string.
-       * @return Boolean
+       *
+       * @return {bool}
        *   Returns true when an error exists, otherwise returns false.
        */
       function validateForm(form) {
@@ -182,9 +197,9 @@
       /**
        * Attempts to close the dialog; Validates user input.
        *
-       * @param String action
+       * @param {string} action
        *   The dialog action chosen by the user: 'apply' or 'cancel'.
-       * @param DOM form
+       * @param {HTMLElement} form
        *   The form DOM element that contains the input with the new button group
        *   title string.
        */
@@ -203,9 +218,9 @@
         /**
          * Applies a string as the name of a CKEditor button group.
          *
-         * @param jQuery $group
+         * @param {jQuery} $group
          *   A jQuery set that contains an li element that wraps a group of buttons.
-         * @param String name
+         * @param {string} name
          *   The new name of the CKEditor button group.
          */
         function namePlaceholderGroup($group, name) {
@@ -336,9 +351,10 @@
 
   };
 
-
   /**
    * Automatically shows/hides settings of buttons-only CKEditor plugins.
+   *
+   * @type {Drupal~behavior}
    */
   Drupal.behaviors.ckeditorAdminButtonPluginSettings = {
     attach: function (context) {
@@ -411,7 +427,7 @@
   /**
    * Themes a blank CKEditor row.
    *
-   * @return String
+   * @return {string}
    */
   Drupal.theme.ckeditorRow = function () {
     return '<li class="ckeditor-row placeholder" role="group"><ul class="ckeditor-toolbar-groups clearfix"></ul></li>';
@@ -420,7 +436,7 @@
   /**
    * Themes a blank CKEditor button group.
    *
-   * @return String
+   * @return {string}
    */
   Drupal.theme.ckeditorToolbarGroup = function () {
     var group = '';
@@ -434,7 +450,7 @@
   /**
    * Themes a form for changing the title of a CKEditor button group.
    *
-   * @return String
+   * @return {string}
    */
   Drupal.theme.ckeditorButtonGroupNameForm = function () {
     return '<form><input name="group-name" required="required"></form>';
@@ -443,7 +459,7 @@
   /**
    * Themes a button that will toggle the button group names in active config.
    *
-   * @return String
+   * @return {string}
    */
   Drupal.theme.ckeditorButtonGroupNamesToggle = function () {
     return '<a class="ckeditor-groupnames-toggle" role="button" aria-pressed="false"></a>';
@@ -452,7 +468,7 @@
   /**
    * Themes a button that will prompt the user to name a new button group.
    *
-   * @return String
+   * @return {string}
    */
   Drupal.theme.ckeditorNewButtonGroup = function () {
     return '<li class="ckeditor-add-new-group"><button role="button" aria-label="' + Drupal.t('Add a CKEditor button group to the end of this row.') + '">' + Drupal.t('Add group') + '</button></li>';
diff --git a/core/modules/ckeditor/js/ckeditor.drupalimage.admin.js b/core/modules/ckeditor/js/ckeditor.drupalimage.admin.js
index 44072df..8989717 100644
--- a/core/modules/ckeditor/js/ckeditor.drupalimage.admin.js
+++ b/core/modules/ckeditor/js/ckeditor.drupalimage.admin.js
@@ -1,9 +1,16 @@
+/**
+ * @file
+ * Ckeditor drupalimage admin behavior.
+ */
+
 (function ($, Drupal, drupalSettings) {
 
   "use strict";
 
   /**
    * Provides the summary for the "drupalimage" plugin settings vertical tab.
+   *
+   * @type {Drupal~behavior}
    */
   Drupal.behaviors.ckeditorDrupalImageSettingsSummary = {
     attach: function () {
diff --git a/core/modules/ckeditor/js/ckeditor.js b/core/modules/ckeditor/js/ckeditor.js
index 59f8b2e..8c1b51a 100644
--- a/core/modules/ckeditor/js/ckeditor.js
+++ b/core/modules/ckeditor/js/ckeditor.js
@@ -1,9 +1,25 @@
+/**
+ * @file
+ * Ckeditor JS API.
+ */
+
 (function (Drupal, debounce, CKEDITOR, $) {
 
   "use strict";
 
+  /**
+   * @namespace
+   */
   Drupal.editors.ckeditor = {
 
+    /**
+     * Editor attach callback.
+     *
+     * @param {HTMLElement} element
+     * @param {string} format
+     *
+     * @return {bool}
+     */
     attach: function (element, format) {
       this._loadExternalPlugins(format);
       // Also pass settings that are Drupal-specific.
@@ -26,6 +42,15 @@
       return !!CKEDITOR.replace(element, format.editorSettings);
     },
 
+    /**
+     * Editor detach callback.
+     *
+     * @param {HTMLElement} element
+     * @param {string} format
+     * @param {string} trigger
+     *
+     * @return {bool}
+     */
     detach: function (element, format, trigger) {
       var editor = CKEDITOR.dom.element.get(element).getEditor();
       if (editor) {
@@ -40,6 +65,13 @@
       return !!editor;
     },
 
+    /**
+     *
+     * @param {HTMLElement} element
+     * @param {function} callback
+     *
+     * @return {bool}
+     */
     onChange: function (element, callback) {
       var editor = CKEDITOR.dom.element.get(element).getEditor();
       if (editor) {
@@ -50,6 +82,15 @@
       return !!editor;
     },
 
+    /**
+     *
+     * @param {HTMLElement} element
+     * @param {object} format
+     * @param {string} mainToolbarId
+     * @param {string} floatedToolbarId
+     *
+     * @return {bool}
+     */
     attachInlineEditor: function (element, format, mainToolbarId, floatedToolbarId) {
       this._loadExternalPlugins(format);
       // Also pass settings that are Drupal-specific.
@@ -101,6 +142,9 @@
       return !!CKEDITOR.inline(element, settings);
     },
 
+    /**
+     * @param {object} format
+     */
     _loadExternalPlugins: function (format) {
       var externalPlugins = format.editorSettings.drupalExternalPlugins;
       // Register and load additional CKEditor plugins as necessary.
@@ -117,8 +161,11 @@
   };
 
   Drupal.ckeditor = {
+
     /**
      * Variable storing the current dialog's save callback.
+     *
+     * @type {?function}
      */
     saveCallback: null,
 
@@ -128,16 +175,16 @@
      * This dynamically loads jQuery UI (if necessary) using the Drupal AJAX
      * framework, then opens a dialog at the specified Drupal path.
      *
-     * @param editor
+     * @param {CKEditor} editor
      *   The CKEditor instance that is opening the dialog.
-     * @param string url
+     * @param {string} url
      *   The URL that contains the contents of the dialog.
-     * @param Object existingValues
+     * @param {object} existingValues
      *   Existing values that will be sent via POST to the url for the dialog
      *   contents.
-     * @param Function saveCallback
+     * @param {function} saveCallback
      *   A function to be called upon saving the dialog.
-     * @param Object dialogSettings
+     * @param {object} dialogSettings
      *   An object containing settings to be passed to the jQuery UI.
      */
     openDialog: function (editor, url, existingValues, saveCallback, dialogSettings) {
diff --git a/core/modules/ckeditor/js/ckeditor.stylescombo.admin.js b/core/modules/ckeditor/js/ckeditor.stylescombo.admin.js
index 5fe814d..56933ea 100644
--- a/core/modules/ckeditor/js/ckeditor.stylescombo.admin.js
+++ b/core/modules/ckeditor/js/ckeditor.stylescombo.admin.js
@@ -1,3 +1,8 @@
+/**
+ * @file
+ * Ckeditor sylecombo admin behavior.
+ */
+
 (function ($, Drupal, drupalSettings) {
 
   "use strict";
@@ -9,6 +14,8 @@
    * plugin settings change, to ensure that the corresponding feature metadata is
    * immediately updated — i.e. ensure that HTML tags and classes entered here are
    * known to be "required", which may affect filter settings.
+   *
+   * @type {Drupal~behavior}
    */
   Drupal.behaviors.ckeditorStylesComboSettings = {
     attach: function (context) {
@@ -46,10 +53,10 @@
      * parsing works identically, but instead of failing on invalid styles, we
      * just ignore those.
      *
-     * @param String styles
+     * @param {string} styles
      *   The "styles" setting.
      *
-     * @return array
+     * @return {Array}
      *   An array containing the "stylesSet" configuration.
      */
     _generateStylesSetSetting: function (styles) {
@@ -93,6 +100,8 @@
 
   /**
    * Provides the summary for the "stylescombo" plugin settings vertical tab.
+   *
+   * @type {Drupal~behavior}
    */
   Drupal.behaviors.ckeditorStylesComboSettingsSummary = {
     attach: function () {
diff --git a/core/modules/ckeditor/js/models/Model.js b/core/modules/ckeditor/js/models/Model.js
index bdab6fd..9868c09 100644
--- a/core/modules/ckeditor/js/models/Model.js
+++ b/core/modules/ckeditor/js/models/Model.js
@@ -9,26 +9,58 @@
 
   /**
    * Backbone model for the CKEditor toolbar configuration state.
+   *
+   * @constructor
+   *
+   * @augments Backbone.Model
    */
-  Drupal.ckeditor.Model = Backbone.Model.extend({
-    defaults: {
-      // The CKEditor configuration that is being manipulated through the UI.
+  Drupal.ckeditor.Model = Backbone.Model.extend(/** @lends Drupal.ckeditor.Model# */{
+
+    /**
+     * Default values.
+     *
+     * @type {object}
+     */
+    defaults: /** @lends Drupal.ckeditor.Model# */{
+
+      /**
+       * The CKEditor configuration that is being manipulated through the UI.
+       */
       activeEditorConfig: null,
-      // The textarea that contains the serialized representation of the active
-      // CKEditor configuration.
+
+      /**
+       * The textarea that contains the serialized representation of the active
+       * CKEditor configuration.
+       */
       $textarea: null,
-      // Tracks whether the active toolbar DOM structure has been changed. When
-      // true, activeEditorConfig needs to be updated, and when that is updated,
-      // $textarea will also be updated.
+
+      /**
+       * Tracks whether the active toolbar DOM structure has been changed. When
+       * true, activeEditorConfig needs to be updated, and when that is updated,
+       * $textarea will also be updated.
+       */
       isDirty: false,
-      // The configuration for the hidden CKEditor instance that is used to build
-      // the features metadata.
+
+      /**
+       * The configuration for the hidden CKEditor instance that is used to build
+       * the features metadata.
+       */
       hiddenEditorConfig: null,
-      // A hash, keyed by a feature name, that details CKEditor plugin features.
+
+      /**
+       * A hash, keyed by a feature name, that details CKEditor plugin features.
+       */
       featuresMetadata: null,
-      // Whether the button group names are currently visible.
+
+      /**
+       * Whether the button group names are currently visible.
+       */
       groupNamesVisible: false
     },
+
+    /**
+     * @method
+     */
     sync: function () {
       // Push the settings into the textarea.
       this.get('$textarea').val(JSON.stringify(this.get('activeEditorConfig')));
diff --git a/core/modules/ckeditor/js/plugins/drupalimage/plugin.js b/core/modules/ckeditor/js/plugins/drupalimage/plugin.js
index fd18c5a..68eb7fe 100644
--- a/core/modules/ckeditor/js/plugins/drupalimage/plugin.js
+++ b/core/modules/ckeditor/js/plugins/drupalimage/plugin.js
@@ -7,8 +7,12 @@
  *   uses to track where images are being used)
  * - use a Drupal-native dialog (that is in fact just an alterable Drupal form
  *   like any other) instead of CKEditor's own dialogs.
- *   @see \Drupal\editor\Form\EditorImageDialog
+ *
+ * @see \Drupal\editor\Form\EditorImageDialog
+ *
+ * @ignore
  */
+
 (function ($, Drupal, CKEDITOR) {
 
   "use strict";
diff --git a/core/modules/ckeditor/js/plugins/drupalimagecaption/plugin.js b/core/modules/ckeditor/js/plugins/drupalimagecaption/plugin.js
index cbb6160..1dffb23 100644
--- a/core/modules/ckeditor/js/plugins/drupalimagecaption/plugin.js
+++ b/core/modules/ckeditor/js/plugins/drupalimagecaption/plugin.js
@@ -5,8 +5,11 @@
  * This alters the existing CKEditor image2 widget plugin, which is already
  * altered by the Drupal Image plugin, to:
  * - allow for the data-caption and data-align attributes to be set
- * - mimic the upcasting behavior of the caption_filter filter
+ * - mimic the upcasting behavior of the caption_filter filter.
+ *
+ * @ignore
  */
+
 (function (CKEDITOR) {
 
   "use strict";
@@ -220,9 +223,10 @@
    * Function will check first the passed element itself and then all its
    * children in DFS order.
    *
-   * @param CKEDITOR.htmlParser.element element
-   * @param String name
-   * @return CKEDITOR.htmlParser.element
+   * @param {CKEDITOR.htmlParser.element} element
+   * @param {string} name
+   *
+   * @return {CKEDITOR.htmlParser.element}
    */
   function findElementByName(element, name) {
     if (element.name === name) {
@@ -233,7 +237,8 @@
     element.forEach(function (el) {
       if (el.name === name) {
         found = el;
-        return false; // Stop here.
+        // Stop here.
+        return false;
       }
     }, CKEDITOR.NODE_ELEMENT);
     return found;
diff --git a/core/modules/ckeditor/js/plugins/drupallink/plugin.js b/core/modules/ckeditor/js/plugins/drupallink/plugin.js
index 04d8aba..c26445b 100644
--- a/core/modules/ckeditor/js/plugins/drupallink/plugin.js
+++ b/core/modules/ckeditor/js/plugins/drupallink/plugin.js
@@ -1,6 +1,8 @@
 /**
  * @file
  * Drupal Link plugin.
+ *
+ * @ignore
  */
 
 (function ($, Drupal, drupalSettings, CKEDITOR) {
@@ -199,6 +201,7 @@
    *
    * The following selection will all return the link element.
    *
+   * @example
    *  <a href="#">li^nk</a>
    *  <a href="#">[link]</a>
    *  text[<a href="#">link]</a>
@@ -207,6 +210,8 @@
    *  [<a href="#"><b>li]nk</b></a>
    *
    * @param {CKEDITOR.editor} editor
+   *
+   * @return {?bool}
    */
   function getSelectedLink(editor) {
     var selection = editor.getSelection();
diff --git a/core/modules/ckeditor/js/views/AuralView.js b/core/modules/ckeditor/js/views/AuralView.js
index 5acd776..439e8dd 100644
--- a/core/modules/ckeditor/js/views/AuralView.js
+++ b/core/modules/ckeditor/js/views/AuralView.js
@@ -7,11 +7,11 @@
 
   "use strict";
 
-  /**
-   * Backbone View for CKEditor toolbar configuration; aural UX (output only).
-   */
-  Drupal.ckeditor.AuralView = Backbone.View.extend({
+  Drupal.ckeditor.AuralView = Backbone.View.extend(/** @lends Drupal.ckeditor.AuralView# */{
 
+    /**
+     * @type {object}
+     */
     events: {
       'click .ckeditor-buttons a': 'announceButtonHelp',
       'click .ckeditor-multiple-buttons a': 'announceSeparatorHelp',
@@ -21,7 +21,11 @@
     },
 
     /**
-     * {@inheritdoc}
+     * Backbone View for CKEditor toolbar configuration; aural UX (output only).
+     *
+     * @constructs
+     *
+     * @augments Backbone.View
      */
     initialize: function () {
       // Announce the button and group positions when the model is no longer
@@ -32,8 +36,8 @@
     /**
      * Calls announce on buttons and groups when their position is changed.
      *
-     * @param Drupal.ckeditor.ConfigurationModel model
-     * @param Boolean isDirty
+     * @param {Drupal.ckeditor.ConfigurationModel} model
+     * @param {bool} isDirty
      *   A model attribute that indicates if the changed toolbar configuration
      *   has been stored or not.
      */
@@ -57,7 +61,7 @@
     /**
      * Handles the focus event of elements in the active and available toolbars.
      *
-     * @param jQuery.Event event
+     * @param {jQuery.Event} event
      */
     onFocus: function (event) {
       event.stopPropagation();
@@ -76,7 +80,7 @@
     /**
      * Announces the current position of a button group.
      *
-     * @param jQuery $group
+     * @param {jQuery} $group
      *   A jQuery set that contains an li element that wraps a group of buttons.
      */
     announceButtonGroupPosition: function ($group) {
@@ -106,7 +110,7 @@
     /**
      * Announces current button position.
      *
-     * @param jQuery $button
+     * @param {jQuery} $button
      *   A jQuery set that contains an li element that wraps a button.
      */
     announceButtonPosition: function ($button) {
@@ -166,7 +170,7 @@
     /**
      * Provides help information when a button is clicked.
      *
-     * @param jQuery.Event event
+     * @param {jQuery.Event} event
      */
     announceButtonHelp: function (event) {
       var $link = $(event.currentTarget);
@@ -194,7 +198,7 @@
     /**
      * Provides help information when a separator is clicked.
      *
-     * @param jQuery.Event event
+     * @param {jQuery.Event} event
      */
     announceSeparatorHelp: function (event) {
       var $link = $(event.currentTarget);
diff --git a/core/modules/ckeditor/js/views/ControllerView.js b/core/modules/ckeditor/js/views/ControllerView.js
index 7d77943..125debf 100644
--- a/core/modules/ckeditor/js/views/ControllerView.js
+++ b/core/modules/ckeditor/js/views/ControllerView.js
@@ -7,15 +7,19 @@
 
   "use strict";
 
-  /**
-   * Backbone View acting as a controller for CKEditor toolbar configuration.
-   */
-  Drupal.ckeditor.ControllerView = Backbone.View.extend({
+  Drupal.ckeditor.ControllerView = Backbone.View.extend(/** @lends Drupal.ckeditor.ControllerView# */{
 
+    /**
+     * @type {object}
+     */
     events: {},
 
     /**
-     * {@inheritdoc}
+     * Backbone View acting as a controller for CKEditor toolbar configuration.
+     *
+     * @constructs
+     *
+     * @augments Backbone.View
      */
     initialize: function () {
       this.getCKEditorFeatures(this.model.get('hiddenEditorConfig'), this.disableFeaturesDisallowedByFilters.bind(this));
@@ -28,16 +32,18 @@
     /**
      * Converts the active toolbar DOM structure to an object representation.
      *
-     * @param Drupal.ckeditor.ConfigurationModel model
+     * @param {Drupal.ckeditor.ConfigurationModel} model
      *   The state model for the CKEditor configuration.
-     * @param Boolean isDirty
+     * @param {bool} isDirty
      *   Tracks whether the active toolbar DOM structure has been changed.
      *   isDirty is toggled back to false in this method.
-     * @param Object options
+     * @param {object} options
      *   An object that includes:
-     *   - Boolean broadcast: (optional) A flag that controls whether a
-     *     CKEditorToolbarChanged event should be fired for configuration
-     *     changes.
+     * @param {bool} [options.broadcast]
+     *   A flag that controls whether a CKEditorToolbarChanged event should be
+     *   fired for configuration changes.
+     *
+     * @fires event:CKEditorToolbarChanged
      */
     parseEditorDOM: function (model, isDirty, options) {
       if (isDirty) {
@@ -100,10 +106,10 @@
      * must be provided that will receive a hash of Drupal.EditorFeature
      * features keyed by feature (button) name.
      *
-     * @param Object CKEditorConfig
+     * @param {object} CKEditorConfig
      *   An object that represents the configuration settings for a CKEditor
      *   editor component.
-     * @param Function callback
+     * @param {function} callback
      *   A function to invoke when the instanceReady event is fired by the
      *   CKEditor object.
      */
@@ -192,9 +198,10 @@
      * Retrieves the feature for a given button from featuresMetadata. Returns
      * false if the given button is in fact a divider.
      *
-     * @param String button
+     * @param {string} button
      *   The name of a CKEditor button.
-     * @return Object
+     *
+     * @return {object}
      *   The feature metadata object for a button.
      */
     getFeatureForButton: function (button) {
@@ -218,7 +225,7 @@
     /**
      * Checks buttons against filter settings; disables disallowed buttons.
      *
-     * @param Object features
+     * @param {object} features
      *   A map of Drupal.EditorFeature objects.
      */
     disableFeaturesDisallowedByFilters: function (features) {
@@ -272,7 +279,7 @@
     /**
      * Sets up broadcasting of CKEditor toolbar configuration changes.
      *
-     * @param jQuery $ckeditorToolbar
+     * @param {jQuery} $ckeditorToolbar
      *   The active toolbar DOM element wrapped in jQuery.
      */
     broadcastConfigurationChanges: function ($ckeditorToolbar) {
@@ -329,14 +336,15 @@
     /**
      * Returns the list of buttons from an editor configuration.
      *
-     * @param Object config
+     * @param {object} config
      *   A CKEditor configuration object.
-     * @return Array
+     *
+     * @return {Array}
      *   A list of buttons in the CKEditor configuration.
      */
     getButtonList: function (config) {
       var buttons = [];
-      // Remove the rows
+      // Remove the rows.
       config = _.flatten(config);
 
       // Loop through the button groups and pull out the buttons.
diff --git a/core/modules/ckeditor/js/views/KeyboardView.js b/core/modules/ckeditor/js/views/KeyboardView.js
index 2a2868a..ecd088c 100644
--- a/core/modules/ckeditor/js/views/KeyboardView.js
+++ b/core/modules/ckeditor/js/views/KeyboardView.js
@@ -7,13 +7,14 @@
 
   "use strict";
 
-  /**
-   * Backbone View for CKEditor toolbar configuration; keyboard UX.
-   */
-  Drupal.ckeditor.KeyboardView = Backbone.View.extend({
+  Drupal.ckeditor.KeyboardView = Backbone.View.extend(/** @lends Drupal.ckeditor.KeyboardView# */{
 
     /**
-     * {@inheritdoc}
+     * Backbone View for CKEditor toolbar configuration; keyboard UX.
+     *
+     * @constructs
+     *
+     * @augments Backbone.View
      */
     initialize: function () {
       // Add keyboard arrow support.
@@ -22,7 +23,7 @@
     },
 
     /**
-     * {@inheritdoc}
+     * @inheritdoc
      */
     render: function () {
     },
@@ -30,7 +31,7 @@
     /**
      * Handles keypresses on a CKEditor configuration button.
      *
-     * @param jQuery.Event event
+     * @param {jQuery.Event} event
      */
     onPressButton: function (event) {
       var upDownKeys = [
@@ -181,7 +182,7 @@
     /**
      * Handles keypresses on a CKEditor configuration group.
      *
-     * @param jQuery.Event event
+     * @param {jQuery.Event} event
      */
     onPressGroup: function (event) {
       var upDownKeys = [
diff --git a/core/modules/ckeditor/js/views/VisualView.js b/core/modules/ckeditor/js/views/VisualView.js
index 95d56e7..b9779a2 100644
--- a/core/modules/ckeditor/js/views/VisualView.js
+++ b/core/modules/ckeditor/js/views/VisualView.js
@@ -1,16 +1,14 @@
 /**
  * @file
- * A Backbone View that provides the visual UX view of CKEditor toolbar configuration.
+ * A Backbone View that provides the visual UX view of CKEditor toolbar
+ *   configuration.
  */
 
 (function (Drupal, Backbone, $) {
 
   "use strict";
 
-  /**
-   * Backbone View for CKEditor toolbar configuration; visual UX.
-   */
-  Drupal.ckeditor.VisualView = Backbone.View.extend({
+  Drupal.ckeditor.VisualView = Backbone.View.extend(/** @lends Drupal.ckeditor.VisualView# */{
 
     events: {
       'click .ckeditor-toolbar-group-name': 'onGroupNameClick',
@@ -19,7 +17,11 @@
     },
 
     /**
-     * {@inheritdoc}
+     * Backbone View for CKEditor toolbar configuration; visual UX.
+     *
+     * @constructs
+     *
+     * @augments Backbone.View
      */
     initialize: function () {
       this.listenTo(this.model, 'change:isDirty change:groupNamesVisible', this.render);
@@ -32,7 +34,12 @@
     },
 
     /**
-     * {@inheritdoc}
+     *
+     * @param {*} model
+     * @param {string} [value]
+     * @param {object} changedAttributes
+     *
+     * @return {Drupal.ckeditor.VisualView}
      */
     render: function (model, value, changedAttributes) {
       this.insertPlaceholders();
@@ -57,7 +64,7 @@
     /**
      * Handles clicks to a button group name.
      *
-     * @param jQuery.Event event
+     * @param {jQuery.Event} event
      */
     onGroupNameClick: function (event) {
       var $group = $(event.currentTarget).closest('.ckeditor-toolbar-group');
@@ -69,6 +76,8 @@
 
     /**
      * Handles clicks on the button group names toggle button.
+     *
+     * @param {jQuery.Event} event
      */
     onGroupNamesToggleClick: function (event) {
       this.model.set('groupNamesVisible', !this.model.get('groupNamesVisible'));
@@ -78,17 +87,17 @@
     /**
      * Prompts the user to provide a name for a new button group; inserts it.
      *
-     * @param jQuery.Event event
+     * @param {jQuery.Event} event
      */
     onAddGroupButtonClick: function (event) {
 
       /**
        * Inserts a new button if the openGroupNameDialog function returns true.
        *
-       * @param Boolean success
+       * @param {bool} success
        *   A flag that indicates if the user created a new group (true) or
        *   canceled out of the dialog (false).
-       * @param jQuery $group
+       * @param {jQuery} $group
        *   A jQuery DOM fragment that represents the new button group. It has
        *   not been added to the DOM yet.
        */
@@ -110,8 +119,8 @@
     /**
      * Handles jQuery Sortable stop sort of a button group.
      *
-     * @param jQuery.Event event
-     * @param Object ui
+     * @param {jQuery.Event} event
+     * @param {object} ui
      *   A jQuery.ui.sortable argument that contains information about the
      *   elements involved in the sort action.
      */
@@ -128,8 +137,8 @@
     /**
      * Handles jQuery Sortable start sort of a button.
      *
-     * @param jQuery.Event event
-     * @param Object ui
+     * @param {jQuery.Event} event
+     * @param {object} ui
      *   A jQuery.ui.sortable argument that contains information about the
      *   elements involved in the sort action.
      */
@@ -143,8 +152,8 @@
     /**
      * Handles jQuery Sortable stop sort of a button.
      *
-     * @param jQuery.Event event
-     * @param Object ui
+     * @param {jQuery.Event} event
+     * @param {object} ui
      *   A jQuery.ui.sortable argument that contains information about the
      *   elements involved in the sort action.
      */
diff --git a/core/modules/editor/js/editor.admin.js b/core/modules/editor/js/editor.admin.js
index 4cbfdc7..553cbf5 100644
--- a/core/modules/editor/js/editor.admin.js
+++ b/core/modules/editor/js/editor.admin.js
@@ -11,69 +11,81 @@
 
   "use strict";
 
+  /**
+   * @namespace
+   */
   Drupal.editorConfiguration = {
 
     /**
-     * Must be called by a specific text editor's configuration whenever a feature
-     * is added by the user.
+     * Must be called by a specific text editor's configuration whenever a
+     * feature is added by the user.
      *
-     * Triggers the drupalEditorFeatureAdded event on the document, which receives
-     * a Drupal.EditorFeature object.
+     * Triggers the drupalEditorFeatureAdded event on the document, which
+     * receives a Drupal.EditorFeature object.
      *
-     * @param Drupal.EditorFeature feature
+     * @param {Drupal.EditorFeature} feature
      *   A text editor feature object.
+     *
+     * @fires event:drupalEditorFeatureAdded
      */
     addedFeature: function (feature) {
       $(document).trigger('drupalEditorFeatureAdded', feature);
     },
 
     /**
-     * Must be called by a specific text editor's configuration whenever a feature
-     * is removed by the user.
+     * Must be called by a specific text editor's configuration whenever a
+     * feature is removed by the user.
      *
      * Triggers the drupalEditorFeatureRemoved event on the document, which
      * receives a Drupal.EditorFeature object.
      *
-     * @param Drupal.EditorFeature feature
+     * @param {Drupal.EditorFeature} feature
      *   A text editor feature object.
+     *
+     * @fires event:drupalEditorFeatureRemoved
      */
     removedFeature: function (feature) {
       $(document).trigger('drupalEditorFeatureRemoved', feature);
     },
 
     /**
-     * Must be called by a specific text editor's configuration whenever a feature
-     * is modified, i.e. has different rules.
+     * Must be called by a specific text editor's configuration whenever a
+     * feature is modified, i.e. has different rules.
      *
-     * For example when the "Bold" button is configured to use the <b> tag instead
-     * of the <strong> tag.
+     * For example when the "Bold" button is configured to use the <b> tag
+     * instead of the <strong> tag.
      *
      * Triggers the drupalEditorFeatureModified event on the document, which
      * receives a Drupal.EditorFeature object.
      *
-     * @param Drupal.EditorFeature feature
+     * @param {Drupal.EditorFeature} feature
      *   A text editor feature object.
+     *
+     * @fires event:drupalEditorFeatureModified
      */
     modifiedFeature: function (feature) {
       $(document).trigger('drupalEditorFeatureModified', feature);
     },
 
     /**
-     * May be called by a specific text editor's configuration whenever a feature
-     * is being added, to check whether it would require the filter settings to be
-     * updated.
+     * May be called by a specific text editor's configuration whenever a
+     * feature is being added, to check whether it would require the filter
+     * settings to be updated.
      *
-     * The canonical use case is when a text editor is being enabled: preferably
-     * this would not cause the filter settings to be changed; rather, the default
-     * set of buttons (features) for the text editor should adjust itself to not
-     * cause filter setting changes.
+     * The canonical use case is when a text editor is being enabled:
+     * preferably
+     * this would not cause the filter settings to be changed; rather, the
+     * default set of buttons (features) for the text editor should adjust
+     * itself to not cause filter setting changes.
      *
      * Note: for filters to integrate with this functionality, it is necessary
-     * that they implement Drupal.filterSettingsForEditors[filterID].getRules().
+     * that they implement
+     * Drupal.filterSettingsForEditors[filterID].getRules().
      *
-     * @param Drupal.EditorFeature feature
+     * @param {Drupal.EditorFeature} feature
      *   A text editor feature object.
-     * @return Boolean
+     *
+     * @return {bool}
      *   Whether the given feature is allowed by the current filters.
      */
     featureIsAllowedByFilters: function (feature) {
@@ -102,22 +114,27 @@
        *   };
        *
        * In this example, the given text editor feature resulted in the above
-       * universe, which shows that it must be allowed to generate the a, strong
-       * and img tags. For the a tag, it must be able to set the "href" attribute
-       * and the "external" class. For the strong tag, no further properties are
-       * required. For the img tag, the "src" attribute is required.
-       * The "tag" key is used to track whether that tag was explicitly allowed by
-       * one of the filter's rules. The "touchedByAllowedPropertyRule" key is used
-       * for state tracking that is essential for filterStatusAllowsFeature() to
-       * be able to reason: when all of a filter's rules have been applied, and
-       * none of the forbidden rules matched (which would have resulted in early
-       * termination) yet the universe has not been made empty (which would be the
-       * end result if everything in the universe were explicitly allowed), then
-       * this piece of state data enables us to determine whether a tag whose
-       * properties were not all explicitly allowed are in fact still allowed,
-       * because its tag was explicitly allowed and there were no filter rules
-       * applying "allowed tag property value" restrictions for this particular
-       * tag.
+       * universe, which shows that it must be allowed to generate the a,
+       * strong
+       * and img tags. For the a tag, it must be able to set the "href"
+       * attribute and the "external" class. For the strong tag, no further
+       * properties are required. For the img tag, the "src" attribute is
+       * required. The "tag" key is used to track whether that tag was
+       * explicitly allowed by one of the filter's rules. The
+       * "touchedByAllowedPropertyRule" key is used for state tracking that is
+       * essential for filterStatusAllowsFeature() to be able to reason: when
+       * all of a filter's rules have been applied, and none of the forbidden
+       * rules matched (which would have resulted in early termination) yet the
+       * universe has not been made empty (which would be the end result if
+       * everything in the universe were explicitly allowed), then this piece
+       * of state data enables us to determine whether a tag whose properties
+       * were not all explicitly allowed are in fact still allowed, because its
+       * tag was explicitly allowed and there were no filter rules applying
+       * "allowed tag property value" restrictions for this particular tag.
+       *
+       * @param {object} feature
+       *
+       * @return {object}
        *
        * @see findPropertyValueOnTag()
        * @see filterStatusAllowsFeature()
@@ -151,9 +168,9 @@
             continue;
           }
 
-          // Expand the existing universe, assume that each tags' property value
-          // is disallowed. If the filter rules allow everything in the feature's
-          // universe, then the feature is allowed.
+          // Expand the existing universe, assume that each tags' property
+          // value is disallowed. If the filter rules allow everything in the
+          // feature's universe, then the feature is allowed.
           for (var p = 0; p < properties.length; p++) {
             var property = properties[p];
             for (var pv = 0; pv < featureRule.required[property].length; pv++) {
@@ -169,6 +186,10 @@
       /**
        * Provided a section of a feature or filter rule, checks if no property
        * values are defined for all properties: attributes, classes and styles.
+       *
+       * @param {object} section
+       *
+       * @return {bool}
        */
       function emptyProperties(section) {
         return section.attributes.length === 0 && section.classes.length === 0 && section.styles.length === 0;
@@ -178,6 +199,14 @@
        * Calls findPropertyValueOnTag on the given tag for every property value
        * that is listed in the "propertyValues" parameter. Supports the wildcard
        * tag.
+       *
+       * @param {object} universe
+       * @param {string} tag
+       * @param {string} property
+       * @param {Array} propertyValues
+       * @param {bool} allowing
+       *
+       * @return {bool}
        */
       function findPropertyValuesOnTag(universe, tag, property, propertyValues, allowing) {
         // Detect the wildcard case.
@@ -196,6 +225,13 @@
 
       /**
        * Calls findPropertyValuesOnAllTags for all tags in the universe.
+       *
+       * @param {object} universe
+       * @param {string} property
+       * @param {Array} propertyValues
+       * @param {bool} allowing
+       *
+       * @return {bool}
        */
       function findPropertyValuesOnAllTags(universe, property, propertyValues, allowing) {
         var atLeastOneFound = false;
@@ -208,10 +244,18 @@
       }
 
       /**
-       * Finds out if a specific property value (potentially containing wildcards)
-       * exists on the given tag. When the "allowing" parameter equals true, the
-       * universe will be updated if that specific property value exists.
-       * Returns true if found, false otherwise.
+       * Finds out if a specific property value (potentially containing
+       * wildcards) exists on the given tag. When the "allowing" parameter
+       * equals true, the universe will be updated if that specific property
+       * value exists. Returns true if found, false otherwise.
+       *
+       * @param {object} universe
+       * @param {string} tag
+       * @param {string} property
+       * @param {string} propertyValue
+       * @param {bool} allowing
+       *
+       * @return {bool}
        */
       function findPropertyValueOnTag(universe, tag, property, propertyValue, allowing) {
         // If the tag does not exist in the universe, then it definitely can't
@@ -258,6 +302,11 @@
       /**
        * Deletes a tag from the universe if the tag itself and each of its
        * properties are marked as allowed.
+       *
+       * @param {object} universe
+       * @param {string} tag
+       *
+       * @return {bool}
        */
       function deleteFromUniverseIfAllowed(universe, tag) {
         // Detect the wildcard case.
@@ -273,6 +322,10 @@
 
       /**
        * Calls deleteFromUniverseIfAllowed for all tags in the universe.
+       *
+       * @param {object} universe
+       *
+       * @return {bool}
        */
       function deleteAllTagsFromUniverseIfAllowed(universe) {
         var atLeastOneDeleted = false;
@@ -287,6 +340,11 @@
       /**
        * Checks if any filter rule forbids either a tag or a tag property value
        * that exists in the universe.
+       *
+       * @param {object} universe
+       * @param {object} filterStatus
+       *
+       * @return {bool}
        */
       function anyForbiddenFilterRuleMatches(universe, filterStatus) {
         var properties = ['attributes', 'styles', 'classes'];
@@ -315,8 +373,8 @@
               // … then iterate over all properties …
               for (var k = 0; k < properties.length; k++) {
                 var property = properties[k];
-                // … and return true if just one of the forbidden property values
-                // for this tag and property is listed in the universe.
+                // … and return true if just one of the forbidden property
+                // values for this tag and property is listed in the universe.
                 if (findPropertyValuesOnTag(universe, tag, property, filterRule.restrictedTags.forbidden[property], false)) {
                   return true;
                 }
@@ -329,10 +387,13 @@
       }
 
       /**
-       * Applies every filter rule's explicit allowing of a tag or a tag property
-       * value to the universe. Whenever both the tag and all of its required
-       * property values are marked as explicitly allowed, they are deleted from
-       * the universe.
+       * Applies every filter rule's explicit allowing of a tag or a tag
+       * property value to the universe. Whenever both the tag and all of its
+       * required property values are marked as explicitly allowed, they are
+       * deleted from the universe.
+       *
+       * @param {object} universe
+       * @param {object} filterStatus
        */
       function markAllowedTagsAndPropertyValues(universe, filterStatus) {
         var properties = ['attributes', 'styles', 'classes'];
@@ -365,9 +426,10 @@
               // … then iterate over all properties …
               for (var k = 0; k < properties.length; k++) {
                 var property = properties[k];
-                // … and try to delete this tag from the universe if just one of
-                // the allowed property values for this tag and property is listed
-                // in the universe. (Because everything might be allowed now.)
+                // … and try to delete this tag from the universe if just one
+                // of the allowed property values for this tag and property is
+                // listed in the universe. (Because everything might be allowed
+                // now.)
                 if (findPropertyValuesOnTag(universe, tag, property, filterRule.restrictedTags.allowed[property], true)) {
                   deleteFromUniverseIfAllowed(universe, tag);
                 }
@@ -383,6 +445,11 @@
        * requirements and then checking whether anything in the filter prevents
        * that.
        *
+       * @param {object} filterStatus
+       * @param {object} feature
+       *
+       * @return {bool}
+       *
        * @see generateUniverseFromFeatureRequirements()
        */
       function filterStatusAllowsFeature(filterStatus, feature) {
@@ -391,8 +458,8 @@
           return true;
         }
 
-        // A feature that specifies no rules has no HTML requirements and is hence
-        // allowed by definition.
+        // A feature that specifies no rules has no HTML requirements and is
+        // hence allowed by definition.
         if (feature.rules.length === 0) {
           return true;
         }
@@ -418,17 +485,16 @@
         // universe will become empty.
         markAllowedTagsAndPropertyValues(universe, filterStatus);
 
-        // If there was at least one filter rule allowing tags, then everything in
-        // the universe must be allowed for this feature to be allowed, and thus
-        // by now it must be empty.
-        // However, it is still possible that the filter allows the feature, due
-        // to no rules for allowing tag property values and/or rules for
-        // forbidding tag property values. For details: see the comments below.
-        //
+        // If there was at least one filter rule allowing tags, then everything
+        // in the universe must be allowed for this feature to be allowed, and
+        // thus by now it must be empty. However, it is still possible that the
+        // filter allows the feature, due to no rules for allowing tag property
+        // values and/or rules for forbidding tag property values. For details:
+        // see the comments below.
         // @see generateUniverseFromFeatureRequirements()
         if (_.some(_.pluck(filterStatus.rules, 'allow'))) {
-          // If the universe is empty, then everything was explicitly allowed and
-          // our job is done: this filter allows this feature!
+          // If the universe is empty, then everything was explicitly allowed
+          // and our job is done: this filter allows this feature!
           if (_.isEmpty(universe)) {
             return true;
           }
@@ -440,13 +506,13 @@
               return false;
             }
             // Every tag was explicitly allowed, but since the universe is not
-            // empty, one or more tag properties are disallowed. However, if only
-            // blacklisting of tag properties was applied to these tags, and no
-            // whitelisting was ever applied, then it's still fine: since none of
-            // the tag properties were blacklisted, we got to this point, and since
-            // no whitelisting was applied, it doesn't matter that the properties:
-            // this could never have happened anyway.
-            // It's only this late that we can know this for certain.
+            // empty, one or more tag properties are disallowed. However, if
+            // only blacklisting of tag properties was applied to these tags,
+            // and no whitelisting was ever applied, then it's still fine:
+            // since none of the tag properties were blacklisted, we got to
+            // this point, and since no whitelisting was applied, it doesn't
+            // matter that the properties: this could never have happened
+            // anyway. It's only this late that we can know this for certain.
             else {
               var tags = _.keys(universe);
               // Figure out if there was any rule applying whitelisting tag
@@ -471,7 +537,8 @@
         }
       }
 
-      // If any filter's current status forbids the editor feature, return false.
+      // If any filter's current status forbids the editor feature, return
+      // false.
       Drupal.filterConfiguration.update();
       for (var filterID in Drupal.filterConfiguration.statuses) {
         if (Drupal.filterConfiguration.statuses.hasOwnProperty(filterID)) {
@@ -487,25 +554,89 @@
   };
 
   /**
+   * Constructor for an editor feature HTML rule.
+   *
+   * Intended to be used in combination with {@link Drupal.EditorFeature}.
+   *
+   * A text editor feature rule object describes both:
+   *  - required HTML tags, attributes, styles and classes: without these, the
+   *    text editor feature is unable to function. It's possible that a
+   *  - allowed HTML tags, attributes, styles and classes: these are optional
+   *    in the strictest sense, but it is possible that the feature generates
+   *    them.
+   *
+   * The structure can be very clearly seen below: there's a "required" and an
+   * "allowed" key. For each of those, there are objects with the "tags",
+   * "attributes", "styles" and "classes" keys. For all these keys the values
+   * are initialized to the empty array. List each possible value as an array
+   * value. Besides the "required" and "allowed" keys, there's an optional
+   * "raw" key: it allows text editor implementations to optionally pass in
+   * their raw representation instead of the Drupal-defined representation for
+   * HTML rules.
+   *
+   * @example
+   * tags: ['<a>']
+   * attributes: ['href', 'alt']
+   * styles: ['color', 'text-decoration']
+   * classes: ['external', 'internal']
+   *
+   * @constructor
+   *
+   * @see Drupal.EditorFeature
+   */
+  Drupal.EditorFeatureHTMLRule = function () {
+
+    /**
+     *
+     * @type {object}
+     *
+     * @prop {Array} tags
+     * @prop {Array} attributes
+     * @prop {Array} styles
+     * @prop {Array} classes
+     */
+    this.required = {tags: [], attributes: [], styles: [], classes: []};
+
+    /**
+     *
+     * @type {object}
+     *
+     * @prop {Array} tags
+     * @prop {Array} attributes
+     * @prop {Array} styles
+     * @prop {Array} classes
+     */
+    this.allowed = {tags: [], attributes: [], styles: [], classes: []};
+
+    /**
+     *
+     * @type {null}
+     */
+    this.raw = null;
+  };
+
+  /**
    * A text editor feature object. Initialized with the feature name.
    *
-   * Contains a set of HTML rules (Drupal.EditorFeatureHTMLRule objects) that
-   * describe which HTML tags, attributes, styles and classes are required (i.e.
-   * essential for the feature to function at all) and which are allowed (i.e. the
-   * feature may generate this, but they're not essential).
+   * Contains a set of HTML rules ({@link Drupal.EditorFeatureHTMLRule} objects)
+   * that describe which HTML tags, attributes, styles and classes are required
+   * (i.e. essential for the feature to function at all) and which are allowed
+   * (i.e. the feature may generate this, but they're not essential).
+   *
+   * It is necessary to allow for multiple HTML rules per feature: with just
+   * one HTML rule per feature, there is not enough expressiveness to describe
+   * certain cases. For example: a "table" feature would probably require the
+   * `<table>` tag, and might allow e.g. the "summary" attribute on that tag.
+   * However, the table feature would also require the `<tr>` and `<td>` tags,
+   * but it doesn't make sense to allow for a "summary" attribute on these tags.
+   * Hence these would need to be split in two separate rules.
    *
-   * It is necessary to allow for multiple HTML rules per feature: with just one
-   * HTML rule per feature, there is not enough expressiveness to describe certain
-   * cases. For example: a "table" feature would probably require the <table> tag,
-   * and might allow for e.g. the "summary" attribute on that tag. However, the
-   * table feature would also require the <tr> and <td> tags, but it doesn't make
-   * sense to allow for a "summary" attribute on these tags. Hence these would
-   * need to be split in two separate rules.
+   * HTML rules must be added with the `addHTMLRule()` method. A feature that
+   * has zero HTML rules does not create or modify HTML.
    *
-   * HTML rules must be added with the addHTMLRule() method. A feature that has
-   * zero HTML rules does not create or modify HTML.
+   * @constructor
    *
-   * @param String name
+   * @param {string} name
    *   The name of the feature.
    *
    * @see Drupal.EditorFeatureHTMLRule
@@ -518,7 +649,7 @@
   /**
    * Adds a HTML rule to the list of HTML rules for this feature.
    *
-   * @param Drupal.editorFeatureHTMLRule rule
+   * @param {Drupal.EditorFeatureHTMLRule} rule
    *   A text editor feature HTML rule.
    */
   Drupal.EditorFeature.prototype.addHTMLRule = function (rule) {
@@ -526,66 +657,53 @@
   };
 
   /**
-   * Constructor for an editor feature HTML rule. Intended to be used in
-   * combination with Drupal.EditorFeature.
-   *
-   * A text editor feature rule object describes both
-   *  - required HTML tags, attributes, styles and classes: without these, the
-   *    text editor feature is unable to function. It's possible that a
-   *  - allowed HTML tags, attributes, styles and classes: these are optional in
-   *    the strictest sense, but it is possible that the feature generates them.
-   *
-   * The structure can be very clearly seen below: there's a "required" and an
-   * "allowed" key. For each of those, there are objects with the "tags",
-   * "attributes", "styles" and "classes" keys. For all these keys the values are
-   * initialized to the empty array. List each possible value as an array value.
-   * Besides the "required" and "allowed" keys, there's an optional "raw" key: it
-   * allows text editor implementations to optionally pass in their raw
-   * representation instead of the Drupal-defined representation for HTML rules.
-   *
-   * Examples:
-   *  - tags: ['<a>']
-   *  - attributes: ['href', 'alt']
-   *  - styles: ['color', 'text-decoration']
-   *  - classes: ['external', 'internal']
-   */
-  Drupal.EditorFeatureHTMLRule = function () {
-    this.required = {tags: [], attributes: [], styles: [], classes: []};
-    this.allowed = {tags: [], attributes: [], styles: [], classes: []};
-    this.raw = null;
-  };
-
-  /**
-   * Constructor for a text filter status object. Initialized with the filter ID.
+   * Text filter status object. Initialized with the filter ID.
    *
    * Indicates whether the text filter is currently active (enabled) or not.
    *
-   * Contains a set of HTML rules (Drupal.FilterHTMLRule objects) that describe
-   * which HTML tags are allowed or forbidden. They can also describe for a set of
-   * tags (or all tags) which attributes, styles and classes are allowed and which
-   * are forbidden.
+   * Contains a set of HTML rules ({@link Drupal.FilterHTMLRule} objects) that
+   * describe which HTML tags are allowed or forbidden. They can also describe
+   * for a set of tags (or all tags) which attributes, styles and classes are
+   * allowed and which are forbidden.
    *
-   * It is necessary to allow for multiple HTML rules per feature, for analogous
-   * reasons as Drupal.EditorFeature.
+   * It is necessary to allow for multiple HTML rules per feature, for
+   * analogous reasons as {@link Drupal.EditorFeature}.
    *
-   * HTML rules must be added with the addHTMLRule() method. A filter that has
+   * HTML rules must be added with the `addHTMLRule()` method. A filter that has
    * zero HTML rules does not disallow any HTML.
    *
-   * @param String name
+   * @constructor
+   *
+   * @param {string} name
    *   The name of the feature.
    *
    * @see Drupal.FilterHTMLRule
    */
   Drupal.FilterStatus = function (name) {
+
+    /**
+     *
+     * @type {string}
+     */
     this.name = name;
+
+    /**
+     *
+     * @type {bool}
+     */
     this.active = false;
+
+    /**
+     *
+     * @type {Array.<Drupal.FilterHTMLRule>}
+     */
     this.rules = [];
   };
 
   /**
    * Adds a HTML rule to the list of HTML rules for this filter.
    *
-   * @param Drupal.FilterHTMLRule rule
+   * @param {Drupal.FilterHTMLRule} rule
    *   A text filter HTML rule.
    */
   Drupal.FilterStatus.prototype.addHTMLRule = function (rule) {
@@ -593,59 +711,72 @@
   };
 
   /**
-   * A text filter HTML rule object. Intended to be used in combination with
-   * Drupal.FilterStatus.
+   * A text filter HTML rule object.
+   *
+   * Intended to be used in combination with {@link Drupal.FilterStatus}.
    *
-   * A text filter rule object describes
+   * A text filter rule object describes:
    *  1. allowed or forbidden tags: (optional) whitelist or blacklist HTML tags
-   *  2. restricted tag properties: (optional) whitelist or blacklist attributes,
-   *     styles and classes on a set of HTML tags.
+   *  2. restricted tag properties: (optional) whitelist or blacklist
+   *     attributes, styles and classes on a set of HTML tags.
    *
    * Typically, each text filter rule object does either 1 or 2, not both.
    *
    * The structure can be very clearly seen below:
-   *  1. use the "tags" key to list HTML tags, and set the "allow" key to either
-   *     true (to allow these HTML tags) or false (to forbid these HTML tags). If
-   *     you leave the "tags" key's default value (the empty array), no
-   *     restrictions are applied.
-   *  2. all nested within the "restrictedTags" key: use the "tags" subkey to list
-   *     HTML tags to which you want to apply property restrictions, then use the
-   *     "allowed" subkey to whitelist specific property values, and similarly use
-   *     the "forbidden" subkey to blacklist specific property values.
+   *  1. use the "tags" key to list HTML tags, and set the "allow" key to
+   *     either true (to allow these HTML tags) or false (to forbid these HTML
+   *     tags). If you leave the "tags" key's default value (the empty array),
+   *     no restrictions are applied.
+   *  2. all nested within the "restrictedTags" key: use the "tags" subkey to
+   *     list HTML tags to which you want to apply property restrictions, then
+   *     use the "allowed" subkey to whitelist specific property values, and
+   *     similarly use the "forbidden" subkey to blacklist specific property
+   *     values.
+   *
+   * @example <caption>Whitelist the "p", "strong" and "a" HTML tags.</caption>
+   * {
+   *   tags: ['p', 'strong', 'a'],
+   *   allow: true,
+   *   restrictedTags: {
+   *     tags: [],
+   *     allowed: { attributes: [], styles: [], classes: [] },
+   *     forbidden: { attributes: [], styles: [], classes: [] }
+   *   }
+   * }
+   * @example <caption>For the "a" HTML tag, only allow the "href" attribute
+   * and the "external" class and disallow the "target" attribute.</caption>
+   * {
+   *   tags: [],
+   *   allow: null,
+   *   restrictedTags: {
+   *     tags: ['a'],
+   *     allowed: { attributes: ['href'], styles: [], classes: ['external'] },
+   *     forbidden: { attributes: ['target'], styles: [], classes: [] }
+   *   }
+   * }
+   * @example <caption>For all tags, allow the "data-*" attribute (that is, any
+   * attribute that begins with "data-").</caption>
+   * {
+   *   tags: [],
+   *   allow: null,
+   *   restrictedTags: {
+   *     tags: ['*'],
+   *     allowed: { attributes: ['data-*'], styles: [], classes: [] },
+   *     forbidden: { attributes: [], styles: [], classes: [] }
+   *   }
+   * }
    *
-   * Examples:
-   *  - Whitelist the "p", "strong" and "a" HTML tags:
-   *    {
-   *      tags: ['p', 'strong', 'a'],
-   *      allow: true,
-   *      restrictedTags: {
-   *        tags: [],
-   *        allowed: { attributes: [], styles: [], classes: [] },
-   *        forbidden: { attributes: [], styles: [], classes: [] }
-   *      }
-   *    }
-   *  - For the "a" HTML tag, only allow the "href" attribute and the "external"
-   *    class and disallow the "target" attribute.
-   *    {
-   *      tags: [],
-   *      allow: null,
-   *      restrictedTags: {
-   *        tags: ['a'],
-   *        allowed: { attributes: ['href'], styles: [], classes: ['external'] },
-   *        forbidden: { attributes: ['target'], styles: [], classes: [] }
-   *      }
-   *    }
-   *  - For all tags, allow the "data-*" attribute (that is, any attribute that
-   *    begins with "data-").
-   *    {
-   *      tags: [],
-   *      allow: null,
-   *      restrictedTags: {
-   *        tags: ['*'],
-   *        allowed: { attributes: ['data-*'], styles: [], classes: [] },
-   *        forbidden: { attributes: [], styles: [], classes: [] }
-   *      }
-   *    }
+   * @return {{
+   *   tags: Array,
+   *   allow: null,
+   *   restrictedTags: {
+   *     tags: Array,
+   *     allowed: {attributes: Array, styles: Array, classes: Array},
+   *     forbidden: {attributes: Array, styles: Array, classes: Array}
+   *   }
+   *  }}
+   *
+   *  @see Drupal.FilterStatus
    */
   Drupal.FilterHTMLRule = function () {
     return {
@@ -664,21 +795,29 @@
   /**
    * Tracks the configuration of all text filters in Drupal.FilterStatus objects
    * for Drupal.editorConfiguration.featureIsAllowedByFilters().
+   *
+   * @namespace
    */
   Drupal.filterConfiguration = {
 
     /**
      * Drupal.FilterStatus objects, keyed by filter ID.
+     *
+     * @type {Object.<string, Drupal.FilterStatus>}
      */
     statuses: {},
 
     /**
-     * Live filter setting parsers, keyed by filter ID, for those filters that
-     * implement it.
+     * Live filter setting parsers.
      *
-     * Filters should load the implementing JavaScript on the filter configuration
-     * form and implement Drupal.filterSettings[filterID].getRules(), which should
-     * return an array of Drupal.FilterHTMLRule objects.
+     * Object keyed by filter ID, for those filters that implement it.
+     *
+     * Filters should load the implementing JavaScript on the filter
+     * configuration form and implement
+     * `Drupal.filterSettings[filterID].getRules()`, which should return an
+     * array of {@link Drupal.FilterHTMLRule} objects.
+     *
+     * @namespace
      */
     liveSettingParsers: {},
 
@@ -686,7 +825,7 @@
      * Updates all Drupal.FilterStatus objects to reflect the current state.
      *
      * Automatically checks whether a filter is currently enabled or not. To
-     * support more finegrained
+     * support more finegrained.
      *
      * If a filter implements a live setting parser, then that will be used to
      * keep the HTML rules for the Drupal.FilterStatus object up-to-date.
@@ -709,6 +848,8 @@
 
   /**
    * Initializes Drupal.filterConfiguration.
+   *
+   * @type {Drupal~behavior}
    */
   Drupal.behaviors.initializeFilterConfiguration = {
     attach: function (context, settings) {
@@ -719,7 +860,8 @@
         var nameAttribute = $checkbox.attr('name');
 
         // The filter's checkbox has a name attribute of the form
-        // "filters[<name of filter>][status]", parse "<name of filter>" from it.
+        // "filters[<name of filter>][status]", parse "<name of filter>"
+        // from it.
         var filterID = nameAttribute.substring(8, nameAttribute.indexOf(']'));
 
         // Create a Drupal.FilterStatus object to track the state (whether it's
diff --git a/core/modules/editor/js/editor.dialog.js b/core/modules/editor/js/editor.dialog.js
index 3ec2372..04b9403 100644
--- a/core/modules/editor/js/editor.dialog.js
+++ b/core/modules/editor/js/editor.dialog.js
@@ -1,4 +1,5 @@
 /**
+ * @file
  * AJAX commands used by Editor module.
  */
 
@@ -9,10 +10,18 @@
   /**
    * Command to save the contents of an editor-provided modal.
    *
-   * This command does not close the open modal. It should be followed by a call
-   * to Drupal.AjaxCommands.prototype.closeDialog. Editors that are integrated
-   * with dialogs must independently listen for an editor:dialogsave event to save
-   * the changes into the contents of their interface.
+   * This command does not close the open modal. It should be followed by a
+   * call to `Drupal.AjaxCommands.prototype.closeDialog`. Editors that are
+   * integrated with dialogs must independently listen for an
+   * `editor:dialogsave` event to save the changes into the contents of their
+   * interface.
+   *
+   * @param {Drupal.Ajax} [ajax]
+   * @param {object} response
+   * @param {Array} response.values
+   * @param {number} [status]
+   *
+   * @fires event:editor:dialogsave
    */
   Drupal.AjaxCommands.prototype.editorDialogSave = function (ajax, response, status) {
     $(window).trigger('editor:dialogsave', [response.values]);
diff --git a/core/modules/editor/js/editor.formattedTextEditor.js b/core/modules/editor/js/editor.formattedTextEditor.js
index e624f67..6ad38b9 100644
--- a/core/modules/editor/js/editor.formattedTextEditor.js
+++ b/core/modules/editor/js/editor.formattedTextEditor.js
@@ -10,26 +10,47 @@
  * JavaScript would use:
  *  - Drupal.editors.magical.attachInlineEditor()
  */
+
 (function ($, Drupal, drupalSettings) {
 
   "use strict";
 
-  Drupal.quickedit.editors.editor = Drupal.quickedit.EditorView.extend({
+  Drupal.quickedit.editors.editor = Drupal.quickedit.EditorView.extend(/** @lends Drupal.quickedit.editors.editor# */{
 
-    // The text format for this field.
+    /**
+     * The text format for this field.
+     *
+     * @type {string}
+     */
     textFormat: null,
 
-    // Indicates whether this text format has transformations.
+    /**
+     * Indicates whether this text format has transformations.
+     *
+     * @type {bool}
+     */
     textFormatHasTransformations: null,
 
-    // Stores a reference to the text editor object for this field.
+    /**
+     * Stores a reference to the text editor object for this field.
+     *
+     * @type {Drupal.quickedit.EditorModel}
+     */
     textEditor: null,
 
-    // Stores the textual DOM element that is being in-place edited.
+    /**
+     * Stores the textual DOM element that is being in-place edited.
+     *
+     * @type {jQuery}
+     */
     $textElement: null,
 
     /**
-     * {@inheritdoc}
+     * @constructs
+     *
+     * @augments Drupal.quickedit.EditorView
+     *
+     * @param {object} options
      */
     initialize: function (options) {
       Drupal.quickedit.EditorView.prototype.initialize.call(this, options);
@@ -46,14 +67,19 @@
     },
 
     /**
-     * {@inheritdoc}
+     * @inheritdoc
+     *
+     * @return {jQuery}
      */
     getEditedElement: function () {
       return this.$textElement;
     },
 
     /**
-     * {@inheritdoc}
+     * @inheritdoc
+     *
+     * @param {object} fieldModel
+     * @param {string} state
      */
     stateChange: function (fieldModel, state) {
       var editorModel = this.model;
@@ -143,14 +169,16 @@
     },
 
     /**
-     * {@inheritdoc}
+     * @inheritdoc
+     *
+     * @return {object}
      */
     getQuickEditUISettings: function () {
       return {padding: true, unifiedToolbar: true, fullWidthToolbar: true, popup: false};
     },
 
     /**
-     * {@inheritdoc}
+     * @inheritdoc
      */
     revert: function () {
       this.$textElement.html(this.model.get('originalValue'));
@@ -162,7 +190,7 @@
      * More accurately: it re-filters formatted text to exclude transformation
      * filters used by the text format.
      *
-     * @param Function callback
+     * @param {function} callback
      *   A callback function that will receive the untransformed text.
      *
      * @see \Drupal\editor\Ajax\GetUntransformedTextCommand
diff --git a/core/modules/editor/js/editor.js b/core/modules/editor/js/editor.js
index 1b26b0f..61f4b96 100644
--- a/core/modules/editor/js/editor.js
+++ b/core/modules/editor/js/editor.js
@@ -10,10 +10,10 @@
   /**
    * Finds the text area field associated with the given text format selector.
    *
-   * @param jQuery $formatSelector
+   * @param {jQuery} $formatSelector
    *   A text format selector DOM element.
    *
-   * @return DOM
+   * @return {HTMLElement}
    *   The text area DOM element, if it was found.
    */
   function findFieldForFormatSelector($formatSelector) {
@@ -26,9 +26,9 @@
   /**
    * Changes the text editor on a text area.
    *
-   * @param DOM field
+   * @param {HTMLElement} field
    *   The text area DOM element.
-   * @param String newFormatID
+   * @param {string} newFormatID
    *   The text format we're changing to; the text editor for the currently
    *   active text format will be detached, and the text editor for the new text
    *   format will be attached.
@@ -58,7 +58,7 @@
   /**
    * Handles changes in text format.
    *
-   * @param jQuery.Event event
+   * @param {jQuery.Event} event
    */
   function onTextFormatChange(event) {
     var $select = $(event.target);
@@ -129,11 +129,15 @@
 
   /**
    * Initialize an empty object for editors to place their attachment code.
+   *
+   * @namespace
    */
   Drupal.editors = {};
 
   /**
    * Enables editors on text_format elements.
+   *
+   * @type {Drupal~behavior}
    */
   Drupal.behaviors.editor = {
     attach: function (context, settings) {
@@ -214,6 +218,19 @@
     }
   };
 
+  /**
+   * Attach editor behaviors to the field.
+   *
+   * @param {HTMLElement} field
+   *   The textarea DOM element.
+   * @param {object} format
+   *   The text format that's being activated, from
+   *   drupalSettings.editor.formats.
+   *
+   * @listens event:change
+   *
+   * @fires event:formUpdated
+   */
   Drupal.editorAttach = function (field, format) {
     if (format.editor) {
       // HTML5 validation cannot ever work for WYSIWYG editors, because WYSIWYG
@@ -240,6 +257,17 @@
     }
   };
 
+  /**
+   * Detach editor behaviors from the field.
+   *
+   * @param {HTMLElement} field
+   *   The textarea DOM element.
+   * @param {object} format
+   *   The text format that's being activated, from
+   *   drupalSettings.editor.formats.
+   * @param {string} trigger
+   *   Trigger value from the detach behavior.
+   */
   Drupal.editorDetach = function (field, format, trigger) {
     if (format.editor) {
       // Restore the HTML5 validation "required" attribute if it was removed in
@@ -261,13 +289,14 @@
   /**
    * Filter away XSS attack vectors when switching text formats.
    *
-   * @param DOM field
+   * @param {HTMLElement} field
    *   The textarea DOM element.
-   * @param Object format
-   *   The text format that's being activated, from drupalSettings.editor.formats.
-   * @param String originalFormatID
+   * @param {object} format
+   *   The text format that's being activated, from
+   *   drupalSettings.editor.formats.
+   * @param {string} originalFormatID
    *   The text format ID of the original text format.
-   * @param Function callback
+   * @param {function} callback
    *   A callback to be called (with no parameters) after the field's value has
    *   been XSS filtered.
    */
diff --git a/core/modules/quickedit/js/editors/formEditor.js b/core/modules/quickedit/js/editors/formEditor.js
index 8dc3fb5..54564dd 100644
--- a/core/modules/quickedit/js/editors/formEditor.js
+++ b/core/modules/quickedit/js/editors/formEditor.js
@@ -7,16 +7,32 @@
 
   "use strict";
 
-  Drupal.quickedit.editors.form = Drupal.quickedit.EditorView.extend({
+  /**
+   * @constructor
+   *
+   * @augments Drupal.quickedit.EditorView
+   */
+  Drupal.quickedit.editors.form = Drupal.quickedit.EditorView.extend(/** @lends Drupal.quickedit.editors.form# */{
 
-    // Tracks the form container DOM element that is used while in-place editing.
+    /**
+     * Tracks form container DOM element that is used while in-place editing.
+     *
+     * @type {jQuery}
+     */
     $formContainer: null,
 
-    // Holds the Drupal.ajax object
+    /**
+     * Holds the Drupal.Ajax object.
+     *
+     * @type {Drupal.Ajax}
+     */
     formSaveAjax: null,
 
     /**
-     * {@inheritdoc}
+     * @inheritdoc
+     *
+     * @param {object} fieldModel
+     * @param {string} state
      */
     stateChange: function (fieldModel, state) {
       var from = fieldModel.previous('state');
@@ -24,28 +40,36 @@
       switch (to) {
         case 'inactive':
           break;
+
         case 'candidate':
           if (from !== 'inactive') {
             this.removeForm();
           }
           break;
+
         case 'highlighted':
           break;
+
         case 'activating':
           // If coming from an invalid state, then the form is already loaded.
           if (from !== 'invalid') {
             this.loadForm();
           }
           break;
+
         case 'active':
           break;
+
         case 'changed':
           break;
+
         case 'saving':
           this.save();
           break;
+
         case 'saved':
           break;
+
         case 'invalid':
           this.showValidationErrors();
           break;
@@ -53,7 +77,9 @@
     },
 
     /**
-     * {@inheritdoc}
+     * @inheritdoc
+     *
+     * @return {object}
      */
     getQuickEditUISettings: function () {
       return {padding: true, unifiedToolbar: true, fullWidthToolbar: true, popup: true};
@@ -137,7 +163,7 @@
     },
 
     /**
-     * Removes the form for this field and detaches behaviors and event handlers.
+     * Removes the form for this field, detaches behaviors and event handlers.
      */
     removeForm: function () {
       if (this.$formContainer === null) {
@@ -155,7 +181,7 @@
     },
 
     /**
-     * {@inheritdoc}
+     * @inheritdoc
      */
     save: function () {
       var $formContainer = this.$formContainer;
@@ -180,8 +206,8 @@
         // First, transition the state to 'saved'.
         fieldModel.set('state', 'saved');
         // Second, set the 'htmlForOtherViewModes' attribute, so that when this
-        // field is rerendered, the change can be propagated to other instances of
-        // this field, which may be displayed in different view modes.
+        // field is rerendered, the change can be propagated to other instances
+        // of this field, which may be displayed in different view modes.
         fieldModel.set('htmlForOtherViewModes', response.other_view_modes);
         // Finally, set the 'html' attribute on the field model. This will cause
         // the field to be rerendered.
@@ -213,7 +239,7 @@
     },
 
     /**
-     * {@inheritdoc}
+     * @inheritdoc
      */
     showValidationErrors: function () {
       this.$formContainer
diff --git a/core/modules/quickedit/js/editors/plainTextEditor.js b/core/modules/quickedit/js/editors/plainTextEditor.js
index f380a40..4e43d61 100644
--- a/core/modules/quickedit/js/editors/plainTextEditor.js
+++ b/core/modules/quickedit/js/editors/plainTextEditor.js
@@ -1,19 +1,25 @@
 /**
  * @file
- * contentEditable-based in-place editor for plain text content.
+ * ContentEditable-based in-place editor for plain text content.
  */
 
 (function ($, _, Drupal) {
 
   "use strict";
 
-  Drupal.quickedit.editors.plain_text = Drupal.quickedit.EditorView.extend({
+  Drupal.quickedit.editors.plain_text = Drupal.quickedit.EditorView.extend(/** @lends Drupal.quickedit.editors.plain_text# */{
 
-    // Stores the textual DOM element that is being in-place edited.
+    /**
+     * Stores the textual DOM element that is being in-place edited.
+     */
     $textElement: null,
 
     /**
-     * {@inheritdoc}
+     * @constructs
+     *
+     * @augments Drupal.quickedit.EditorView
+     *
+     * @param {object} options
      */
     initialize: function (options) {
       Drupal.quickedit.EditorView.prototype.initialize.call(this, options);
@@ -21,7 +27,8 @@
       var editorModel = this.model;
       var fieldModel = this.fieldModel;
 
-      // Store the original value of this field. Necessary for reverting changes.
+      // Store the original value of this field. Necessary for reverting
+      // changes.
       var $textElement;
       var $fieldItems = this.$el.find('.field-item');
       if ($fieldItems.length) {
@@ -32,7 +39,7 @@
       }
       editorModel.set('originalValue', $.trim(this.$textElement.text()));
 
-      // Sets the state to 'changed' whenever the value changes
+      // Sets the state to 'changed' whenever the value changes.
       var previousText = editorModel.get('originalValue');
       $textElement.on('keyup paste', function (event) {
         var currentText = $.trim($textElement.text());
@@ -45,14 +52,20 @@
     },
 
     /**
-     * {@inheritdoc}
+     * @inheritdoc
+     *
+     * @return {jQuery}
      */
     getEditedElement: function () {
       return this.$textElement;
     },
 
     /**
-     * {@inheritdoc}
+     * @inheritdoc
+     *
+     * @param {object} fieldModel
+     * @param {string} state
+     * @param {object} options
      */
     stateChange: function (fieldModel, state, options) {
       var from = fieldModel.previous('state');
@@ -60,6 +73,7 @@
       switch (to) {
         case 'inactive':
           break;
+
         case 'candidate':
           if (from !== 'inactive') {
             this.$textElement.removeAttr('contenteditable');
@@ -68,8 +82,10 @@
             this.removeValidationErrors();
           }
           break;
+
         case 'highlighted':
           break;
+
         case 'activating':
           // Defer updating the field model until the current state change has
           // propagated, to not trigger a nested state change event.
@@ -77,19 +93,24 @@
             fieldModel.set('state', 'active');
           });
           break;
+
         case 'active':
           this.$textElement.attr('contenteditable', 'true');
           break;
+
         case 'changed':
           break;
+
         case 'saving':
           if (from === 'invalid') {
             this.removeValidationErrors();
           }
           this.save(options);
           break;
+
         case 'saved':
           break;
+
         case 'invalid':
           this.showValidationErrors();
           break;
@@ -97,14 +118,16 @@
     },
 
     /**
-     * {@inheritdoc}
+     * @inheritdoc
+     *
+     * @return {object}
      */
     getQuickEditUISettings: function () {
       return {padding: true, unifiedToolbar: false, fullWidthToolbar: false, popup: false};
     },
 
     /**
-     * {@inheritdoc}
+     * @inheritdoc
      */
     revert: function () {
       this.$textElement.html(this.model.get('originalValue'));
diff --git a/core/modules/quickedit/js/models/AppModel.js b/core/modules/quickedit/js/models/AppModel.js
index 1682e7f..a9a030b 100644
--- a/core/modules/quickedit/js/models/AppModel.js
+++ b/core/modules/quickedit/js/models/AppModel.js
@@ -9,18 +9,47 @@
 
   "use strict";
 
-  Drupal.quickedit.AppModel = Backbone.Model.extend({
+  /**
+   * @constructor
+   *
+   * @augments Backbone.Model
+   */
+  Drupal.quickedit.AppModel = Backbone.Model.extend(/** @lends Drupal.quickedit.AppModel# */{
 
-    defaults: {
-      // The currently state = 'highlighted' Drupal.quickedit.FieldModel, if
-      // any.
-      // @see Drupal.quickedit.FieldModel.states
+    /**
+     * @type {object}
+     *
+     * @prop {Drupal.quickedit.FieldModel} highlightedField
+     * @prop {Drupal.quickedit.FieldModel} activeField
+     * @prop {Drupal.dialog~dialogDefinition} activeModal
+     */
+    defaults: /** @lends Drupal.quickedit.AppModel# */{
+
+      /**
+       * The currently state = 'highlighted' Drupal.quickedit.FieldModel, if
+       * any.
+       *
+       * @type {Drupal.quickedit.FieldModel}
+       *
+       * @see Drupal.quickedit.FieldModel.states
+       */
       highlightedField: null,
-      // The currently state = 'active' Drupal.quickedit.FieldModel, if any.
-      // @see Drupal.quickedit.FieldModel.states
+
+      /**
+       * The currently state = 'active' Drupal.quickedit.FieldModel, if any.
+       *
+       * @type {Drupal.quickedit.FieldModel}
+       *
+       * @see Drupal.quickedit.FieldModel.states
+       */
       activeField: null,
-      // Reference to a Drupal.dialog instance if a state change requires
-      // confirmation.
+
+      /**
+       * Reference to a Drupal.dialog instance if a state change requires
+       * confirmation.
+       *
+       * @type {Drupal.dialog~dialogDefinition}
+       */
       activeModal: null
     }
 
diff --git a/core/modules/quickedit/js/models/BaseModel.js b/core/modules/quickedit/js/models/BaseModel.js
index 06112cf..c445363 100644
--- a/core/modules/quickedit/js/models/BaseModel.js
+++ b/core/modules/quickedit/js/models/BaseModel.js
@@ -7,10 +7,16 @@
 
   "use strict";
 
-  Drupal.quickedit.BaseModel = Backbone.Model.extend({
+  Drupal.quickedit.BaseModel = Backbone.Model.extend(/** @lends Drupal.quickedit.BaseModel# */{
 
     /**
-     * {@inheritdoc}
+     * @constructs
+     *
+     * @augments Backbone.Model
+     *
+     * @param {object} options
+     *
+     * @return {Drupal.quickedit.BaseModel}
      */
     initialize: function (options) {
       this.__initialized = true;
@@ -18,7 +24,12 @@
     },
 
     /**
-     * {@inheritdoc}
+     *
+     * @param {object|string} key
+     * @param {*} val
+     * @param {object} [options]
+     *
+     * @return {*}
      */
     set: function (key, val, options) {
       if (this.__initialized) {
diff --git a/core/modules/quickedit/js/models/EditorModel.js b/core/modules/quickedit/js/models/EditorModel.js
index 059b13e..142c9cc 100644
--- a/core/modules/quickedit/js/models/EditorModel.js
+++ b/core/modules/quickedit/js/models/EditorModel.js
@@ -9,16 +9,43 @@
 
   "use strict";
 
-  Drupal.quickedit.EditorModel = Backbone.Model.extend({
+  /**
+   * @constructor
+   *
+   * @augments Backbone.Model
+   */
+  Drupal.quickedit.EditorModel = Backbone.Model.extend(/** @lends Drupal.quickedit.EditorModel# */{
 
-    defaults: {
-      // Not the full HTML representation of this field, but the "actual"
-      // original value of the field, stored by the used in-place editor, and
-      // in a representation that can be chosen by the in-place editor.
+    /**
+     * @type {object}
+     *
+     * @prop {string} originalValue
+     * @prop {string} currentValue
+     * @prop {Array} validationErrors
+     */
+    defaults: /** @lends Drupal.quickedit.EditorModel# */{
+
+      /**
+       * Not the full HTML representation of this field, but the "actual"
+       * original value of the field, stored by the used in-place editor, and
+       * in a representation that can be chosen by the in-place editor.
+       *
+       * @type {string}
+       */
       originalValue: null,
-      // Analogous to originalValue, but the current value.
+
+      /**
+       * Analogous to originalValue, but the current value.
+       *
+       * @type {string}
+       */
       currentValue: null,
-      // Stores any validation errors to be rendered.
+
+      /**
+       * Stores any validation errors to be rendered.
+       *
+       * @type {Array}
+       */
       validationErrors: null
     }
 
diff --git a/core/modules/quickedit/js/models/EntityModel.js b/core/modules/quickedit/js/models/EntityModel.js
index 0760aed..2048bde 100644
--- a/core/modules/quickedit/js/models/EntityModel.js
+++ b/core/modules/quickedit/js/models/EntityModel.js
@@ -7,58 +7,139 @@
 
   "use strict";
 
-  Drupal.quickedit.EntityModel = Drupal.quickedit.BaseModel.extend({
+  Drupal.quickedit.EntityModel = Drupal.quickedit.BaseModel.extend(/** @lends Drupal.quickedit.EntityModel# */{
 
-    defaults: {
-      // The DOM element that represents this entity. It may seem bizarre to
-      // have a DOM element in a Backbone Model, but we need to be able to map
-      // entities in the DOM to EntityModels in memory.
+    /**
+     * @type {object}
+     */
+    defaults: /** @lends Drupal.quickedit.EntityModel# */{
+
+      /**
+       * The DOM element that represents this entity.
+       *
+       * It may seem bizarre to have a DOM element in a Backbone Model, but we
+       * need to be able to map entities in the DOM to EntityModels in memory.
+       *
+       * @type {HTMLElement}
+       */
       el: null,
-      // An entity ID, of the form "<entity type>/<entity ID>", e.g. "node/1".
+
+      /**
+       * An entity ID, of the form `<entity type>/<entity ID>`
+       *
+       * @example
+       * "node/1"
+       *
+       * @type {string}
+       */
       entityID: null,
-      // An entity instance ID. The first instance of a specific entity (i.e. with
-      // a given entity ID) is assigned 0, the second 1, and so on.
+
+      /**
+       * An entity instance ID.
+       *
+       * The first instance of a specific entity (i.e. with a given entity ID)
+       * is assigned 0, the second 1, and so on.
+       *
+       * @type {number}
+       */
       entityInstanceID: null,
-      // The unique ID of this entity instance on the page, of the form "<entity
-      // type>/<entity ID>[entity instance ID]", e.g. "node/1[0]".
+
+      /**
+       * The unique ID of this entity instance on the page, of the form
+       * `<entity type>/<entity ID>[entity instance ID]`
+       *
+       * @example
+       * "node/1[0]"
+       *
+       * @type {string}
+       */
       id: null,
-      // The label of the entity.
+
+      /**
+       * The label of the entity.
+       *
+       * @type {string}
+       */
       label: null,
-      // A Drupal.quickedit.FieldCollection for all fields of this entity.
+
+      /**
+       * A FieldCollection for all fields of the entity.
+       *
+       * @type {Drupal.quickedit.FieldCollection}
+       *
+       * @see Drupal.quickedit.FieldCollection
+       */
       fields: null,
 
       // The attributes below are stateful. The ones above will never change
       // during the life of a EntityModel instance.
 
-      // Indicates whether this instance of this entity is currently being
-      // edited in-place.
+      /**
+       * Indicates whether this entity is currently being edited in-place.
+       *
+       * @type {bool}
+       */
       isActive: false,
-      // Whether one or more fields have already been stored in
-      // PrivateTempStore.
+
+      /**
+       * Whether one or more fields are already been stored in PrivateTempStore.
+       *
+       * @type {bool}
+       */
       inTempStore: false,
-      // Whether one or more fields have already been stored in PrivateTempStore
-      // *or* the field that's currently being edited is in the 'changed' or a
-      // later state. In other words, this boolean indicates whether a "Save"
-      // button is necessary or not.
+
+      /**
+       * Indicates whether a "Save" button is necessary or not.
+       *
+       * Whether one or more fields have already been stored in PrivateTempStore
+       * *or* the field that's currently being edited is in the 'changed' or a
+       * later state.
+       *
+       * @type {bool}
+       */
       isDirty: false,
-      // Whether the request to the server has been made to commit this entity.
-      // Used to prevent multiple such requests.
+
+      /**
+       * Whether the request to the server has been made to commit this entity.
+       *
+       * Used to prevent multiple such requests.
+       *
+       * @type {bool}
+       */
       isCommitting: false,
-      // The current processing state of an entity.
+
+      /**
+       * The current processing state of an entity.
+       *
+       * @type {string}
+       */
       state: 'closed',
-      // The IDs of the fields whose new values have been stored in
-      // PrivateTempStore. We must store this on the EntityModel as well (even
-      // though it already is on the FieldModel) because when a field is
-      // rerendered, its FieldModel is destroyed and this allows us to
-      // transition it back to the proper state.
+
+      /**
+       * IDs of fields whose new values have been stored in PrivateTempStore.
+       *
+       * We must store this on the EntityModel as well (even though it already
+       * is on the FieldModel) because when a field is rerendered, its
+       * FieldModel is destroyed and this allows us to transition it back to
+       * the proper state.
+       *
+       * @type {Array.<string>}
+       */
       fieldsInTempStore: [],
-      // A flag the tells the application that this EntityModel must be reloaded
-      // in order to restore the original values to its fields in the client.
+
+      /**
+       * A flag the tells the application that this EntityModel must be reloaded
+       * in order to restore the original values to its fields in the client.
+       *
+       * @type {bool}
+       */
       reload: false
     },
 
     /**
-     * {@inheritdoc}
+     * @constructs
+     *
+     * @augments Drupal.quickedit.BaseModel
      */
     initialize: function () {
       this.set('fields', new Drupal.quickedit.FieldCollection());
@@ -77,10 +158,11 @@
     /**
      * Updates FieldModels' states when an EntityModel change occurs.
      *
-     * @param Drupal.quickedit.EntityModel entityModel
-     * @param String state
-     *   The state of the associated entity. One of Drupal.quickedit.EntityModel.states.
-     * @param Object options
+     * @param {Drupal.quickedit.EntityModel} entityModel
+     * @param {string} state
+     *   The state of the associated entity. One of
+     *   {@link Drupal.quickedit.EntityModel.states}.
+     * @param {object} options
      */
     stateChange: function (entityModel, state, options) {
       var to = state;
@@ -195,12 +277,12 @@
      *
      * Helper function.
      *
-     * @param Drupal.quickedit.EntityModel entityModel
+     * @param {Drupal.quickedit.EntityModel} entityModel
      *   The model of the entity for which a field's state attribute has changed.
-     * @param Drupal.quickedit.FieldModel fieldModel
+     * @param {Drupal.quickedit.FieldModel} fieldModel
      *   The model of the field whose state attribute has changed.
      *
-     * @see fieldStateChange()
+     * @see Drupal.quickedit.EntityModel#fieldStateChange
      */
     _updateInTempStoreAttributes: function (entityModel, fieldModel) {
       var current = fieldModel.get('state');
@@ -233,10 +315,11 @@
     /**
      * Reacts to state changes in this entity's fields.
      *
-     * @param Drupal.quickedit.FieldModel fieldModel
+     * @param {Drupal.quickedit.FieldModel} fieldModel
      *   The model of the field whose state attribute changed.
-     * @param String state
-     *   The state of the associated field. One of Drupal.quickedit.FieldModel.states.
+     * @param {string} state
+     *   The state of the associated field. One of
+     *   {@link Drupal.quickedit.FieldModel.states}.
      */
     fieldStateChange: function (fieldModel, state) {
       var entityModel = this;
@@ -354,10 +437,10 @@
     /**
      * Fires an AJAX request to the REST save URL for an entity.
      *
-     * @param options
+     * @param {object} options
      *   An object of options that contains:
-     *     - success: (optional) A function to invoke if the entity is success-
-     *     fully saved.
+     * @param {function} [options.success]
+     *   A function to invoke if the entity is successfully saved.
      */
     save: function (options) {
       var entityModel = this;
@@ -393,19 +476,22 @@
     },
 
     /**
-     * {@inheritdoc}
      *
-     * @param Object attrs
+     * @param {object} attrs
      *   The attributes changes in the save or set call.
-     * @param Object options
+     * @param {object} options
      *   An object with the following option:
-     *     - String reason (optional): a string that conveys a particular reason
-     *       to allow for an exceptional state change.
-     *     - Array accept-field-states (optional) An array of strings that
-     *     represent field states that the entities must be in to validate. For
-     *     example, if accept-field-states is ['candidate', 'highlighted'], then
-     *     all the fields of the entity must be in either of these two states
-     *     for the save or set call to validate and proceed.
+     * @param {string} [options.reason]
+     *   A string that conveys a particular reason to allow for an exceptional
+     *   state change.
+     * @param {Array} options.accept-field-states
+     *   An array of strings that represent field states that the entities must
+     *   be in to validate. For example, if `accept-field-states` is
+     *   `['candidate', 'highlighted']`, then all the fields of the entity must
+     *   be in either of these two states for the save or set call to
+     *   validate and proceed.
+     *
+     * @return {string}
      */
     validate: function (attrs, options) {
       var acceptedFieldStates = options['accept-field-states'] || [];
@@ -444,7 +530,18 @@
       }
     },
 
-    // Like @see AppView.acceptEditorStateChange()
+    /**
+     *
+     * @param {string} from
+     * @param {string} to
+     * @param {object} context
+     * @param {string} context.reason
+     * @param {bool} context.confirming
+     *
+     * @return {bool}
+     *
+     * @see Drupal.quickedit.AppView#acceptEditorStateChange
+     */
     _acceptStateChange: function (from, to, context) {
       var accept = true;
 
@@ -481,9 +578,11 @@
     },
 
     /**
-     * @param Array acceptedFieldStates
-     *   @see validate()
-     * @return Boolean
+     * @param {Array} acceptedFieldStates
+     *
+     * @return {bool}
+     *
+     * @see Drupal.quickedit.EntityModel#validate
      */
     _fieldsHaveAcceptableStates: function (acceptedFieldStates) {
       var accept = true;
@@ -504,7 +603,7 @@
     },
 
     /**
-     * {@inheritdoc}
+     * @param {object} options
      */
     destroy: function (options) {
       Drupal.quickedit.BaseModel.prototype.destroy.call(this, options);
@@ -518,18 +617,19 @@
     },
 
     /**
-     * {@inheritdoc}
+     * @inheritdoc
      */
     sync: function () {
       // We don't use REST updates to sync.
       return;
     }
 
-  }, {
+  }, /** @lends Drupal.quickedit.EntityModel */{
 
     /**
-     * A list (sequence) of all possible states an entity can be in during
-     * in-place editing.
+     * Sequence of all possible states an entity can be in during quickediting.
+     *
+     * @type {Array.<string>}
      */
     states: [
       // Initial state, like field's 'inactive' OR the user has just finished
@@ -587,11 +687,12 @@
     /**
      * Indicates whether the 'from' state comes before the 'to' state.
      *
-     * @param String from
-     *   One of Drupal.quickedit.EntityModel.states.
-     * @param String to
-     *   One of Drupal.quickedit.EntityModel.states.
-     * @return Boolean
+     * @param {string} from
+     *   One of {@link Drupal.quickedit.EntityModel.states}.
+     * @param {string} to
+     *   One of {@link Drupal.quickedit.EntityModel.states}.
+     *
+     * @return {bool}
      */
     followsStateSequence: function (from, to) {
       return _.indexOf(this.states, from) < _.indexOf(this.states, to);
@@ -599,7 +700,16 @@
 
   });
 
-  Drupal.quickedit.EntityCollection = Backbone.Collection.extend({
+  /**
+   * @constructor
+   *
+   * @augments Backbone.Collection
+   */
+  Drupal.quickedit.EntityCollection = Backbone.Collection.extend(/** @lends Drupal.quickedit.EntityCollection# */{
+
+    /**
+     * @type {Drupal.quickedit.EntityModel}
+     */
     model: Drupal.quickedit.EntityModel
   });
 
diff --git a/core/modules/quickedit/js/models/FieldModel.js b/core/modules/quickedit/js/models/FieldModel.js
index 6bd4e44..dafd5df 100644
--- a/core/modules/quickedit/js/models/FieldModel.js
+++ b/core/modules/quickedit/js/models/FieldModel.js
@@ -7,62 +7,112 @@
 
   "use strict";
 
-  /**
-   * State of an in-place editable field in the DOM.
-   */
-  Drupal.quickedit.FieldModel = Drupal.quickedit.BaseModel.extend({
+  Drupal.quickedit.FieldModel = Drupal.quickedit.BaseModel.extend(/** @lends Drupal.quickedit.FieldModel# */{
+
+    /**
+     * @type {object}
+     */
+    defaults: /** @lends Drupal.quickedit.FieldModel# */{
 
-    defaults: {
-      // The DOM element that represents this field. It may seem bizarre to have
-      // a DOM element in a Backbone Model, but we need to be able to map fields
-      // in the DOM to FieldModels in memory.
+      /**
+       * The DOM element that represents this field. It may seem bizarre to have
+       * a DOM element in a Backbone Model, but we need to be able to map fields
+       * in the DOM to FieldModels in memory.
+       */
       el: null,
-      // A field ID, of the form
-      // "<entity type>/<id>/<field name>/<language>/<view mode>", e.g.
-      // "node/1/field_tags/und/full".
+
+      /**
+       * A field ID, of the form
+       * `<entity type>/<id>/<field name>/<language>/<view mode>`
+       *
+       * @example
+       * "node/1/field_tags/und/full"
+       */
       fieldID: null,
-      // The unique ID of this field within its entity instance on the page, of
-      // the form "<entity type>/<id>/<field name>/<language>/<view mode>[entity instance ID]",
-      // e.g. "node/1/field_tags/und/full[0]".
+
+      /**
+       * The unique ID of this field within its entity instance on the page, of
+       * the form `<entity type>/<id>/<field name>/<language>/<view
+       * mode>[entity instance ID]`.
+       *
+       * @example
+       * "node/1/field_tags/und/full[0]"
+       */
       id: null,
-      // A Drupal.quickedit.EntityModel. Its "fields" attribute, which is a
-      // FieldCollection, is automatically updated to include this FieldModel.
+
+      /**
+       * A Drupal.quickedit.EntityModel. Its "fields" attribute, which is a
+       * FieldCollection, is automatically updated to include this FieldModel.
+       */
       entity: null,
-      // This field's metadata as returned by the QuickEditController::metadata().
+
+      /**
+       * This field's metadata as returned by the
+       * QuickEditController::metadata().
+       */
       metadata: null,
-      // Callback function for validating changes between states. Receives the
-      // previous state, new state, context, and a callback
+
+      /**
+       * Callback function for validating changes between states. Receives the
+       * previous state, new state, context, and a callback.
+       */
       acceptStateChange: null,
-      // A logical field ID, of the form
-      // "<entity type>/<id>/<field name>/<language>", i.e. the fieldID without
-      // the view mode, to be able to identify other instances of the same field
-      // on the page but rendered in a different view mode. e.g. "node/1/field_tags/und".
+
+      /**
+       * A logical field ID, of the form
+       * `<entity type>/<id>/<field name>/<language>`, i.e. the fieldID without
+       * the view mode, to be able to identify other instances of the same
+       * field on the page but rendered in a different view mode.
+       *
+       * @example
+       * "node/1/field_tags/und".
+       */
       logicalFieldID: null,
 
       // The attributes below are stateful. The ones above will never change
       // during the life of a FieldModel instance.
 
-      // In-place editing state of this field. Defaults to the initial state.
-      // Possible values: @see Drupal.quickedit.FieldModel.states.
+      /**
+       * In-place editing state of this field. Defaults to the initial state.
+       * Possible values: @see Drupal.quickedit.FieldModel.states.
+       */
       state: 'inactive',
-      // The field is currently in the 'changed' state or one of the following
-      // states in which the field is still changed.
+
+      /**
+       * The field is currently in the 'changed' state or one of the following
+       * states in which the field is still changed.
+       */
       isChanged: false,
-      // Is tracked by the EntityModel, is mirrored here solely for decorative
-      // purposes: so that FieldDecorationView.renderChanged() can react to it.
+
+      /**
+       * Is tracked by the EntityModel, is mirrored here solely for decorative
+       * purposes: so that FieldDecorationView.renderChanged() can react to it.
+       */
       inTempStore: false,
-      // The full HTML representation of this field (with the element that has
-      // the data-quickedit-field-id as the outer element). Used to propagate
-      // changes from this field to other instances of the same field storage.
+
+      /**
+       * The full HTML representation of this field (with the element that has
+       * the data-quickedit-field-id as the outer element). Used to propagate
+       * changes from this field to other instances of the same field storage.
+       */
       html: null,
-      // An object containing the full HTML representations (values) of other view
-      // modes (keys) of this field, for other instances of this field displayed
-      // in a different view mode.
+
+      /**
+       * An object containing the full HTML representations (values) of other
+       * view modes (keys) of this field, for other instances of this field
+       * displayed in a different view mode.
+       */
       htmlForOtherViewModes: null
     },
 
     /**
-     * {@inheritdoc}
+     * State of an in-place editable field in the DOM.
+     *
+     * @constructs
+     *
+     * @augments Drupal.quickedit.BaseModel
+     *
+     * @param {object} options
      */
     initialize: function (options) {
       // Store the original full HTML representation of this field.
@@ -79,7 +129,8 @@
     },
 
     /**
-     * {@inheritdoc}
+     *
+     * @param {object} options
      */
     destroy: function (options) {
       if (this.get('state') !== 'inactive') {
@@ -89,7 +140,7 @@
     },
 
     /**
-     * {@inheritdoc}
+     * @inheritdoc
      */
     sync: function () {
       // We don't use REST updates to sync.
@@ -97,7 +148,22 @@
     },
 
     /**
-     * {@inheritdoc}
+     *
+     * @param {object} attrs
+     *   The attributes changes in the save or set call.
+     * @param {object} options
+     *   An object with the following option:
+     * @param {string} [options.reason]
+     *   A string that conveys a particular reason to allow for an exceptional
+     *   state change.
+     * @param {Array} options.accept-field-states
+     *   An array of strings that represent field states that the entities must
+     *   be in to validate. For example, if `accept-field-states` is
+     *   `['candidate', 'highlighted']`, then all the fields of the entity must
+     *   be in either of these two states for the save or set call to
+     *   validate and proceed.
+     *
+     * @return {string}
      */
     validate: function (attrs, options) {
       var current = this.get('state');
@@ -117,7 +183,7 @@
     /**
      * Extracts the entity ID from this field's ID.
      *
-     * @return String
+     * @return {string}
      *   An entity ID: a string of the format `<entity type>/<id>`.
      */
     getEntityID: function () {
@@ -127,7 +193,7 @@
     /**
      * Extracts the view mode ID from this field's ID.
      *
-     * @return String
+     * @return {string}
      *   A view mode ID.
      */
     getViewMode: function () {
@@ -137,16 +203,16 @@
     /**
      * Find other instances of this field with different view modes.
      *
-     * @return Array
+     * @return {Array}
      *   An array containing view mode IDs.
      */
     findOtherViewModes: function () {
       var currentField = this;
       var otherViewModes = [];
       Drupal.quickedit.collections.fields
-        // Find all instances of fields that display the same logical field (same
-        // entity, same field, just a different instance and maybe a different
-        // view mode).
+        // Find all instances of fields that display the same logical field
+        // (same entity, same field, just a different instance and maybe a
+        // different view mode).
         .where({logicalFieldID: currentField.get('logicalFieldID')})
         .forEach(function (field) {
           // Ignore the current field.
@@ -164,11 +230,12 @@
       return otherViewModes;
     }
 
-  }, {
+  }, /** @lends Drupal.quickedit.FieldModel */{
 
     /**
-     * A list (sequence) of all possible states a field can be in during in-place
-     * editing.
+     * Sequence of all possible states a field can be in during quickediting.
+     *
+     * @type {Array.<string>}
      */
     states: [
       // The field associated with this FieldModel is linked to an EntityModel;
@@ -178,13 +245,14 @@
       // This is both the initial (not yet in-place editing) and the end state (
       // finished in-place editing).
       'inactive',
-      // The user is in-place editing this entity, and this field is a candidate
+      // The user is in-place editing this entity, and this field is a
+      // candidate
       // for in-place editing. In-place editor should not
       // - Trigger: user.
-      // - Guarantees: entity is ready, in-place editor (EditorView) is associated
-      //   with the field.
-      // - Expected behavior: visual indicators around the field indicate it is
-      //   available for in-place editing, no in-place editor presented yet.
+      // - Guarantees: entity is ready, in-place editor (EditorView) is
+      // associated with the field. - Expected behavior: visual indicators
+      // around the field indicate it is available for in-place editing, no
+      // in-place editor presented yet.
       'candidate',
       // User is highlighting this field.
       // - Trigger: user.
@@ -192,13 +260,12 @@
       // - Expected behavior: visual indicators to convey highlighting, in-place
       //   editing toolbar shows field's label.
       'highlighted',
-      // User has activated the in-place editing of this field; in-place editor is
-      // activating.
-      // - Trigger: user.
-      // - Guarantees: see 'candidate'.
-      // - Expected behavior: loading indicator, in-place editor is loading remote
-      //   data (e.g. retrieve form from back-end). Upon retrieval of remote data,
-      //   the in-place editor transitions the field's state to 'active'.
+      // User has activated the in-place editing of this field; in-place editor
+      // is activating. - Trigger: user. - Guarantees: see 'candidate'. -
+      // Expected behavior: loading indicator, in-place editor is loading
+      // remote data (e.g. retrieve form from back-end). Upon retrieval of
+      // remote data, the in-place editor transitions the field's state to
+      // 'active'.
       'activating',
       // In-place editor has finished loading remote data; ready for use.
       // - Trigger: in-place editor.
@@ -224,11 +291,12 @@
       // - Trigger: in-place editor.
       // - Guarantees: see 'candidate' and 'active'.
       // - Expected behavior: transition back to 'candidate' state because the
-      //   deed is done. Then: 1) transition to 'inactive' to allow the field to
-      //   be rerendered, 2) destroy the FieldModel (which also destroys attached
-      //   views like the EditorView), 3) replace the existing field HTML with the
-      //   existing HTML and 4) attach behaviors again so that the field becomes
-      //   available again for in-place editing.
+      //   deed is done. Then: 1) transition to 'inactive' to allow the field
+      // to
+      //   be rerendered, 2) destroy the FieldModel (which also destroys
+      // attached views like the EditorView), 3) replace the existing field
+      // HTML with the existing HTML and 4) attach behaviors again so that the
+      // field becomes available again for in-place editing.
       'saved',
       // In-place editor has failed to saved the changed field: there were
       // validation errors.
@@ -242,11 +310,12 @@
     /**
      * Indicates whether the 'from' state comes before the 'to' state.
      *
-     * @param String from
-     *   One of Drupal.quickedit.FieldModel.states.
-     * @param String to
-     *   One of Drupal.quickedit.FieldModel.states.
-     * @return Boolean
+     * @param {string} from
+     *   One of {@link Drupal.quickedit.FieldModel.states}.
+     * @param {string} to
+     *   One of {@link Drupal.quickedit.FieldModel.states}.
+     *
+     * @return {bool}
      */
     followsStateSequence: function (from, to) {
       return _.indexOf(this.states, from) < _.indexOf(this.states, to);
@@ -254,7 +323,16 @@
 
   });
 
-  Drupal.quickedit.FieldCollection = Backbone.Collection.extend({
+  /**
+   * @constructor
+   *
+   * @augments Backbone.Collection
+   */
+  Drupal.quickedit.FieldCollection = Backbone.Collection.extend(/** @lends Drupal.quickedit.FieldCollection */{
+
+    /**
+     * @type {Drupal.quickedit.FieldModel}
+     */
     model: Drupal.quickedit.FieldModel
   });
 
diff --git a/core/modules/quickedit/js/quickedit.js b/core/modules/quickedit/js/quickedit.js
index 274913b..3313e83 100644
--- a/core/modules/quickedit/js/quickedit.js
+++ b/core/modules/quickedit/js/quickedit.js
@@ -5,7 +5,7 @@
  * Everything happens asynchronously, to allow for:
  *   - dynamically rendered contextual links
  *   - asynchronously retrieved (and cached) per-field in-place editing metadata
- *   - asynchronous setup of in-place editable field and "Quick edit" link
+ *   - asynchronous setup of in-place editable field and "Quick edit" link.
  *
  * To achieve this, there are several queues:
  *   - fieldsMetadataQueue: fields whose metadata still needs to be fetched.
@@ -63,6 +63,10 @@
    */
   var entityInstancesTracker = {};
 
+  /**
+   *
+   * @type {Drupal~behavior}
+   */
   Drupal.behaviors.quickedit = {
     attach: function (context) {
       // Initialize the Quick Edit app once per page load.
@@ -82,23 +86,25 @@
 
       // Process each field element: queue to be used or to fetch metadata.
       // When a field is being rerendered after editing, it will be processed
-      // immediately. New fields will be unable to be processed immediately, but
-      // will instead be queued to have their metadata fetched, which occurs below
-      // in fetchMissingMetaData().
+      // immediately. New fields will be unable to be processed immediately,
+      // but
+      // will instead be queued to have their metadata fetched, which occurs
+      // below in fetchMissingMetaData().
       $fields.each(function (index, fieldElement) {
         processField(fieldElement);
       });
 
       // Entities and fields on the page have been detected, try to set up the
-      // contextual links for those entities that already have the necessary meta-
-      // data in the client-side cache.
+      // contextual links for those entities that already have the necessary
+      // meta- data in the client-side cache.
       contextualLinksQueue = _.filter(contextualLinksQueue, function (contextualLink) {
         return !initializeEntityContextualLink(contextualLink);
       });
 
       // Fetch metadata for any fields that are queued to retrieve it.
       fetchMissingMetadata(function (fieldElementsWithFreshMetadata) {
-        // Metadata has been fetched, reprocess fields whose metadata was missing.
+        // Metadata has been fetched, reprocess fields whose metadata was
+        // missing.
         _.each(fieldElementsWithFreshMetadata, processField);
 
         // Metadata has been fetched, try to set up more contextual links now.
@@ -114,10 +120,23 @@
     }
   };
 
+  /**
+   *
+   * @namespace
+   */
   Drupal.quickedit = {
-    // A Drupal.quickedit.AppView instance.
+
+    /**
+     * A {@link Drupal.quickedit.AppView} instance.
+     */
     app: null,
 
+    /**
+     * @type {object}
+     *
+     * @prop {Array.<Drupal.quickedit.EntityModel>} entities
+     * @prop {Array.<Drupal.quickedit.FieldModel>} fields
+     */
     collections: {
       // All in-place editable entities (Drupal.quickedit.EntityModel) on the
       // page.
@@ -126,29 +145,77 @@
       fields: null
     },
 
-    // In-place editors will register themselves in this object.
+    /**
+     * In-place editors will register themselves in this object.
+     *
+     * @namespace
+     */
     editors: {},
 
-    // Per-field metadata that indicates whether in-place editing is allowed,
-    // which in-place editor should be used, etc.
+    /**
+     * Per-field metadata that indicates whether in-place editing is allowed,
+     * which in-place editor should be used, etc.
+     *
+     * @namespace
+     */
     metadata: {
+      /**
+       *
+       * @param {string} fieldID
+       *
+       * @return {bool}
+       */
       has: function (fieldID) {
         return storage.getItem(this._prefixFieldID(fieldID)) !== null;
       },
+
+      /**
+       *
+       * @param {string} fieldID
+       * @param {object} metadata
+       */
       add: function (fieldID, metadata) {
         storage.setItem(this._prefixFieldID(fieldID), JSON.stringify(metadata));
       },
+
+      /**
+       *
+       * @param {string} fieldID
+       * @param {string} [key]
+       * @return {object|*}
+       */
       get: function (fieldID, key) {
         var metadata = JSON.parse(storage.getItem(this._prefixFieldID(fieldID)));
         return (typeof key === 'undefined') ? metadata : metadata[key];
       },
+
+      /**
+       *
+       * @param {string} fieldID
+       *
+       * @return {string}
+       */
       _prefixFieldID: function (fieldID) {
         return 'Drupal.quickedit.metadata.' + fieldID;
       },
+
+      /**
+       *
+       * @param {string} fieldID
+       *
+       * @return {string}
+       */
       _unprefixFieldID: function (fieldID) {
         // Strip "Drupal.quickedit.metadata.", which is 26 characters long.
         return fieldID.substring(26);
       },
+
+      /**
+       *
+       * @param {string} fieldIDs
+       *
+       * @return {Array}
+       */
       intersection: function (fieldIDs) {
         var prefixedFieldIDs = _.map(fieldIDs, this._prefixFieldID);
         var intersection = _.intersection(prefixedFieldIDs, _.keys(sessionStorage));
@@ -174,8 +241,14 @@
   }
 
   /**
-   * Detect contextual links on entities annotated by Quick Edit; queue these to
-   * be processed.
+   * Detect contextual links on entities annotated by quickedit.
+   *
+   * Queue contextual links to be processed.
+   *
+   * @param {jQuery.Event} event
+   * @param {object} data
+   *
+   * @listens event:drupalContextualLinkAdded
    */
   $(document).on('drupalContextualLinkAdded', function (event, data) {
     if (data.$region.is('[data-quickedit-entity-id]')) {
@@ -191,7 +264,8 @@
         el: data.$el[0],
         region: data.$region[0]
       };
-      // Set up contextual links for this, otherwise queue it to be set up later.
+      // Set up contextual links for this, otherwise queue it to be set up
+      // later.
       if (!initializeEntityContextualLink(contextualLink)) {
         contextualLinksQueue.push(contextualLink);
       }
@@ -201,10 +275,11 @@
   /**
    * Extracts the entity ID from a field ID.
    *
-   * @param String fieldID
+   * @param {string} fieldID
    *   A field ID: a string of the format
    *   `<entity type>/<id>/<field name>/<language>/<view mode>`.
-   * @return String
+   *
+   * @return {string}
    *   An entity ID: a string of the format `<entity type>/<id>`.
    */
   function extractEntityID(fieldID) {
@@ -214,7 +289,7 @@
   /**
    * Initialize the Quick Edit app.
    *
-   * @param DOM bodyElement
+   * @param {HTMLElement} bodyElement
    *   This document's body element.
    */
   function initQuickEdit(bodyElement) {
@@ -234,7 +309,7 @@
   /**
    * Assigns the entity an instance ID.
    *
-   * @param DOM entityElement.
+   * @param {HTMLElement} entityElement
    *   A Drupal Entity API entity's DOM element with a data-quickedit-entity-id
    *   attribute.
    */
@@ -255,7 +330,7 @@
   /**
    * Fetch the field's metadata; queue or initialize it (if EntityModel exists).
    *
-   * @param DOM fieldElement
+   * @param {HTMLElement} fieldElement
    *   A Drupal Field API field's DOM element with a data-quickedit-field-id
    *   attribute.
    */
@@ -308,13 +383,13 @@
   /**
    * Initialize a field; create FieldModel.
    *
-   * @param DOM fieldElement
+   * @param {HTMLElement} fieldElement
    *   The field's DOM element.
-   * @param String fieldID
+   * @param {string} fieldID
    *   The field's ID.
-   * @param String entityID
+   * @param {string} entityID
    *   The field's entity's ID.
-   * @param String entityInstanceID
+   * @param {string} entityInstanceID
    *   The field's entity's instance ID.
    */
   function initializeField(fieldElement, fieldID, entityID, entityInstanceID) {
@@ -344,7 +419,7 @@
    *
    * Fields whose metadata is missing are tracked at fieldsMetadataQueue.
    *
-   * @param Function callback
+   * @param {function} callback
    *   A callback function that receives field elements whose metadata will just
    *   have been fetched.
    */
@@ -381,9 +456,9 @@
    * Loads missing in-place editor's attachments (JavaScript and CSS files).
    *
    * Missing in-place editors are those whose fields are actively being used on
-   * the page but don't have
+   * the page but don't have.
    *
-   * @param Function callback
+   * @param {function} callback
    *   Callback function to be called when the missing in-place editors (if any)
    *   have been inserted into the DOM. i.e. they may still be loading.
    */
@@ -421,15 +496,15 @@
       _.defer(callback);
       realInsert(ajax, response, status);
     };
-    // Trigger the AJAX request, which will should return AJAX commands to insert
-    // any missing attachments.
+    // Trigger the AJAX request, which will should return AJAX commands to
+    // insert any missing attachments.
     loadEditorsAjax.execute();
   }
 
   /**
    * Attempts to set up a "Quick edit" link and corresponding EntityModel.
    *
-   * @param Object contextualLink
+   * @param {object} contextualLink
    *   An object with the following properties:
    *     - String entityID: a Quick Edit entity identifier, e.g. "node/1" or
    *       "block_content/5".
@@ -438,13 +513,13 @@
    *       instance of this entity).
    *     - DOM el: element pointing to the contextual links placeholder for this
    *       entity.
-   *     - DOM region: element pointing to the contextual region for this entity.
-   * @return Boolean
+   *     - DOM region: element pointing to the contextual region of this entity.
+   *
+   * @return {bool}
    *   Returns true when a contextual the given contextual link metadata can be
-   *   removed from the queue (either because the contextual link has been set up
-   *   or because it is certain that in-place editing is not allowed for any of
-   *   its fields).
-   *   Returns false otherwise.
+   *   removed from the queue (either because the contextual link has been set
+   *   up or because it is certain that in-place editing is not allowed for any
+   *   of its fields). Returns false otherwise.
    */
   function initializeEntityContextualLink(contextualLink) {
     var metadata = Drupal.quickedit.metadata;
@@ -533,14 +608,15 @@
    * Deletes any contained EntityModels (plus their associated FieldModels and
    * ContextualLinkView) and FieldModels, as well as the corresponding queues.
    *
-   * After EntityModels, FieldModels must also be deleted, because it is possible
-   * in Drupal for a field DOM element to exist outside of the entity DOM element,
-   * e.g. when viewing the full node, the title of the node is not rendered within
-   * the node (the entity) but as the page title.
+   * After EntityModels, FieldModels must also be deleted, because it is
+   * possible in Drupal for a field DOM element to exist outside of the entity
+   * DOM element, e.g. when viewing the full node, the title of the node is not
+   * rendered within the node (the entity) but as the page title.
    *
-   * Note: this will not delete an entity that is actively being in-place edited.
+   * Note: this will not delete an entity that is actively being in-place
+   * edited.
    *
-   * @param jQuery $context
+   * @param {jQuery} $context
    *   The context within which to delete.
    */
   function deleteContainedModelsAndQueues($context) {
diff --git a/core/modules/quickedit/js/theme.js b/core/modules/quickedit/js/theme.js
index a6d1d91..a808773 100644
--- a/core/modules/quickedit/js/theme.js
+++ b/core/modules/quickedit/js/theme.js
@@ -1,6 +1,6 @@
 /**
  * @file
- * Provides overridable theme functions for all of Quick Edit's client-side HTML.
+ * Provides theme functions for all of Quick Edit's client-side HTML.
  */
 
 (function ($, Drupal) {
@@ -10,10 +10,11 @@
   /**
    * Theme function for a "backstage" for the Quick Edit module.
    *
-   * @param Object settings
-   *   An object with the following keys:
-   *   - String id: the id to apply to the backstage.
-   * @return String
+   * @param {object} settings
+   * @param {string} settings.id
+   *   the id to apply to the backstage.
+   *
+   * @return {string}
    *   The corresponding HTML.
    */
   Drupal.theme.quickeditBackstage = function (settings) {
@@ -25,10 +26,11 @@
   /**
    * Theme function for a toolbar container of the Quick Edit module.
    *
-   * @param Object settings
-   *   An object with the following keys:
-   *   - String id: the id to apply to the toolbar container.
-   * @return String
+   * @param {object} settings
+   * @param {string} settings.id
+   *   the id to apply to the backstage.
+   *
+   * @return {string}
    *   The corresponding HTML.
    */
   Drupal.theme.quickeditEntityToolbar = function (settings) {
@@ -47,11 +49,13 @@
   /**
    * Theme function for a toolbar container of the Quick Edit module.
    *
-   * @param Object settings
-   *   An object with the following keys:
-   *   - String entityLabel: The title of the active entity.
-   *   - String fieldLabel: The label of the highlighted or active field.
-   * @return String
+   * @param {object} settings
+   * @param {string} settings.entityLabel
+   *   The title of the active entity.
+   * @param {string} settings.fieldLabel
+   *   The label of the highlighted or active field.
+   *
+   * @return {string}
    *   The corresponding HTML.
    */
   Drupal.theme.quickeditEntityToolbarLabel = function (settings) {
@@ -59,9 +63,9 @@
   };
 
   /**
-   * Element that defines a containing box of the placement of the entity toolbar.
+   * Element defining a containing box for the placement of the entity toolbar.
    *
-   * @return String
+   * @return {string}
    *   The corresponding HTML.
    */
   Drupal.theme.quickeditEntityToolbarFence = function () {
@@ -71,10 +75,11 @@
   /**
    * Theme function for a toolbar container of the Quick Edit module.
    *
-   * @param settings
-   *   An object with the following keys:
-   *   - id: the id to apply to the toolbar container.
-   * @return
+   * @param {object} settings
+   * @param {string} settings.id
+   *   The id to apply to the toolbar container.
+   *
+   * @return {string}
    *   The corresponding HTML.
    */
   Drupal.theme.quickeditFieldToolbar = function (settings) {
@@ -84,12 +89,15 @@
   /**
    * Theme function for a toolbar toolgroup of the Quick Edit module.
    *
-   * @param Object settings
-   *   An object with the following keys:
-   *   - String id: (optional) the id of the toolgroup
-   *   - String classes: the class of the toolgroup.
-   *   - Array buttons: @see Drupal.theme.quickeditButtons().
-   * @return String
+   * @param {object} settings
+   * @param {string} [settings.id]
+   *   The id of the toolgroup.
+   * @param {string} settings.classes
+   *   The class of the toolgroup.
+   * @param {Array} settings.buttons
+   *   See {@link Drupal.theme.quickeditButtons}.
+   *
+   * @return {string}
    *   The corresponding HTML.
    */
   Drupal.theme.quickeditToolgroup = function (settings) {
@@ -110,15 +118,16 @@
   /**
    * Theme function for buttons of the Quick Edit module.
    *
-   * Can be used for the buttons both in the toolbar toolgroups and in the modal.
+   * Can be used for the buttons both in the toolbar toolgroups and in the
+   * modal.
+   *
+   * @param {object} settings
+   * @param {Array} settings.buttons
+   * - String type: the type of the button (defaults to 'button')
+   * - Array classes: the classes of the button.
+   * - String label: the label of the button.
    *
-   * @param Object settings
-   *   An object with the following keys:
-   *   - buttons: an array of objects with the following keys:
-   *     - String type: the type of the button (defaults to 'button')
-   *     - Array classes: the classes of the button.
-   *     - String label: the label of the button.
-   * @return String
+   * @return {string}
    *   The corresponding HTML.
    */
   Drupal.theme.quickeditButtons = function (settings) {
@@ -146,11 +155,13 @@
   /**
    * Theme function for a form container of the Quick Edit module.
    *
-   * @param Object settings
-   *   An object with the following keys:
-   *   - String id: the id to apply to the toolbar container.
-   *   - String loadingMsg: The message to show while loading.
-   * @return String
+   * @param {object} settings
+   * @param {string} settings.id
+   *   The id to apply to the toolbar container.
+   * @param {string} settings.loadingMsg
+   *   The message to show while loading.
+   *
+   * @return {string}
    *   The corresponding HTML.
    */
   Drupal.theme.quickeditFormContainer = function (settings) {
diff --git a/core/modules/quickedit/js/util.js b/core/modules/quickedit/js/util.js
index e8a9643..7c277f5 100644
--- a/core/modules/quickedit/js/util.js
+++ b/core/modules/quickedit/js/util.js
@@ -7,19 +7,37 @@
 
   "use strict";
 
+  /**
+   * @namespace
+   */
   Drupal.quickedit.util = Drupal.quickedit.util || {};
 
+  /**
+   * @namespace
+   */
   Drupal.quickedit.util.constants = {};
+
+  /**
+   *
+   * @type {string}
+   */
   Drupal.quickedit.util.constants.transitionEnd = "transitionEnd.quickedit webkitTransitionEnd.quickedit transitionend.quickedit msTransitionEnd.quickedit oTransitionEnd.quickedit";
 
   /**
    * Converts a field id into a formatted url path.
    *
-   * @param String id
-   *   The id of an editable field. For example, 'node/1/body/und/full'.
-   * @param String urlFormat
-   *   The Controller route for field processing. For example,
-   *   '/quickedit/form/!entity_type/!id/!field_name/!langcode/!view_mode'.
+   * @example
+   * Drupal.quickedit.util.buildUrl(
+   *   'node/1/body/und/full',
+   *   '/quickedit/form/!entity_type/!id/!field_name/!langcode/!view_mode'
+   * );
+   *
+   * @param {string} id
+   *   The id of an editable field.
+   * @param {string} urlFormat
+   *   The Controller route for field processing.
+   *
+   * @return {string}
    */
   Drupal.quickedit.util.buildUrl = function (id, urlFormat) {
     var parts = id.split('/');
@@ -35,9 +53,9 @@
   /**
    * Shows a network error modal dialog.
    *
-   * @param String title
+   * @param {string} title
    *   The title to use in the modal dialog.
-   * @param String message
+   * @param {string} message
    *   The message to use in the modal dialog.
    */
   Drupal.quickedit.util.networkErrorModal = function (title, message) {
@@ -65,6 +83,9 @@
     networkErrorModal.showModal();
   };
 
+  /**
+   * @namespace
+   */
   Drupal.quickedit.util.form = {
 
     /**
@@ -73,20 +94,23 @@
      * Leverages Drupal.ajax' ability to have scoped (per-instance) command
      * implementations to be able to call a callback.
      *
-     * @param Object options
+     * @param {object} options
      *   An object with the following keys:
-     *    - jQuery $el: (required) DOM element necessary for Drupal.ajax to
-     *      perform AJAX commands.
-     *    - String fieldID: (required) the field ID that uniquely identifies the
-     *      field for which this form will be loaded.
-     *    - Boolean nocssjs: (required) boolean indicating whether no CSS and JS
-     *      should be returned (necessary when the form is invisible to the user).
-     *    - Boolean reset: (required) boolean indicating whether the data stored
-     *      for this field's entity in PrivateTempStore should be used or reset.
-     * @param Function callback
-     *   A callback function that will receive the form to be inserted, as well as
-     *   the ajax object, necessary if the callback wants to perform other AJAX
-     *   commands.
+     * @param {jQuery} options.$el
+     *   DOM element necessary for Drupal.ajax to perform AJAX commands.
+     * @param {string} options.fieldID
+     *   The field ID that uniquely identifies the field for which this form
+     *   will be loaded.
+     * @param {bool} options.nocssjs
+     *   Boolean indicating whether no CSS and JS should be returned (necessary
+     *   when the form is invisible to the user).
+     * @param {bool} options.reset
+     *   Boolean indicating whether the data stored for this field's entity in
+     *   PrivateTempStore should be used or reset.
+     * @param {function} callback
+     *   A callback function that will receive the form to be inserted, as well
+     *   as the ajax object, necessary if the callback wants to perform other
+     *   Ajax commands.
      */
     load: function (options, callback) {
       var fieldID = options.fieldID;
@@ -115,20 +139,24 @@
         callback(response.data, ajax);
         Drupal.ajax.instances[this.instanceIndex] = null;
       };
-      // This will ensure our scoped quickeditFieldForm AJAX command gets called.
+      // This will ensure our scoped quickeditFieldForm AJAX command gets
+      // called.
       formLoaderAjax.execute();
     },
 
     /**
      * Creates a Drupal.ajax instance that is used to save a form.
      *
-     * @param Object options
-     *   An object with the following keys:
-     *    - nocssjs: (required) boolean indicating whether no CSS and JS should be
-     *      returned (necessary when the form is invisible to the user).
-     *    - other_view_modes: (required) array containing view mode IDs (of other
-     *      instances of this field on the page).
-     * @return Drupal.ajax
+     * @param {object} options
+     * @param {bool} options.nocssjs
+     *   Boolean indicating whether no CSS and JS should be returned (necessary
+     *   when the form is invisible to the user).
+     * @param {Array.<string>} options.other_view_modes
+     *   Array containing view mode IDs (of other instances of this field on the
+     *   page).
+     * @param {jQuery} $submit
+     *
+     * @return {Drupal.Ajax}
      *   A Drupal.ajax instance.
      */
     ajaxifySaving: function (options, $submit) {
@@ -142,8 +170,16 @@
           nocssjs: options.nocssjs,
           other_view_modes: options.other_view_modes
         },
-        // Reimplement the success handler to ensure Drupal.attachBehaviors() does
-        // not get called on the form.
+
+        /**
+         * Reimplement the success handler.
+         *
+         * Ensure {@link Drupal.attachBehaviors} does not get called on the
+         * form.
+         *
+         * @param {Drupal.AjaxCommands~commandDefinition} response
+         * @param {number} [status]
+         */
         success: function (response, status) {
           for (var i in response) {
             if (response.hasOwnProperty(i) && response[i].command && this.commands[response[i].command]) {
@@ -161,9 +197,9 @@
     /**
      * Cleans up the Drupal.ajax instance that is used to save the form.
      *
-     * @param Drupal.ajax ajax
-     *   A Drupal.ajax instance that was returned by
-     *   Drupal.quickedit.form.ajaxifySaving().
+     * @param {Drupal.Ajax} ajax
+     *   A Drupal.Ajax instance that was returned by
+     *   {@link Drupal.quickedit.form.ajaxifySaving}.
      */
     unajaxifySaving: function (ajax) {
       $(ajax.element).off('click.quickedit');
diff --git a/core/modules/quickedit/js/views/AppView.js b/core/modules/quickedit/js/views/AppView.js
index 767aa16..67b4764 100644
--- a/core/modules/quickedit/js/views/AppView.js
+++ b/core/modules/quickedit/js/views/AppView.js
@@ -10,24 +10,29 @@
   "use strict";
 
   // Indicates whether the page should be reloaded after in-place editing has
-  // shut down. A page reload is necessary to re-instate the original HTML of the
-  // edited fields if in-place editing has been canceled and one or more of the
-  // entity's fields were saved to PrivateTempStore: one of them may have been
-  // changed to the empty value and hence may have been rerendered as the empty
-  // string, which makes it impossible for Quick Edit to know where to restore
-  // the original HTML.
+  // shut down. A page reload is necessary to re-instate the original HTML of
+  // the edited fields if in-place editing has been canceled and one or more of
+  // the entity's fields were saved to PrivateTempStore: one of them may have
+  // been changed to the empty value and hence may have been rerendered as the
+  // empty string, which makes it impossible for Quick Edit to know where to
+  // restore the original HTML.
   var reload = false;
 
-  Drupal.quickedit.AppView = Backbone.View.extend({
+  Drupal.quickedit.AppView = Backbone.View.extend(/** @lends Drupal.quickedit.AppView# */{
 
     /**
-     * {@inheritdoc}
+     * @constructs
      *
-     * @param Object options
+     * @augments Backbone.View
+     *
+     * @param {object} options
      *   An object with the following keys:
-     *   - Drupal.quickedit.AppModel model: the application state model
-     *   - Drupal.quickedit.EntityCollection entitiesCollection: all on-page entities
-     *   - Drupal.quickedit.FieldCollection fieldsCollection: all on-page fields
+     * @param {Drupal.quickedit.AppModel} options.model
+     *   The application state model.
+     * @param {Drupal.quickedit.EntityCollection} options.entitiesCollection
+     *   All on-page entities.
+     * @param {Drupal.quickedit.FieldCollection} options.fieldsCollection
+     *   All on-page fields
      */
     initialize: function (options) {
       // AppView's configuration for handling states.
@@ -57,10 +62,11 @@
     /**
      * Handles setup/teardown and state changes when the active entity changes.
      *
-     * @param Drupal.quickedit.EntityModel entityModel
+     * @param {Drupal.quickedit.EntityModel} entityModel
      *   An instance of the EntityModel class.
-     * @param String state
-     *   The state of the associated field. One of Drupal.quickedit.EntityModel.states.
+     * @param {string} state
+     *   The state of the associated field. One of
+     *   {@link Drupal.quickedit.EntityModel.states}.
      */
     appStateChange: function (entityModel, state) {
       var app = this;
@@ -75,8 +81,8 @@
           });
           entityModel.toolbarView = entityToolbarView;
           // Second, set up in-place editors.
-          // They must be notified of state changes, hence this must happen while
-          // the associated fields are still in the 'inactive' state.
+          // They must be notified of state changes, hence this must happen
+          // while the associated fields are still in the 'inactive' state.
           entityModel.get('fields').each(function (fieldModel) {
             app.setupEditor(fieldModel);
           });
@@ -86,6 +92,7 @@
             entityModel.set('state', 'opening');
           });
           break;
+
         case 'closed':
           entityToolbarView = entityModel.toolbarView;
           // First, tear down the in-place editors.
@@ -97,8 +104,8 @@
             entityToolbarView.remove();
             delete entityModel.toolbarView;
           }
-          // A page reload may be necessary to re-instate the original HTML of the
-          // edited fields.
+          // A page reload may be necessary to re-instate the original HTML of
+          // the edited fields.
           if (reload) {
             reload = false;
             location.reload();
@@ -112,14 +119,16 @@
      *
      * This is what ensures that the app is in control of what happens.
      *
-     * @param String from
+     * @param {string} from
      *   The previous state.
-     * @param String to
+     * @param {string} to
      *   The new state.
-     * @param null|Object context
+     * @param {null|object} context
      *   The context that is trying to trigger the state change.
-     * @param Drupal.quickedit.FieldModel fieldModel
+     * @param {Drupal.quickedit.FieldModel} fieldModel
      *   The fieldModel to which this change applies.
+     *
+     * @return {bool}
      */
     acceptEditorStateChange: function (from, to, context, fieldModel) {
       var accept = true;
@@ -164,9 +173,9 @@
             accept = true;
           }
           // Allow: invalid -> activating.
-          // Necessary to be able to correct a field that turned out to be invalid
-          // after the user already had moved on to the next field (which we
-          // explicitly allow to have a fluent UX).
+          // Necessary to be able to correct a field that turned out to be
+          // invalid after the user already had moved on to the next field
+          // (which we explicitly allow to have a fluent UX).
           else if (from === 'invalid' && to === 'activating') {
             accept = true;
           }
@@ -177,11 +186,11 @@
         if (accept) {
           var activeField;
           var activeFieldState;
-          // Ensure only one field (editor) at a time is active … but allow a user
-          // to hop from one field to the next, even if we still have to start
-          // saving the field that is currently active: assume it will be valid,
-          // to allow for a fluent UX. (If it turns out to be invalid, this block
-          // of code also handles that.)
+          // Ensure only one field (editor) at a time is active … but allow a
+          // user to hop from one field to the next, even if we still have to
+          // start saving the field that is currently active: assume it will be
+          // valid, to allow for a fluent UX. (If it turns out to be invalid,
+          // this block of code also handles that.)
           if ((this.readyFieldStates.indexOf(from) !== -1 || from === 'invalid') && this.activeFieldStates.indexOf(to) !== -1) {
             activeField = this.model.get('activeField');
             if (activeField && activeField !== fieldModel) {
@@ -198,12 +207,12 @@
               }
 
               // If the field that's being activated is in fact already in the
-              // invalid state (which can only happen because above we allowed the
-              // user to move on to another field to allow for a fluent UX; we
-              // assumed it would be saved successfully), then we shouldn't allow
-              // the field to enter the 'activating' state, instead, we simply
-              // change the active editor. All guarantees and assumptions for this
-              // field still hold!
+              // invalid state (which can only happen because above we allowed
+              // the user to move on to another field to allow for a fluent UX;
+              // we assumed it would be saved successfully), then we shouldn't
+              // allow the field to enter the 'activating' state, instead, we
+              // simply change the active editor. All guarantees and
+              // assumptions for this field still hold!
               if (from === 'invalid') {
                 this.model.set('activeField', fieldModel);
                 accept = false;
@@ -244,7 +253,7 @@
      *
      * Must happen before the fieldModel's state is changed to 'candidate'.
      *
-     * @param Drupal.quickedit.FieldModel fieldModel
+     * @param {Drupal.quickedit.FieldModel} fieldModel
      *   The field for which an in-place editor must be set up.
      */
     setupEditor: function (fieldModel) {
@@ -273,8 +282,8 @@
         entityModel: entityModel
       });
 
-      // Create decoration for edited element: padding if necessary, sets classes
-      // on the element to style it according to the current state.
+      // Create decoration for edited element: padding if necessary, sets
+      // classes on the element to style it according to the current state.
       var decorationView = new Drupal.quickedit.FieldDecorationView({
         el: $(editorView.getEditedElement()),
         model: fieldModel,
@@ -293,7 +302,7 @@
      *
      * Must happen after the fieldModel's state is changed to 'inactive'.
      *
-     * @param Drupal.quickedit.FieldModel fieldModel
+     * @param {Drupal.quickedit.FieldModel} fieldModel
      *   The field for which an in-place editor must be torn down.
      */
     teardownEditor: function (fieldModel) {
@@ -320,7 +329,9 @@
     /**
      * Asks the user to confirm whether he wants to stop editing via a modal.
      *
-     * @see acceptEditorStateChange()
+     * @param {Drupal.quickedit.EntityModel} entityModel
+     *
+     * @see Drupal.quickedit.AppView#acceptEditorStateChange
      */
     confirmEntityDeactivation: function (entityModel) {
       var that = this;
@@ -370,15 +381,16 @@
               }
             }
           ],
-          // Prevent this modal from being closed without the user making a choice
-          // as per http://stackoverflow.com/a/5438771.
+          // Prevent this modal from being closed without the user making a
+          // choice as per http://stackoverflow.com/a/5438771.
           closeOnEscape: false,
           create: function () {
             $(this).parent().find('.ui-dialog-titlebar-close').remove();
           },
           beforeClose: false,
           close: function (event) {
-            // Automatically destroy the DOM element that was used for the dialog.
+            // Automatically destroy the DOM element that was used for the
+            // dialog.
             $(event.target).remove();
           }
         });
@@ -391,9 +403,10 @@
     /**
      * Reacts to field state changes; tracks global state.
      *
-     * @param Drupal.quickedit.FieldModel fieldModel
-     * @param String state
-     *   The state of the associated field. One of Drupal.quickedit.FieldModel.states.
+     * @param {Drupal.quickedit.FieldModel} fieldModel
+     * @param {string} state
+     *   The state of the associated field. One of
+     *   {@link Drupal.quickedit.FieldModel.states}.
      */
     editorStateChange: function (fieldModel, state) {
       var from = fieldModel.previous('state');
@@ -423,15 +436,15 @@
     /**
      * Render an updated field (a field whose 'html' attribute changed).
      *
-     * @param Drupal.quickedit.FieldModel fieldModel
+     * @param {Drupal.quickedit.FieldModel} fieldModel
      *   The FieldModel whose 'html' attribute changed.
-     * @param String html
+     * @param {string} html
      *   The updated 'html' attribute.
-     * @param Object options
+     * @param {object} options
      *   An object with the following keys:
-     *   - Boolean propagation: whether this change to the 'html' attribute
-     *     occurred because of the propagation of changes to another instance of
-     *     this field.
+     * @param {bool} options.propagation
+     *   Whether this change to the 'html' attribute occurred because of the
+     *   propagation of changes to another instance of this field.
      */
     renderUpdatedField: function (fieldModel, html, options) {
       // Get data necessary to rerender property before it is unavailable.
@@ -458,19 +471,19 @@
       // of this field happens not because of propagation, but because it is
       // being edited itself.
       if (!options.propagation) {
-        // Deferred because renderUpdatedField is reacting to a field model change
-        // event, and we want to make sure that event fully propagates before
-        // making another change to the same model.
+        // Deferred because renderUpdatedField is reacting to a field model
+        // change event, and we want to make sure that event fully propagates
+        // before making another change to the same model.
         _.defer(function () {
           // First set the state to 'candidate', to allow all attached views to
           // clean up all their "active state"-related changes.
           fieldModel.set('state', 'candidate');
 
-          // Similarly, the above .set() call's change event must fully propagate
-          // before calling it again.
+          // Similarly, the above .set() call's change event must fully
+          // propagate before calling it again.
           _.defer(function () {
-            // Set the field's state to 'inactive', to enable the updating of its
-            // DOM value.
+            // Set the field's state to 'inactive', to enable the updating of
+            // its DOM value.
             fieldModel.set('state', 'inactive', {reason: 'rerender'});
 
             renderField();
@@ -483,31 +496,32 @@
     },
 
     /**
-     * Propagates the changes to an updated field to all instances of that field.
+     * Propagates changes to an updated field to all instances of that field.
      *
-     * @param Drupal.quickedit.FieldModel updatedField
+     * @param {Drupal.quickedit.FieldModel} updatedField
      *   The FieldModel whose 'html' attribute changed.
-     * @param String html
+     * @param {string} html
      *   The updated 'html' attribute.
-     * @param Object options
+     * @param {object} options
      *   An object with the following keys:
-     *   - Boolean propagation: whether this change to the 'html' attribute
-     *     occurred because of the propagation of changes to another instance of
-     *     this field.
+     * @param {bool} options.propagation
+     *   Whether this change to the 'html' attribute occurred because of the
+     *   propagation of changes to another instance of this field.
      *
-     * @see Drupal.quickedit.AppView.renderUpdatedField()
+     * @see Drupal.quickedit.AppView#renderUpdatedField
      */
     propagateUpdatedField: function (updatedField, html, options) {
-      // Don't propagate field updates that themselves were caused by propagation.
+      // Don't propagate field updates that themselves were caused by
+      // propagation.
       if (options.propagation) {
         return;
       }
 
       var htmlForOtherViewModes = updatedField.get('htmlForOtherViewModes');
       Drupal.quickedit.collections.fields
-        // Find all instances of fields that display the same logical field (same
-        // entity, same field, just a different instance and maybe a different
-        // view mode).
+        // Find all instances of fields that display the same logical field
+        // (same entity, same field, just a different instance and maybe a
+        // different view mode).
         .where({logicalFieldID: updatedField.get('logicalFieldID')})
         .forEach(function (field) {
           // Ignore the field that was already updated.
@@ -522,8 +536,8 @@
           // If this other instance of the field has a different view mode, and
           // that is one of the view modes for which a re-rendered version is
           // available (and that should be the case unless this field was only
-          // added to the page after editing of the updated field began), then use
-          // that view mode's re-rendered version.
+          // added to the page after editing of the updated field began), then
+          // use that view mode's re-rendered version.
           else {
             if (field.getViewMode() in htmlForOtherViewModes) {
               field.set('html', htmlForOtherViewModes[field.getViewMode()], {propagation: true});
@@ -538,7 +552,7 @@
      *
      * This happens when a field was modified, saved and hence rerendered.
      *
-     * @param Drupal.quickedit.FieldModel fieldModel
+     * @param {Drupal.quickedit.FieldModel} fieldModel
      *   A field that was just added to the collection of fields.
      */
     rerenderedFieldToCandidate: function (fieldModel) {
@@ -557,10 +571,11 @@
     },
 
     /**
-     * EntityModel Collection change handler, called on change:isActive, enforces
-     * a single active entity.
+     * EntityModel Collection change handler.
+     *
+     * Handler is called `change:isActive` and enforces a single active entity.
      *
-     * @param Drupal.quickedit.EntityModel
+     * @param {Drupal.quickedit.EntityModel} changedEntityModel
      *   The entityModel instance whose active state has changed.
      */
     enforceSingleActiveEntity: function (changedEntityModel) {
diff --git a/core/modules/quickedit/js/views/ContextualLinkView.js b/core/modules/quickedit/js/views/ContextualLinkView.js
index 6c50617..75036b1 100644
--- a/core/modules/quickedit/js/views/ContextualLinkView.js
+++ b/core/modules/quickedit/js/views/ContextualLinkView.js
@@ -7,8 +7,13 @@
 
   "use strict";
 
-  Drupal.quickedit.ContextualLinkView = Backbone.View.extend({
+  Drupal.quickedit.ContextualLinkView = Backbone.View.extend(/** @lends Drupal.quickedit.ContextualLinkView# */{
 
+    /**
+     * Define all events to listen to.
+     *
+     * @return {object}
+     */
     events: function () {
       // Prevents delay and simulated mouse events.
       function touchEndToClick(event) {
@@ -26,13 +31,18 @@
     },
 
     /**
-     * {@inheritdoc}
+     * @constructs
      *
-     * @param Object options
+     * @augments Backbone.View
+     *
+     * @param {object} options
      *   An object with the following keys:
-     *   - Drupal.quickedit.EntityModel model: the associated entity's model
-     *   - Drupal.quickedit.AppModel appModel: the application state model
-     *   - strings: the strings for the "Quick edit" link
+     * @param {Drupal.quickedit.EntityModel} options.model
+     *   The associated entity's model.
+     * @param {Drupal.quickedit.AppModel} options.appModel
+     *   The application state model.
+     * @param {object} options.strings
+     *   The strings for the "Quick edit" link.
      */
     initialize: function (options) {
       // Insert the text of the quick edit toggle.
@@ -44,7 +54,11 @@
     },
 
     /**
-     * {@inheritdoc}
+     *
+     * @param {Drupal.quickedit.EntityModel} entityModel
+     * @param {bool} isActive
+     *
+     * @return {Drupal.quickedit.ContextualLinkView}
      */
     render: function (entityModel, isActive) {
       this.$el.find('a').attr('aria-pressed', isActive);
diff --git a/core/modules/quickedit/js/views/EditorView.js b/core/modules/quickedit/js/views/EditorView.js
index e13b0a1..e621528 100644
--- a/core/modules/quickedit/js/views/EditorView.js
+++ b/core/modules/quickedit/js/views/EditorView.js
@@ -7,36 +7,35 @@
 
   "use strict";
 
-  /**
-   * A base implementation that outlines the structure for in-place editors.
-   *
-   * Specific in-place editor implementations should subclass (extend) this View
-   * and override whichever method they deem necessary to override.
-   *
-   * Look at Drupal.quickedit.editors.form and
-   * Drupal.quickedit.editors.plain_text for examples.
-   *
-   * @see Drupal.quickedit.EditorModel
-   */
-  Drupal.quickedit.EditorView = Backbone.View.extend({
+  Drupal.quickedit.EditorView = Backbone.View.extend(/** @lends Drupal.quickedit.EditorView# */{
 
     /**
-     * {@inheritdoc}
+     * A base implementation that outlines the structure for in-place editors.
      *
-     * Typically you would want to override this method to set the originalValue
-     * attribute in the FieldModel to such a value that your in-place editor can
-     * revert to the original value when necessary.
+     * Specific in-place editor implementations should subclass (extend) this
+     * View and override whichever method they deem necessary to override.
      *
-     * If you override this method, you should call this method (the parent
-     * class' initialize()) first, like this:
-     *   Drupal.quickedit.EditorView.prototype.initialize.call(this, options);
+     * Typically you would want to override this method to set the
+     * originalValue attribute in the FieldModel to such a value that your
+     * in-place editor can revert to the original value when necessary.
      *
-     * For an example, @see Drupal.quickedit.editors.plain_text.
+     * @example <caption>If you override this method, you should call this
+     * method (the parent class' initialize()) first.</caption>
+     * Drupal.quickedit.EditorView.prototype.initialize.call(this, options);
      *
-     * @param Object options
+     * @constructs
+     *
+     * @augments Backbone.View
+     *
+     * @param {object} options
      *   An object with the following keys:
-     *   - Drupal.quickedit.EditorModel model: the in-place editor state model
-     *   - Drupal.quickedit.FieldModel fieldModel: the field model
+     * @param {Drupal.quickedit.EditorModel} options.model
+     *   The in-place editor state model.
+     * @param {Drupal.quickedit.FieldModel} options.fieldModel
+     *   The field model.
+     *
+     * @see Drupal.quickedit.EditorModel
+     * @see Drupal.quickedit.editors.plain_text
      */
     initialize: function (options) {
       this.fieldModel = options.fieldModel;
@@ -44,7 +43,7 @@
     },
 
     /**
-     * {@inheritdoc}
+     * @inheritdoc
      */
     remove: function () {
       // The el property is the field, which should not be removed. Remove the
@@ -63,16 +62,18 @@
      * e.g. using a WYSIWYG editor on a body field should happen on the DOM
      * element containing the text itself, not on the field wrapper.
      *
-     * For example, @see Drupal.quickedit.editors.plain_text.
-     *
-     * @return jQuery
+     * @return {jQuery}
      *   A jQuery-wrapped DOM element.
+     *
+     * @see Drupal.quickedit.editors.plain_text
      */
     getEditedElement: function () {
       return this.$el;
     },
 
     /**
+     *
+     * @return {object}
      * Returns 3 Quick Edit UI settings that depend on the in-place editor:
      *  - Boolean padding: indicates whether padding should be applied to the
      *    edited element, to guarantee legibility of text.
@@ -90,9 +91,10 @@
     /**
      * Determines the actions to take given a change of state.
      *
-     * @param Drupal.quickedit.FieldModel fieldModel
-     * @param String state
-     *   The state of the associated field. One of Drupal.quickedit.FieldModel.states.
+     * @param {Drupal.quickedit.FieldModel} fieldModel
+     * @param {string} state
+     *   The state of the associated field. One of
+     *   {@link Drupal.quickedit.FieldModel.states}.
      */
     stateChange: function (fieldModel, state) {
       var from = fieldModel.previous('state');
@@ -102,26 +104,27 @@
           // An in-place editor view will not yet exist in this state, hence
           // this will never be reached. Listed for sake of completeness.
           break;
+
         case 'candidate':
           // Nothing to do for the typical in-place editor: it should not be
-          // visible yet.
-
-          // Except when we come from the 'invalid' state, then we clean up.
+          // visible yet. Except when we come from the 'invalid' state, then we
+          // clean up.
           if (from === 'invalid') {
             this.removeValidationErrors();
           }
           break;
+
         case 'highlighted':
           // Nothing to do for the typical in-place editor: it should not be
           // visible yet.
           break;
+
         case 'activating':
           // The user has indicated he wants to do in-place editing: if
           // something needs to be loaded (CSS/JavaScript/server data/…), then
           // do so at this stage, and once the in-place editor is ready,
-          // set the 'active' state.
-          // A "loading" indicator will be shown in the UI for as long as the
-          // field remains in this state.
+          // set the 'active' state. A "loading" indicator will be shown in the
+          // UI for as long as the field remains in this state.
           var loadDependencies = function (callback) {
             // Do the loading here.
             callback();
@@ -130,30 +133,35 @@
             fieldModel.set('state', 'active');
           });
           break;
+
         case 'active':
           // The user can now actually use the in-place editor.
           break;
+
         case 'changed':
           // Nothing to do for the typical in-place editor. The UI will show an
           // indicator that the field has changed.
           break;
+
         case 'saving':
           // When the user has indicated he wants to save his changes to this
-          // field, this state will be entered.
-          // If the previous saving attempt resulted in validation errors, the
-          // previous state will be 'invalid'. Clean up those validation errors
-          // while the user is saving.
+          // field, this state will be entered. If the previous saving attempt
+          // resulted in validation errors, the previous state will be
+          // 'invalid'. Clean up those validation errors while the user is
+          // saving.
           if (from === 'invalid') {
             this.removeValidationErrors();
           }
           this.save();
           break;
+
         case 'saved':
           // Nothing to do for the typical in-place editor. Immediately after
           // being saved, a field will go to the 'candidate' state, where it
           // should no longer be visible (after all, the field will then again
           // just be a *candidate* to be in-place edited).
           break;
+
         case 'invalid':
           // The modified field value was attempted to be saved, but there were
           // validation errors.
@@ -167,7 +175,6 @@
      */
     revert: function () {
       // A no-op by default; each editor should implement reverting itself.
-
       // Note that if the in-place editor does not cause the FieldModel's
       // element to be modified, then nothing needs to happen.
     },
@@ -233,12 +240,13 @@
           removeHiddenForm();
           // First, transition the state to 'saved'.
           fieldModel.set('state', 'saved');
-          // Second, set the 'htmlForOtherViewModes' attribute, so that when this
-          // field is rerendered, the change can be propagated to other instances of
-          // this field, which may be displayed in different view modes.
+          // Second, set the 'htmlForOtherViewModes' attribute, so that when
+          // this field is rerendered, the change can be propagated to other
+          // instances of this field, which may be displayed in different view
+          // modes.
           fieldModel.set('htmlForOtherViewModes', response.other_view_modes);
-          // Finally, set the 'html' attribute on the field model. This will cause
-          // the field to be rerendered.
+          // Finally, set the 'html' attribute on the field model. This will
+          // cause the field to be rerendered.
           fieldModel.set('html', response.data);
         };
 
diff --git a/core/modules/quickedit/js/views/EntityDecorationView.js b/core/modules/quickedit/js/views/EntityDecorationView.js
index 69a4767..e4607ef 100644
--- a/core/modules/quickedit/js/views/EntityDecorationView.js
+++ b/core/modules/quickedit/js/views/EntityDecorationView.js
@@ -7,26 +7,28 @@
 
   "use strict";
 
-  Drupal.quickedit.EntityDecorationView = Backbone.View.extend({
+  Drupal.quickedit.EntityDecorationView = Backbone.View.extend(/** @lends Drupal.quickedit.EntityDecorationView# */{
 
     /**
-     * {@inheritdoc}
-     *
      * Associated with the DOM root node of an editable entity.
+     *
+     * @constructs
+     *
+     * @augments Backbone.View
      */
     initialize: function () {
       this.listenTo(this.model, 'change', this.render);
     },
 
     /**
-     * {@inheritdoc}
+     * @inheritdoc
      */
     render: function () {
       this.$el.toggleClass('quickedit-entity-active', this.model.get('isActive'));
     },
 
     /**
-     * {@inheritdoc}
+     * @inheritdoc
      */
     remove: function () {
       this.setElement(null);
diff --git a/core/modules/quickedit/js/views/EntityToolbarView.js b/core/modules/quickedit/js/views/EntityToolbarView.js
index 800311d..f2a7f47 100644
--- a/core/modules/quickedit/js/views/EntityToolbarView.js
+++ b/core/modules/quickedit/js/views/EntityToolbarView.js
@@ -7,10 +7,16 @@
 
   "use strict";
 
-  Drupal.quickedit.EntityToolbarView = Backbone.View.extend({
+  Drupal.quickedit.EntityToolbarView = Backbone.View.extend(/** @lends Drupal.quickedit.EntityToolbarView# */{
 
+    /**
+     * @type {jQuery}
+     */
     _fieldToolbarRoot: null,
 
+    /**
+     * @return {object}
+     */
     events: function () {
       var map = {
         'click button.action-save': 'onClickSave',
@@ -21,7 +27,12 @@
     },
 
     /**
-     * {@inheritdoc}
+     * @constructs
+     *
+     * @augments Backbone.View
+     *
+     * @param {object} options
+     * @param {Drupal.quickedit.AppModel} options.appModel
      */
     initialize: function (options) {
       var that = this;
@@ -35,8 +46,8 @@
       // Rerender when a field of the entity changes state.
       this.listenTo(this.model.get('fields'), 'change:state', this.fieldStateChange);
 
-      // Reposition the entity toolbar as the viewport and the position within the
-      // viewport changes.
+      // Reposition the entity toolbar as the viewport and the position within
+      // the viewport changes.
       $(window).on('resize.quickedit scroll.quickedit', debounce($.proxy(this.windowChangeHandler, this), 150));
 
       // Adjust the fence placement within which the entity toolbar may be
@@ -57,7 +68,9 @@
     },
 
     /**
-     * {@inheritdoc}
+     * @inheritdoc
+     *
+     * @return {Drupal.quickedit.EntityToolbarView}
      */
     render: function () {
       if (this.model.get('isActive')) {
@@ -83,7 +96,8 @@
         this.position();
       }
 
-      // The save button text and state varies with the state of the entity model.
+      // The save button text and state varies with the state of the entity
+      // model.
       var $button = this.$el.find('.quickedit-button.action-save');
       var isDirty = this.model.get('isDirty');
       // Adjust the save button according to the state of the model.
@@ -98,6 +112,7 @@
             .removeAttr('disabled')
             .attr('aria-hidden', !isDirty);
           break;
+
         // The changes to the fields of the entity are being committed.
         case 'committing':
           $button
@@ -105,6 +120,7 @@
             .text(Drupal.t('Saving'))
             .attr('disabled', 'disabled');
           break;
+
         default:
           $button.attr('aria-hidden', true);
           break;
@@ -114,7 +130,7 @@
     },
 
     /**
-     * {@inheritdoc}
+     * @inheritdoc
      */
     remove: function () {
       // Remove additional DOM elements controlled by this View.
@@ -130,7 +146,7 @@
     /**
      * Repositions the entity toolbar on window scroll and resize.
      *
-     * @param jQuery.Event event
+     * @param {jQuery.Event} event
      */
     windowChangeHandler: function (event) {
       this.position();
@@ -139,15 +155,17 @@
     /**
      * Determines the actions to take given a change of state.
      *
-     * @param Drupal.quickedit.FieldModel model
-     * @param String state
-     *   The state of the associated field. One of Drupal.quickedit.FieldModel.states.
+     * @param {Drupal.quickedit.FieldModel} model
+     * @param {string} state
+     *   The state of the associated field. One of
+     *   {@link Drupal.quickedit.FieldModel.states}.
      */
     fieldStateChange: function (model, state) {
       switch (state) {
         case 'active':
           this.render();
           break;
+
         case 'invalid':
           this.render();
           break;
@@ -157,8 +175,8 @@
     /**
      * Uses the jQuery.ui.position() method to position the entity toolbar.
      *
-     * @param jQuery|DOM element
-     *   (optional) The element against which the entity toolbar is positioned.
+     * @param {HTMLElement} [element]
+     *   The element against which the entity toolbar is positioned.
      */
     position: function (element) {
       clearTimeout(this.timer);
@@ -169,7 +187,8 @@
       var edge = (document.documentElement.dir === 'rtl') ? 'right' : 'left';
       // A time unit to wait until the entity toolbar is repositioned.
       var delay = 0;
-      // Determines what check in the series of checks below should be evaluated
+      // Determines what check in the series of checks below should be
+      // evaluated.
       var check = 0;
       // When positioned against an active field that has padding, we should
       // ignore that padding when positioning the toolbar, to not unnecessarily
@@ -186,11 +205,13 @@
             // Position against a specific element.
             of = element;
             break;
+
           case 1:
             // Position against a form container.
             activeField = Drupal.quickedit.app.model.get('activeField');
             of = activeField && activeField.editorView && activeField.editorView.$formContainer && activeField.editorView.$formContainer.find('.quickedit-form');
             break;
+
           case 2:
             // Position against an active field.
             of = activeField && activeField.editorView && activeField.editorView.getEditedElement();
@@ -198,12 +219,14 @@
               horizontalPadding = 5;
             }
             break;
+
           case 3:
             // Position against a highlighted field.
             highlightedField = Drupal.quickedit.app.model.get('highlightedField');
             of = highlightedField && highlightedField.editorView && highlightedField.editorView.getEditedElement();
             delay = 250;
             break;
+
           default:
             var fieldModels = this.model.get('fields').models;
             var topMostPosition = 1000000;
@@ -230,18 +253,21 @@
        * Invoked as the 'using' callback of jquery.ui.position() in
        * positionToolbar().
        *
-       * @param Object suggested
+       * @param {*} view
+       * @param {object} suggested
        *   A hash of top and left values for the position that should be set. It
        *   can be forwarded to .css() or .animate().
-       * @param Object info
+       * @param {object} info
        *   The position and dimensions of both the 'my' element and the 'of'
        *   elements, as well as calculations to their relative position. This
        *   object contains the following properties:
-       *     - Object element: A hash that contains information about the HTML
-       *     element that will be positioned. Also known as the 'my' element.
-       *     - Object target: A hash that contains information about the HTML
-       *     element that the 'my' element will be positioned against. Also known
-       *     as the 'of' element.
+       * @param {object} info.element
+       *   A hash that contains information about the HTML element that will be
+       *   positioned. Also known as the 'my' element.
+       * @param {object} info.target
+       *   A hash that contains information about the HTML element that the
+       *   'my' element will be positioned against. Also known as the 'of'
+       *   element.
        */
       function refinePosition(view, suggested, info) {
         // Determine if the pointer should be on the top or bottom.
@@ -250,8 +276,8 @@
         // Don't position the toolbar past the first or last editable field if
         // the entity is the target.
         if (view.$entity[0] === info.target.element[0]) {
-          // Get the first or last field according to whether the toolbar is above
-          // or below the entity.
+          // Get the first or last field according to whether the toolbar is
+          // above or below the entity.
           var $field = view.$entity.find('.quickedit-editable').eq((isBelow) ? -1 : 0);
           if ($field.length > 0) {
             suggested.top = (isBelow) ? ($field.offset().top + $field.outerHeight(true)) : $field.offset().top - info.element.element.outerHeight(true);
@@ -282,8 +308,9 @@
           .position({
             my: edge + ' bottom',
             // Move the toolbar 1px towards the start edge of the 'of' element,
-            // plus any horizontal padding that may have been added to the element
-            // that is being added, to prevent unwanted horizontal movement.
+            // plus any horizontal padding that may have been added to the
+            // element that is being added, to prevent unwanted horizontal
+            // movement.
             at: edge + '+' + (1 + horizontalPadding) + ' top',
             of: of,
             collision: 'flipfit',
@@ -306,10 +333,10 @@
       // only after the user has focused on an editable for 250ms. This prevents
       // the toolbar from jumping around the screen.
       this.timer = setTimeout(function () {
-        // Render the position in the next execution cycle, so that animations on
-        // the field have time to process. This is not strictly speaking, a
-        // guarantee that all animations will be finished, but it's a simple way
-        // to get better positioning without too much additional code.
+        // Render the position in the next execution cycle, so that animations
+        // on the field have time to process. This is not strictly speaking, a
+        // guarantee that all animations will be finished, but it's a simple
+        // way to get better positioning without too much additional code.
         _.defer(positionToolbar);
       }, delay);
     },
@@ -317,7 +344,7 @@
     /**
      * Set the model state to 'saving' when the save button is clicked.
      *
-     * @param jQuery event
+     * @param {jQuery.Event} event
      */
     onClickSave: function (event) {
       event.stopPropagation();
@@ -329,7 +356,7 @@
     /**
      * Sets the model state to candidate when the cancel button is clicked.
      *
-     * @param jQuery event
+     * @param {jQuery.Event} event
      */
     onClickCancel: function (event) {
       event.preventDefault();
@@ -341,7 +368,7 @@
      *
      * Without this, it may reposition itself, away from the user's cursor!
      *
-     * @param jQuery event
+     * @param {jQuery.Event} event
      */
     onMouseenter: function (event) {
       clearTimeout(this.timer);
@@ -349,6 +376,8 @@
 
     /**
      * Builds the entity toolbar HTML; attaches to DOM; sets starting position.
+     *
+     * @return {jQuery}
      */
     buildToolbarEl: function () {
       var $toolbar = $(Drupal.theme('quickeditEntityToolbar', {
@@ -376,8 +405,8 @@
           ]
         }));
 
-      // Give the toolbar a sensible starting position so that it doesn't animate
-      // on to the screen from a far off corner.
+      // Give the toolbar a sensible starting position so that it doesn't
+      // animate on to the screen from a far off corner.
       $toolbar
         .css({
           left: this.$entity.offset().left,
@@ -390,7 +419,7 @@
     /**
      * Returns the DOM element that fields will attach their toolbars to.
      *
-     * @return jQuery
+     * @return {jQuery}
      *   The DOM element that fields will attach their toolbars to.
      */
     getToolbarRoot: function () {
@@ -436,9 +465,9 @@
     /**
      * Adds classes to a toolgroup.
      *
-     * @param String toolgroup
+     * @param {string} toolgroup
      *   A toolgroup name.
-     * @param String classes
+     * @param {string} classes
      *   A string of space-delimited class names that will be applied to the
      *   wrapping element of the toolbar group.
      */
@@ -449,9 +478,9 @@
     /**
      * Removes classes from a toolgroup.
      *
-     * @param String toolgroup
+     * @param {string} toolgroup
      *   A toolgroup name.
-     * @param String classes
+     * @param {string} classes
      *   A string of space-delimited class names that will be removed from the
      *   wrapping element of the toolbar group.
      */
@@ -462,9 +491,10 @@
     /**
      * Finds a toolgroup.
      *
-     * @param String toolgroup
+     * @param {string} toolgroup
      *   A toolgroup name.
-     * @return jQuery
+     *
+     * @return {jQuery}
      *   The toolgroup DOM element.
      */
     _find: function (toolgroup) {
@@ -474,7 +504,7 @@
     /**
      * Shows a toolgroup.
      *
-     * @param String toolgroup
+     * @param {string} toolgroup
      *   A toolgroup name.
      */
     show: function (toolgroup) {
diff --git a/core/modules/quickedit/js/views/FieldDecorationView.js b/core/modules/quickedit/js/views/FieldDecorationView.js
index 49491da..8de4b16 100644
--- a/core/modules/quickedit/js/views/FieldDecorationView.js
+++ b/core/modules/quickedit/js/views/FieldDecorationView.js
@@ -7,10 +7,16 @@
 
   "use strict";
 
-  Drupal.quickedit.FieldDecorationView = Backbone.View.extend({
+  Drupal.quickedit.FieldDecorationView = Backbone.View.extend(/** @lends Drupal.quickedit.FieldDecorationView# */{
 
+    /**
+     * @type {null}
+     */
     _widthAttributeIsEmpty: null,
 
+    /**
+     * @type {object}
+     */
     events: {
       'mouseenter.quickedit': 'onMouseEnter',
       'mouseleave.quickedit': 'onMouseLeave',
@@ -20,11 +26,14 @@
     },
 
     /**
-     * {@inheritdoc}
+     * @constructs
      *
-     * @param Object options
+     * @augments Backbone.View
+     *
+     * @param {object} options
      *   An object with the following keys:
-     *   - Drupal.quickedit.EditorView editorView: the editor object view.
+     * @param {Drupal.quickedit.EditorView} options.editorView
+     *   The editor object view.
      */
     initialize: function (options) {
       this.editorView = options.editorView;
@@ -34,7 +43,7 @@
     },
 
     /**
-     * {@inheritdoc}
+     * @inheritdoc
      */
     remove: function () {
       // The el property is the field, which should not be removed. Remove the
@@ -46,9 +55,10 @@
     /**
      * Determines the actions to take given a change of state.
      *
-     * @param Drupal.quickedit.FieldModel model
-     * @param String state
-     *   The state of the associated field. One of Drupal.quickedit.FieldModel.states.
+     * @param {Drupal.quickedit.FieldModel} model
+     * @param {string} state
+     *   The state of the associated field. One of
+     *   {@link Drupal.quickedit.FieldModel.states}.
      */
     stateChange: function (model, state) {
       var from = model.previous('state');
@@ -57,6 +67,7 @@
         case 'inactive':
           this.undecorate();
           break;
+
         case 'candidate':
           this.decorate();
           if (from !== 'inactive') {
@@ -68,14 +79,17 @@
           }
           this._unpad();
           break;
+
         case 'highlighted':
           this.startHighlight();
           break;
+
         case 'activating':
-          // NOTE: this state is not used by every editor! It's only used by those
-          // that need to interact with the server.
+          // NOTE: this state is not used by every editor! It's only used by
+          // those that need to interact with the server.
           this.prepareEdit();
           break;
+
         case 'active':
           if (from !== 'activating') {
             this.prepareEdit();
@@ -84,13 +98,17 @@
             this._pad();
           }
           break;
+
         case 'changed':
           this.model.set('isChanged', true);
           break;
+
         case 'saving':
           break;
+
         case 'saved':
           break;
+
         case 'invalid':
           break;
       }
@@ -109,7 +127,7 @@
     /**
      * Starts hover; transitions to 'highlight' state.
      *
-     * @param jQuery event
+     * @param {jQuery.Event} event
      */
     onMouseEnter: function (event) {
       var that = this;
@@ -120,7 +138,7 @@
     /**
      * Stops hover; transitions to 'candidate' state.
      *
-     * @param jQuery event
+     * @param {jQuery.Event} event
      */
     onMouseLeave: function (event) {
       var that = this;
@@ -131,7 +149,7 @@
     /**
      * Transition to 'activating' stage.
      *
-     * @param jQuery event
+     * @param {jQuery.Event} event
      */
     onClick: function (event) {
       this.model.set('state', 'activating');
@@ -202,7 +220,7 @@
     },
 
     /**
-     * Adds padding around the editable element in order to make it pop visually.
+     * Adds padding around the editable element to make it pop visually.
      */
     _pad: function () {
       // Early return if the element has already been padded.
@@ -212,8 +230,8 @@
       var self = this;
 
       // Add 5px padding for readability. This means we'll freeze the current
-      // width and *then* add 5px padding, hence ensuring the padding is added "on
-      // the outside".
+      // width and *then* add 5px padding, hence ensuring the padding is added
+      // "on the outside".
       // 1) Freeze the width (if it's not already set); don't use animations.
       if (this.$el[0].style.width === "") {
         this._widthAttributeIsEmpty = true;
@@ -294,7 +312,9 @@
      * Convert extraneous values and information into numbers ready for
      * subtraction.
      *
-     * @param DOM $e
+     * @param {jQuery} $e
+     *
+     * @return {object}
      */
     _getPositionProperties: function ($e) {
       var p;
@@ -314,10 +334,12 @@
     },
 
     /**
-     * Replaces blank or 'auto' CSS "position: <value>" values with "0px".
+     * Replaces blank or 'auto' CSS `position: <value>` values with "0px".
+     *
+     * @param {string} [pos]
+     *   The value for a CSS position declaration.
      *
-     * @param String pos
-     *   (optional) The value for a CSS position declaration.
+     * @return {string}
      */
     _replaceBlankPosition: function (pos) {
       if (pos === 'auto' || !pos) {
diff --git a/core/modules/quickedit/js/views/FieldToolbarView.js b/core/modules/quickedit/js/views/FieldToolbarView.js
index 24676ed..0d28310 100644
--- a/core/modules/quickedit/js/views/FieldToolbarView.js
+++ b/core/modules/quickedit/js/views/FieldToolbarView.js
@@ -7,22 +7,44 @@
 
   "use strict";
 
-  Drupal.quickedit.FieldToolbarView = Backbone.View.extend({
+  Drupal.quickedit.FieldToolbarView = Backbone.View.extend(/** @lends Drupal.quickedit.FieldToolbarView# */{
 
-    // The edited element, as indicated by EditorView.getEditedElement().
+    /**
+     * The edited element, as indicated by EditorView.getEditedElement.
+     *
+     * @type {jQuery}
+     */
     $editedElement: null,
 
-    // A reference to the in-place editor.
+    /**
+     * A reference to the in-place editor.
+     *
+     * @type {Drupal.quickedit.EditorView}
+     */
     editorView: null,
 
+    /**
+     * @type {string}
+     */
     _id: null,
 
     /**
-     * {@inheritdoc}
+     * @constructs
+     *
+     * @augments Backbone.View
+     *
+     * @param {object} options
+     * @param {jQuery} options.$editedElement
+     * @param {Drupal.quickedit.EditorView} options.editorView
      */
     initialize: function (options) {
       this.$editedElement = options.$editedElement;
       this.editorView = options.editorView;
+
+      /**
+       *
+       * @type {jQuery}
+       */
       this.$root = this.$el;
 
       // Generate a DOM-compatible ID for the form container DOM element.
@@ -32,7 +54,9 @@
     },
 
     /**
-     * {@inheritdoc}
+     * @inheritdoc
+     *
+     * @return {Drupal.quickedit.FieldToolbarView}
      */
     render: function () {
       // Render toolbar and set it as the view's element.
@@ -49,8 +73,8 @@
     /**
      * Determines the actions to take given a change of state.
      *
-     * @param Drupal.quickedit.FieldModel model
-     * @param String state
+     * @param {Drupal.quickedit.FieldModel} model
+     * @param {string} state
      *   The state of the associated field. One of Drupal.quickedit.FieldModel.states.
      */
     stateChange: function (model, state) {
@@ -59,6 +83,7 @@
       switch (to) {
         case 'inactive':
           break;
+
         case 'candidate':
           // Remove the view's existing element if we went to the 'activating'
           // state or later, because it will be recreated. Not doing this would
@@ -68,8 +93,10 @@
             this.setElement();
           }
           break;
+
         case 'highlighted':
           break;
+
         case 'activating':
           this.render();
 
@@ -81,14 +108,19 @@
             this.insertWYSIWYGToolGroups();
           }
           break;
+
         case 'active':
           break;
+
         case 'changed':
           break;
+
         case 'saving':
           break;
+
         case 'saved':
           break;
+
         case 'invalid':
           break;
       }
@@ -120,7 +152,7 @@
      *
      * Only used to make sane hovering behavior possible.
      *
-     * @return String
+     * @return {string}
      *   A string that can be used as the ID for this toolbar's container.
      */
     getId: function () {
@@ -132,7 +164,7 @@
      *
      * Used to provide an abstraction for any WYSIWYG editor to plug in.
      *
-     * @return String
+     * @return {string}
      *   A string that can be used as the ID.
      */
     getFloatedWysiwygToolgroupId: function () {
@@ -144,7 +176,7 @@
      *
      * Used to provide an abstraction for any WYSIWYG editor to plug in.
      *
-     * @return String
+     * @return {string}
      *   A string that can be used as the ID.
      */
     getMainWysiwygToolgroupId: function () {
@@ -154,9 +186,10 @@
     /**
      * Finds a toolgroup.
      *
-     * @param String toolgroup
+     * @param {string} toolgroup
      *   A toolgroup name.
-     * @return jQuery
+     *
+     * @return {jQuery}
      */
     _find: function (toolgroup) {
       return this.$el.find('.quickedit-toolgroup.' + toolgroup);
@@ -165,7 +198,7 @@
     /**
      * Shows a toolgroup.
      *
-     * @param String toolgroup
+     * @param {string} toolgroup
      *   A toolgroup name.
      */
     show: function (toolgroup) {
diff --git a/core/modules/toolbar/js/escapeAdmin.js b/core/modules/toolbar/js/escapeAdmin.js
index 0544a40..f47b8b9 100644
--- a/core/modules/toolbar/js/escapeAdmin.js
+++ b/core/modules/toolbar/js/escapeAdmin.js
@@ -1,8 +1,8 @@
 /**
  * @file
- *
  * Replaces the home link in toolbar with a back to site link.
  */
+
 (function ($, Drupal, drupalSettings) {
 
   "use strict";
@@ -24,6 +24,8 @@
    *
    * Back to site link points to the last non-administrative page the user visited
    * within the same browser tab.
+   *
+   * @type {Drupal~behavior}
    */
   Drupal.behaviors.escapeAdmin = {
     attach: function () {
diff --git a/core/modules/toolbar/js/models/MenuModel.js b/core/modules/toolbar/js/models/MenuModel.js
index 07bc942..5f302bb 100644
--- a/core/modules/toolbar/js/models/MenuModel.js
+++ b/core/modules/toolbar/js/models/MenuModel.js
@@ -9,9 +9,23 @@
 
   /**
    * Backbone Model for collapsible menus.
+   *
+   * @constructor
+   *
+   * @augments Backbone.Model
    */
-  Drupal.toolbar.MenuModel = Backbone.Model.extend({
-    defaults: {
+  Drupal.toolbar.MenuModel = Backbone.Model.extend(/** @lends Drupal.toolbar.MenuModel# */{
+
+    /**
+     * @type {object}
+     *
+     * @prop {object} subtrees
+     */
+    defaults: /** @lends Drupal.toolbar.MenuModel# */{
+
+      /**
+       * @type {object}
+       */
       subtrees: {}
     }
   });
diff --git a/core/modules/toolbar/js/models/ToolbarModel.js b/core/modules/toolbar/js/models/ToolbarModel.js
index 77433bf..a74462d 100644
--- a/core/modules/toolbar/js/models/ToolbarModel.js
+++ b/core/modules/toolbar/js/models/ToolbarModel.js
@@ -9,43 +9,123 @@
 
   /**
    * Backbone model for the toolbar.
+   *
+   * @constructor
+   *
+   * @augments Backbone.Model
    */
-  Drupal.toolbar.ToolbarModel = Backbone.Model.extend({
-    defaults: {
-      // The active toolbar tab. All other tabs should be inactive under
-      // normal circumstances. It will remain active across page loads. The
-      // active item is stored as an ID selector e.g. '#toolbar-item--1'.
+  Drupal.toolbar.ToolbarModel = Backbone.Model.extend(/** @lends Drupal.toolbar.ToolbarModel# */{
+
+    /**
+     * @type {object}
+     *
+     * @prop activeTab
+     * @prop activeTray
+     * @prop isOriented
+     * @prop isFixed
+     * @prop areSubtreesLoaded
+     * @prop isViewportOverflowConstrained
+     * @prop orientation
+     * @prop locked
+     * @prop isTrayToggleVisible
+     * @prop height
+     * @prop offsets
+     */
+    defaults: /** @lends Drupal.toolbar.ToolbarModel# */{
+
+      /**
+       * The active toolbar tab. All other tabs should be inactive under
+       * normal circumstances. It will remain active across page loads. The
+       * active item is stored as an ID selector e.g. '#toolbar-item--1'.
+       *
+       * @type {string}
+       */
       activeTab: null,
-      // Represents whether a tray is open or not. Stored as an ID selector e.g.
-      // '#toolbar-item--1-tray'.
+
+      /**
+       * Represents whether a tray is open or not. Stored as an ID selector e.g.
+       * '#toolbar-item--1-tray'.
+       *
+       * @type {string}
+       */
       activeTray: null,
-      // Indicates whether the toolbar is displayed in an oriented fashion,
-      // either horizontal or vertical.
+
+      /**
+       * Indicates whether the toolbar is displayed in an oriented fashion,
+       * either horizontal or vertical.
+       *
+       * @type {bool}
+       */
       isOriented: false,
-      // Indicates whether the toolbar is positioned absolute (false) or fixed
-      // (true).
+
+      /**
+       * Indicates whether the toolbar is positioned absolute (false) or fixed
+       * (true).
+       *
+       * @type {bool}
+       */
       isFixed: false,
-      // Menu subtrees are loaded through an AJAX request only when the Toolbar
-      // is set to a vertical orientation.
+
+      /**
+       * Menu subtrees are loaded through an AJAX request only when the Toolbar
+       * is set to a vertical orientation.
+       *
+       * @type {bool}
+       */
       areSubtreesLoaded: false,
-      // If the viewport overflow becomes constrained, isFixed must be true so
-      // that elements in the trays aren't lost off-screen and impossible to
-      // get to.
+
+      /**
+       * If the viewport overflow becomes constrained, isFixed must be true so
+       * that elements in the trays aren't lost off-screen and impossible to
+       * get to.
+       *
+       * @type {bool}
+       */
       isViewportOverflowConstrained: false,
-      // The orientation of the active tray.
+
+      /**
+       * The orientation of the active tray.
+       *
+       * @type {string}
+       */
       orientation: 'vertical',
-      // A tray is locked if a user toggled it to vertical. Otherwise a tray
-      // will switch between vertical and horizontal orientation based on the
-      // configured breakpoints. The locked state will be maintained across page
-      // loads.
+
+      /**
+       * A tray is locked if a user toggled it to vertical. Otherwise a tray
+       * will switch between vertical and horizontal orientation based on the
+       * configured breakpoints. The locked state will be maintained across page
+       * loads.
+       *
+       * @type {bool}
+       */
       locked: false,
-      // Indicates whether the tray orientation toggle is visible.
+
+      /**
+       * Indicates whether the tray orientation toggle is visible.
+       *
+       * @type {bool}
+       */
       isTrayToggleVisible: false,
-      // The height of the toolbar.
+
+      /**
+       * The height of the toolbar.
+       *
+       * @type {number}
+       */
       height: null,
-      // The current viewport offsets determined by Drupal.displace(). The
-      // offsets suggest how a module might position is components relative to
-      // the viewport.
+
+      /**
+       * The current viewport offsets determined by Drupal.displace(). The
+       * offsets suggest how a module might position is components relative to
+       * the viewport.
+       *
+       * @type {object}
+       *
+       * @prop {number} top
+       * @prop {number} right
+       * @prop {number} bottom
+       * @prop {number} left
+       */
       offsets: {
         top: 0,
         right: 0,
@@ -55,7 +135,12 @@
     },
 
     /**
-     * {@inheritdoc}
+     * @inheritdoc
+     *
+     * @param {object} attributes
+     * @param {object} options
+     *
+     * @return {string}
      */
     validate: function (attributes, options) {
       // Prevent the orientation being set to horizontal if it is locked, unless
diff --git a/core/modules/toolbar/js/toolbar.js b/core/modules/toolbar/js/toolbar.js
index efbad03..cd44b7f 100644
--- a/core/modules/toolbar/js/toolbar.js
+++ b/core/modules/toolbar/js/toolbar.js
@@ -1,8 +1,8 @@
 /**
- * @file toolbar.js
- *
+ * @file
  * Defines the behavior of the Drupal administration toolbar.
  */
+
 (function ($, Drupal, drupalSettings) {
 
   "use strict";
@@ -33,9 +33,10 @@
    * point directly to a resource or toggle the visibility of a tray.
    *
    * Modules register tabs with hook_toolbar().
+   *
+   * @type {Drupal~behavior}
    */
   Drupal.behaviors.toolbar = {
-
     attach: function (context) {
       // Verify that the user agent understands media queries. Complex admin
       // toolbar layouts require media query support.
@@ -138,16 +139,30 @@
 
   /**
    * Toolbar methods of Backbone objects.
+   *
+   * @namespace
    */
   Drupal.toolbar = {
 
-    // A hash of View instances.
+    /**
+     * A hash of View instances.
+     *
+     * @type {object.<string, Backbone.View>}
+     */
     views: {},
 
-    // A hash of Model instances.
+    /**
+     * A hash of Model instances.
+     *
+     * @type {object.<string, Backbone.Model>}
+     */
     models: {},
 
-    // A hash of MediaQueryList objects tracked by the toolbar.
+    /**
+     * A hash of MediaQueryList objects tracked by the toolbar.
+     *
+     * @type {object.<string, object>}
+     */
     mql: {},
 
     /**
@@ -155,13 +170,18 @@
      *
      * A deferred object that is resolved by an inlined JavaScript callback.
      *
-     * JSONP callback.
+     * @type {jQuery.Deferred}
+     *
      * @see toolbar_subtrees_jsonp().
      */
     setSubtrees: new $.Deferred(),
 
     /**
      * Respond to configured narrow media query changes.
+     *
+     * @param {Drupal.toolbar.ToolbarModel} model
+     * @param {string} label
+     * @param {object} mql
      */
     mediaQueryChangeHandler: function (model, label, mql) {
       switch (label) {
@@ -177,11 +197,13 @@
             model.set({'orientation': 'vertical'}, {validate: true});
           }
           break;
+
         case 'toolbar.standard':
           model.set({
             'isFixed': mql.matches
           });
           break;
+
         case 'toolbar.wide':
           model.set({
             'orientation': ((mql.matches) ? 'horizontal' : 'vertical')
@@ -192,6 +214,7 @@
             'isTrayToggleVisible': mql.matches
           });
           break;
+
         default:
           break;
       }
@@ -201,7 +224,7 @@
   /**
    * A toggle is an interactive element often bound to a click handler.
    *
-   * @return {String}
+   * @return {string}
    *   A string representing a DOM fragment.
    */
   Drupal.theme.toolbarOrientationToggle = function () {
diff --git a/core/modules/toolbar/js/toolbar.menu.js b/core/modules/toolbar/js/toolbar.menu.js
index e590297..156c49e 100644
--- a/core/modules/toolbar/js/toolbar.menu.js
+++ b/core/modules/toolbar/js/toolbar.menu.js
@@ -1,8 +1,11 @@
 /**
+ * @file
  * Builds a nested accordion widget.
  *
  * Invoke on an HTML list element with the jQuery plugin pattern.
- * - For example, $('.toolbar-menu').drupalToolbarMenu();
+ *
+ * @example
+ * $('.toolbar-menu').drupalToolbarMenu();
  */
 
 (function ($, Drupal, drupalSettings) {
@@ -77,7 +80,7 @@
       // Adjust the toggle text.
       $toggle
         .find('.action')
-        // Expand Structure, Collapse Structure
+        // Expand Structure, Collapse Structure.
         .text((switcher) ? ui.handleClose : ui.handleOpen);
     }
 
@@ -121,7 +124,7 @@
      * @param {jQuery} $lists
      *   A jQuery object of ul elements.
      *
-     * @param {Integer} level
+     * @param {number} level
      *   The current level number to be assigned to the list elements.
      */
     function markListLevels($lists, level) {
@@ -175,7 +178,12 @@
   /**
    * A toggle is an interactive element often bound to a click handler.
    *
-   * @return {String}
+   * @param {object} options
+   * @param {string} options.class
+   * @param {string} options.action
+   * @param {string} options.text
+   *
+   * @return {string}
    *   A string representing a DOM fragment.
    */
   Drupal.theme.toolbarMenuItemToggle = function (options) {
diff --git a/core/modules/toolbar/js/views/BodyVisualView.js b/core/modules/toolbar/js/views/BodyVisualView.js
index 00abcf2..7499646 100644
--- a/core/modules/toolbar/js/views/BodyVisualView.js
+++ b/core/modules/toolbar/js/views/BodyVisualView.js
@@ -7,20 +7,21 @@
 
   "use strict";
 
-  /**
-   * Adjusts the body element with the toolbar position and dimension changes.
-   */
-  Drupal.toolbar.BodyVisualView = Backbone.View.extend({
+  Drupal.toolbar.BodyVisualView = Backbone.View.extend(/** @lends Drupal.toolbar.BodyVisualView# */{
 
     /**
-     * {@inheritdoc}
+     * Adjusts the body element with the toolbar position and dimension changes.
+     *
+     * @constructs
+     *
+     * @augments Backbone.View
      */
     initialize: function () {
       this.listenTo(this.model, 'change:orientation change:offsets change:activeTray change:isOriented change:isFixed change:isViewportOverflowConstrained', this.render);
     },
 
     /**
-     * {@inheritdoc}
+     * @inheritdoc
      */
     render: function () {
       var $body = $('body');
diff --git a/core/modules/toolbar/js/views/MenuVisualView.js b/core/modules/toolbar/js/views/MenuVisualView.js
index 917259b..f75bb71 100644
--- a/core/modules/toolbar/js/views/MenuVisualView.js
+++ b/core/modules/toolbar/js/views/MenuVisualView.js
@@ -7,19 +7,21 @@
 
   "use strict";
 
-  /**
-   * Backbone View for collapsible menus.
-   */
-  Drupal.toolbar.MenuVisualView = Backbone.View.extend({
+  Drupal.toolbar.MenuVisualView = Backbone.View.extend(/** @lends Drupal.toolbar.MenuVisualView# */{
+
     /**
-     * {@inheritdoc}
+     * Backbone View for collapsible menus.
+     *
+     * @constructs
+     *
+     * @augments Backbone.View
      */
     initialize: function () {
       this.listenTo(this.model, 'change:subtrees', this.render);
     },
 
     /**
-     * {@inheritdoc}
+     * @inheritdoc
      */
     render: function () {
       var subtrees = this.model.get('subtrees');
diff --git a/core/modules/toolbar/js/views/ToolbarAuralView.js b/core/modules/toolbar/js/views/ToolbarAuralView.js
index 9a2183e..d5f6f19 100644
--- a/core/modules/toolbar/js/views/ToolbarAuralView.js
+++ b/core/modules/toolbar/js/views/ToolbarAuralView.js
@@ -7,13 +7,17 @@
 
   "use strict";
 
-  /**
-   * Backbone view for the aural feedback of the toolbar.
-   */
-  Drupal.toolbar.ToolbarAuralView = Backbone.View.extend({
+  Drupal.toolbar.ToolbarAuralView = Backbone.View.extend(/** @lends Drupal.toolbar.ToolbarAuralView# */{
 
     /**
-     * {@inheritdoc}
+     * Backbone view for the aural feedback of the toolbar.
+     *
+     * @constructs
+     *
+     * @augments Backbone.View
+     *
+     * @param {object} options
+     * @param {object} options.strings
      */
     initialize: function (options) {
       this.strings = options.strings;
@@ -25,8 +29,8 @@
     /**
      * Announces an orientation change.
      *
-     * @param Drupal.Toolbar.ToolbarModel model
-     * @param String orientation
+     * @param {Drupal.Toolbar.ToolbarModel} model
+     * @param {string} orientation
      *   The new value of the orientation attribute in the model.
      */
     onOrientationChange: function (model, orientation) {
@@ -38,8 +42,8 @@
     /**
      * Announces a changed active tray.
      *
-     * @param Drupal.Toolbar.ToolbarModel model
-     * @param Element orientation
+     * @param {Drupal.toolbar.ToolbarModel} model
+     * @param {HTMLElement} tray
      *   The new value of the tray attribute in the model.
      */
     onActiveTrayChange: function (model, tray) {
diff --git a/core/modules/toolbar/js/views/ToolbarVisualView.js b/core/modules/toolbar/js/views/ToolbarVisualView.js
index f30bde3..3459404 100644
--- a/core/modules/toolbar/js/views/ToolbarVisualView.js
+++ b/core/modules/toolbar/js/views/ToolbarVisualView.js
@@ -7,11 +7,11 @@
 
   "use strict";
 
-  /**
-   * Backbone view for the toolbar element. Listens to mouse & touch.
-   */
-  Drupal.toolbar.ToolbarVisualView = Backbone.View.extend({
+  Drupal.toolbar.ToolbarVisualView = Backbone.View.extend(/** @lends Drupal.toolbar.ToolbarVisualView# */{
 
+    /**
+     * @return {object}
+     */
     events: function () {
       // Prevents delay and simulated mouse events.
       var touchEndToClick = function (event) {
@@ -28,7 +28,14 @@
     },
 
     /**
-     * {@inheritdoc}
+     * Backbone view for the toolbar element. Listens to mouse & touch.
+     *
+     * @constructs
+     *
+     * @augments Backbone.View
+     *
+     * @param {object} options
+     * @param {object} options.strings
      */
     initialize: function (options) {
       this.strings = options.strings;
@@ -48,7 +55,9 @@
     },
 
     /**
-     * {@inheritdoc}
+     * @inheritdoc
+     *
+     * @return {Drupal.toolbar.ToolbarVisualView}
      */
     render: function () {
       this.updateTabs();
@@ -81,7 +90,7 @@
     /**
      * Responds to a toolbar tab click.
      *
-     * @param jQuery.Event event
+     * @param {jQuery.Event} event
      */
     onTabClick: function (event) {
       // If this tab has a tray associated with it, it is considered an
@@ -101,7 +110,7 @@
     /**
      * Toggles the orientation of a toolbar tray.
      *
-     * @param jQuery.Event event
+     * @param {jQuery.Event} event
      */
     onOrientationToggleClick: function (event) {
       var orientation = this.model.get('orientation');
