diff --git a/core/misc/active-link.js b/core/misc/active-link.js index 6054faa..09cb8e0 100644 --- a/core/misc/active-link.js +++ b/core/misc/active-link.js @@ -17,7 +17,9 @@ * (e.g. pagers, exposed View filters). * * Does not discriminate based on element type, so allows you to set the active - * class on any element: a, li… + * class on any element: a, li... + * + * @type {Behavior} */ Drupal.behaviors.activeLinks = { attach: function (context) { diff --git a/core/misc/ajax.js b/core/misc/ajax.js index 4abb652..280142a 100644 --- a/core/misc/ajax.js +++ b/core/misc/ajax.js @@ -1,28 +1,29 @@ -(function ($, window, Drupal, drupalSettings) { - -"use strict"; - /** - * Provides Ajax page updating via jQuery $.ajax (Asynchronous JavaScript and XML). + * @file + * Provides Ajax page updating via jQuery `$.ajax`. * * Ajax is a method of making a request via JavaScript while viewing an HTML * page. The request returns an array of commands encoded in JSON, which is * then executed to make any changes that are necessary to the page. * - * Drupal uses this file to enhance form elements with #ajax['path'] and - * #ajax['wrapper'] properties. If set, this file will automatically be included - * to provide Ajax capabilities. + * Drupal uses this file to enhance form elements with #ajax['path'] + * and #ajax['wrapper'] properties. If set, this file will automatically be + * included to provide Ajax capabilities. */ +(function ($, window, Drupal, drupalSettings) { + +"use strict"; Drupal.ajax = Drupal.ajax || {}; /** * Attaches the Ajax behavior to each Ajax form element. + * @type {Behavior} */ Drupal.behaviors.AJAX = { attach: function (context, settings) { - function loadAjaxBehavior(base) { + function loadAjaxBehavior (base) { var element_settings = settings.ajax[base]; if (typeof element_settings.selector === 'undefined') { element_settings.selector = '#' + base; @@ -81,6 +82,10 @@ Drupal.behaviors.AJAX = { /** * Extends Error to provide handling for Errors in AJAX + * @constructor + * @augments Error + * @param {xhr} xmlhttp + * @param {String} uri */ Drupal.AjaxError = function(xmlhttp, uri) { @@ -116,34 +121,47 @@ Drupal.AjaxError = function(xmlhttp, uri) { // We don't need readyState except for status == 0. readyStateText = xmlhttp.status === 0 ? ("\n" + Drupal.t("ReadyState: !readyState", {'!readyState': xmlhttp.readyState})) : ""; + /** + * Formated and translated error message. + * @type {string} + */ this.message = statusCode + pathText + statusText + responseText + readyStateText; + /** + * Set to `AjaxError`, used by some browser to display a more accurate + * stacktrace. + * @type {String} + */ this.name = 'AjaxError'; }; - Drupal.AjaxError.prototype = new Error(); Drupal.AjaxError.prototype.constructor = Drupal.AjaxError; /** - * Ajax object. - * - * All Ajax objects on a page are accessible through the global Drupal.ajax + * All Ajax objects on a page are accessible through the global `Drupal.ajax` * object and are keyed by the submit button's ID. You can access them from * your module's JavaScript file to override properties or functions. * * For example, if your Ajax enabled button has the ID 'edit-submit', you can * redefine the function that is called to insert the new content like this * (inside a Drupal.behaviors attach block): - * @code - * Drupal.behaviors.myCustomAJAXStuff = { - * attach: function (context, settings) { - * Drupal.ajax['edit-submit'].commands.insert = function (ajax, response, status) { - * new_content = $(response.data); - * $('#my-wrapper').append(new_content); - * alert('New content was appended to #my-wrapper'); - * } - * } - * }; - * @endcode + * + * @classdesc Ajax object. + * + * @example + * Drupal.behaviors.myCustomAJAXStuff = { + * attach: function (context, settings) { + * Drupal.ajax['edit-submit'].commands.insert = function (ajax, response, status) { + * new_content = $(response.data); + * $('#my-wrapper').append(new_content); + * alert('New content was appended to #my-wrapper'); + * } + * } + * }; + * + * @constructor + * @param {String} base + * @param {HTMLElement} element + * @param {Object} element_settings */ Drupal.ajax = function (base, element, element_settings) { var defaults = { @@ -164,28 +182,48 @@ Drupal.ajax = function (base, element, element_settings) { $.extend(this, defaults, element_settings); + /** + * @type {Drupal.AjaxCommands} + */ this.commands = new Drupal.AjaxCommands(); - // @todo Remove this after refactoring the PHP code to: - // - Call this 'selector'. - // - Include the '#' for ID-based selectors. - // - Support non-ID-based selectors. if (this.wrapper) { + /** + * @todo Remove this after refactoring the PHP code to: + * + * - Call this 'selector'. + * - Include the '#' for ID-based selectors. + * - Support non-ID-based selectors. + * + * @type {string} + */ this.wrapper = '#' + this.wrapper; } + /** + * @type {jQueryObject} + */ this.element = element; + /** + * @type {Object} + */ this.element_settings = element_settings; // If there isn't a form, jQuery.ajax() will be used instead, allowing us to // bind Ajax to links as well. if (this.element.form) { + /** + * @type {jQueryObject} + */ this.$form = $(this.element.form); } // If no Ajax callback URL was given, use the link href or form action. if (!this.url) { if ($(element).is('a')) { + /** + * @type {String} + */ this.url = $(element).attr('href'); } else if (element.form) { @@ -206,19 +244,38 @@ Drupal.ajax = function (base, element, element_settings) { } } - // Replacing 'nojs' with 'ajax' in the URL allows for an easy method to let - // the server detect when it needs to degrade gracefully. - // There are four scenarios to check for: - // 1. /nojs/ - // 2. /nojs$ - The end of a URL string. - // 3. /nojs? - Followed by a query (e.g. path/nojs?destination=foobar). - // 4. /nojs# - Followed by a fragment (e.g.: path/nojs#myfragment). + /** + * Replacing 'nojs' with 'ajax' in the URL allows for an easy method to let + * the server detect when it needs to degrade gracefully. + * There are four scenarios to check for: + * + * 1. `/nojs/` + * 2. `/nojs$` - The end of a URL string. + * 3. `/nojs?` - Followed by a query (e.g. `path/nojs?destination=foobar`). + * 4. `/nojs#` - Followed by a fragment (e.g.: `path/nojs#myfragment`). + * + * @type {String} + */ this.url = this.url.replace(/\/nojs(\/|$|\?|#)/g, '/ajax$1'); - // Set the options for the ajaxSubmit function. // The 'this' variable will not persist inside of the options object. var ajax = this; - ajax.options = { + /** + * Set the options for the ajaxSubmit function. + * @type {Object} + * @prop {String} url + * @prop {Object} data + * @prop {Function} beforeSerialize + * @prop {Function} beforeSubmit + * @prop {Function} beforeSend + * @prop {Function} success + * @prop {Function} complere + * @prop {String} dataType + * @prop {Object} accepts + * @prop {String} accepts.json + * @prop {String} type + */ + this.options = { url: ajax.url, data: ajax.submit, beforeSerialize: function (element_settings, options) { @@ -288,6 +345,8 @@ Drupal.ajax = function (base, element, element_settings) { * In this case we're handling RETURN and SPACEBAR keypresses (event codes 13 * and 32. RETURN is often used to submit a form when in a textfield, and * SPACE is often used to activate an element without submitting. + * @param {HTMLElement} element + * @param {Event} event */ Drupal.ajax.prototype.keypressResponse = function (element, event) { // Create a synonym for this to reduce code confusion. @@ -313,6 +372,8 @@ Drupal.ajax.prototype.keypressResponse = function (element, event) { * perform the actual Ajax call. It is bound to the event using * bind() in the constructor, and it uses the options specified on the * ajax object. + * @param {HTMLElement} element + * @param {Event} event */ Drupal.ajax.prototype.eventResponse = function (element, event) { event.preventDefault(); @@ -358,6 +419,8 @@ Drupal.ajax.prototype.eventResponse = function (element, event) { * * Runs before the beforeSend() handler (see below), and unlike that one, runs * before field data is collected. + * @param {HTMLElement} element + * @param {Object} options */ Drupal.ajax.prototype.beforeSerialize = function (element, options) { // Allow detaching behaviors to update field values before collecting them. @@ -402,6 +465,9 @@ Drupal.ajax.prototype.beforeSerialize = function (element, options) { /** * Modify form values prior to form submission. + * @param {Object} form_values + * @param {HTMLElement} element + * @param {Object} options */ Drupal.ajax.prototype.beforeSubmit = function (form_values, element, options) { // This function is left empty to make it simple to override for modules @@ -410,6 +476,8 @@ Drupal.ajax.prototype.beforeSubmit = function (form_values, element, options) { /** * Prepare the Ajax request before it is sent. + * @param {xhr} xmlhttprequest + * @param {Object} options */ Drupal.ajax.prototype.beforeSend = function (xmlhttprequest, options) { // For forms without file inputs, the jQuery Form plugin serializes the form @@ -470,6 +538,8 @@ Drupal.ajax.prototype.beforeSend = function (xmlhttprequest, options) { /** * Handler for the form redirection completion. + * @param {Object} response + * @param {String} status */ Drupal.ajax.prototype.success = function (response, status) { // Remove the progress element. @@ -503,6 +573,7 @@ Drupal.ajax.prototype.success = function (response, status) { /** * Build an effect object which tells us how to apply the effect when adding new HTML. + * @param {Object} response */ Drupal.ajax.prototype.getEffect = function (response) { var type = response.effect || this.effect; @@ -530,6 +601,8 @@ Drupal.ajax.prototype.getEffect = function (response) { /** * Handler for the form redirection error. + * @param {Object} response + * @param {String} uri */ Drupal.ajax.prototype.error = function (response, uri) { // Remove the progress element. @@ -553,6 +626,7 @@ Drupal.ajax.prototype.error = function (response, uri) { /** * Provide a series of commands that the server can request the client perform. + * @constructor */ Drupal.AjaxCommands = function () {}; Drupal.AjaxCommands.prototype = { @@ -719,6 +793,7 @@ Drupal.AjaxCommands.prototype = { * Uses the proprietary addImport method if available as browsers which * support that method ignore @import statements in dynamically added * stylesheets. + * @method */ add_css: function (ajax, response, status) { // Add the styles in the normal way. diff --git a/core/misc/announce.js b/core/misc/announce.js index dbefeb6..303a80d 100644 --- a/core/misc/announce.js +++ b/core/misc/announce.js @@ -1,18 +1,10 @@ /** + * @file * Adds an HTML element and method to trigger audio UAs to read system messages. * * Use Drupal.announce() to indicate to screen reader users that an element on * the page has changed state. For instance, if clicking a link loads 10 more * items into a list, one might announce the change like this. - * $('#search-list') - * .on('itemInsert', function (event, data) { - * // Insert the new items. - * $(data.container.el).append(data.items.el); - * // Announce the change to the page contents. - * Drupal.announce(Drupal.t('@count items added to @container', - * {'@count': data.items.length, '@container': data.container.title} - * )); - * }); */ (function (Drupal, debounce) { @@ -24,6 +16,7 @@ /** * Builds a div element with the aria-live attribute and attaches it * to the DOM. + * @type {Behavior} */ Drupal.behaviors.drupalAnnounce = { attach: function (context) { @@ -85,11 +78,22 @@ * These messages are then joined and append to the aria-live region as one * text node. * - * @param String text + * @example + * $('#search-list') + * .on('itemInsert', function (event, data) { + * // Insert the new items. + * $(data.container.el).append(data.items.el); + * // Announce the change to the page contents. + * Drupal.announce(Drupal.t('@count items added to @container', + * {'@count': data.items.length, '@container': data.container.title} + * )); + * }); + * @param {String} text * A string to be read by the UA. - * @param String priority + * @param {String} [priority] * A string to indicate the priority of the message. Can be either * 'polite' or 'assertive'. Polite is the default. + * @return {Function} * * @see http://www.w3.org/WAI/PF/aria-practices/#liveprops */ diff --git a/core/misc/autocomplete.js b/core/misc/autocomplete.js index 743e8d0..2ae9947 100644 --- a/core/misc/autocomplete.js +++ b/core/misc/autocomplete.js @@ -1,3 +1,8 @@ +/** + * @file + * + * Autocomplete using jQuery UI. + */ (function ($, Drupal) { "use strict"; @@ -156,6 +161,7 @@ function selectHandler (event, ui) { /** * Attaches the autocomplete behavior to all required fields. + * @type {Behavior} */ Drupal.behaviors.autocomplete = { attach: function (context) { diff --git a/core/misc/batch.js b/core/misc/batch.js index b3013e5..14c9059 100644 --- a/core/misc/batch.js +++ b/core/misc/batch.js @@ -1,9 +1,13 @@ +/** + * @file + */ (function ($, Drupal) { "use strict"; /** * Attaches the batch behavior to progress bars. + * @type {Behavior} */ Drupal.behaviors.batch = { attach: function (context, settings) { diff --git a/core/misc/collapse.js b/core/misc/collapse.js index 84a803d..348dad9 100644 --- a/core/misc/collapse.js +++ b/core/misc/collapse.js @@ -1,11 +1,20 @@ +/** + * @file + */ (function ($, Modernizr, Drupal) { "use strict"; /** - * The collapsible details object represents a single collapsible details element. + * The collapsible details object represents a single collapsible details + * element. + * @constructor + * @param {HTMLElement} node */ -function CollapsibleDetails (node) { +Drupal.CollapsibleDetails = function (node) { + /** + * @type {jQueryObject} + */ this.$node = $(node); this.$node.data('details', this); // Expand details if there are errors inside, or if it contains an @@ -18,22 +27,15 @@ function CollapsibleDetails (node) { this.setupSummary(); // Initialize and setup the legend. this.setupLegend(); -} +}; /** - * Extend CollapsibleDetails function. + * Holds references to instantiated CollapsibleDetails objects. + * @type {Array.} */ -$.extend(CollapsibleDetails, { - /** - * Holds references to instantiated CollapsibleDetails objects. - */ - instances: [] -}); +Drupal.CollapsibleDetails.instances = []; -/** - * Extend CollapsibleDetails prototype. - */ -$.extend(CollapsibleDetails.prototype, { +$.extend(Drupal.CollapsibleDetails.prototype, /** @lends Drupal.CollapsibleDetails# */ { /** * Initialize and setup summary events and markup. */ @@ -65,6 +67,7 @@ $.extend(CollapsibleDetails.prototype, { }, /** * Handle legend clicks + * @param {Event} e */ onLegendClick: function (e) { this.toggle(); @@ -93,6 +96,9 @@ $.extend(CollapsibleDetails.prototype, { } }); +/** + * @type {Behavior} + */ Drupal.behaviors.collapse = { attach: function (context) { if (Modernizr.details) { @@ -101,13 +107,10 @@ Drupal.behaviors.collapse = { var $collapsibleDetails = $(context).find('details').once('collapse'); if ($collapsibleDetails.length) { for (var i = 0; i < $collapsibleDetails.length; i++) { - CollapsibleDetails.instances.push(new CollapsibleDetails($collapsibleDetails[i])); + Drupal.CollapsibleDetails.instances.push(new Drupal.CollapsibleDetails($collapsibleDetails[i])); } } } }; -// Expose constructor in the public space. -Drupal.CollapsibleDetails = CollapsibleDetails; - })(jQuery, Modernizr, Drupal); diff --git a/core/misc/debounce.js b/core/misc/debounce.js index 9731257..11a97b2 100644 --- a/core/misc/debounce.js +++ b/core/misc/debounce.js @@ -1,6 +1,7 @@ /** - * Limits the invocations of a function in a given time frame. - * + * @file + */ +/** * Adapted from underscore.js with the addition Drupal namespace. * * The debounce function wrapper should be used sparingly. One clear use case @@ -11,13 +12,15 @@ * function can be written in such a way that it is only invoked under specific * conditions. * - * @param {Function} callback + * @summary Limits the invocations of a function in a given time frame. + * @param {Function} func * The function to be invoked. - * * @param {Number} wait * The time period within which the callback function should only be * invoked once. For example if the wait period is 250ms, then the callback * will only be called at most 4 times per second. + * @param {Boolean} [immediate=undefined] + * Run the callback at the beginning. */ Drupal.debounce = function (func, wait, immediate) { diff --git a/core/misc/dialog.ajax.js b/core/misc/dialog.ajax.js index d2d8d3a..9001b9b 100644 --- a/core/misc/dialog.ajax.js +++ b/core/misc/dialog.ajax.js @@ -7,6 +7,9 @@ "use strict"; + /** + * @type {Behavior} + */ Drupal.behaviors.dialog = { attach: function (context, settings) { var $context = $(context); @@ -36,9 +39,10 @@ /** * Scan a dialog for any primary buttons and move them to the button area. * - * @param $dialog + * @function + * @param {jQueryObject} $dialog * An jQuery object containing the element that is the dialog target. - * @return + * @return {Array} * An array of buttons that need to be added to the button area. */ prepareDialogButtons: function ($dialog) { @@ -71,6 +75,7 @@ /** * Command to open a dialog. + * @method */ Drupal.AjaxCommands.prototype.openDialog = function (ajax, response, status) { if (!response.selector) { @@ -121,6 +126,7 @@ * Command to close a dialog. * * If no selector is given, it defaults to trying to close the modal. + * @method */ Drupal.AjaxCommands.prototype.closeDialog = function (ajax, response, status) { var $dialog = $(response.selector); @@ -139,6 +145,7 @@ * Command to set a dialog property. * * jQuery UI specific way of setting dialog options. + * @method */ Drupal.AjaxCommands.prototype.setDialogOption = function (ajax, response, status) { var $dialog = $(response.selector); diff --git a/core/misc/dialog.js b/core/misc/dialog.js index 2bb3a32..d47a574 100644 --- a/core/misc/dialog.js +++ b/core/misc/dialog.js @@ -11,17 +11,26 @@ drupalSettings.dialog = { autoOpen: true, dialogClass: '', - // When using this API directly (when generating dialogs on the client side), - // you may want to override this method and do - // @code - // jQuery(event.target).remove() - // @endcode - // as well, to remove the dialog on closing. + /** + * When using this API directly (when generating dialogs on the client side), + * you may want to override this method and do + * as well, to remove the dialog on closing. + * @example + * jQuery(event.target).remove() + * @param {Event} event + */ close: function (event) { Drupal.detachBehaviors(event.target, null, 'unload'); } }; +/** + * Mock HTML5 dialog API + * + * @param {HTMLElement} element + * @param {Object} [options] + * @returns {Dialog} + */ Drupal.dialog = function (element, options) { function openDialog (settings) { diff --git a/core/misc/dialog.position.js b/core/misc/dialog.position.js index 7b12055..8a01e53 100644 --- a/core/misc/dialog.position.js +++ b/core/misc/dialog.position.js @@ -62,7 +62,7 @@ 'dialog:aftercreate': function (event, dialog, $element, settings) { var autoResize = debounce(resetSize, 20); var eventData = { settings: settings, $element: $element }; - if (settings.autoResize === true || settings.autoResize === 'true') { + if (settings.autoResize === true || settings.autoResize === 'true') { $element .dialog('option', { resizable: false, draggable: false }) .dialog('widget').css('position', 'fixed'); diff --git a/core/misc/displace.js b/core/misc/displace.js index c658694..8affe5c 100644 --- a/core/misc/displace.js +++ b/core/misc/displace.js @@ -1,19 +1,23 @@ /** + * @file * Manages elements that can offset the size of the viewport. */ + +/** + * @typedef OffsetObject + * @type {Object} + * @prop {Number} top + * @prop {Number} left + * @prop {Number} right + * @prop {Number} bottom + */ (function ($, Drupal, debounce) { "use strict"; - var offsets = { - top: 0, - right: 0, - bottom: 0, - left: 0 - }; - /** * Registers a resize handler on the window. + * @type {Behavior} */ Drupal.behaviors.drupalDisplace = { attach: function () { @@ -28,41 +32,46 @@ }; /** + * Event to listen to for reacting to layout changes of fixed elements on the + * page. + * @event drupalViewportOffsetChange + */ + + /** * Informs listeners of the current offset dimensions. * - * @param {boolean} broadcast - * (optional) When true or undefined, causes the recalculated offsets values to be + * @prop {OffsetObject} offsets + * @prop {Function} calculateOffset + * + * @function + * @fires drupalViewportOffsetChange + * @param {Boolean} [broadcast] + * When true or undefined, causes the recalculated offsets values to be * broadcast to listeners. * - * @return {object} + * @return {OffsetObject} * An object whose keys are the for sides an element -- top, right, bottom * and left. The value of each key is the viewport displacement distance for * that edge. */ - function displace (broadcast) { - offsets = Drupal.displace.offsets = calculateOffsets(); + Drupal.displace = function (broadcast) { + var offsets = calculateOffsets(); if (typeof broadcast === 'undefined' || broadcast) { $(document).trigger('drupalViewportOffsetChange', offsets); } + Drupal.displace.offsets = offsets; return offsets; - } + }; /** - * Determines the viewport offsets. - * - * @return {object} - * An object whose keys are the for sides an element -- top, right, bottom - * and left. The value of each key is the viewport displacement distance for - * that edge. + * @type {OffsetObject} */ - function calculateOffsets () { - return { - top: calculateOffset('top'), - right: calculateOffset('right'), - bottom: calculateOffset('bottom'), - left: calculateOffset('left') - }; - } + Drupal.displace.offsets = { + top: 0, + right: 0, + bottom: 0, + left: 0 + }; /** * Gets a specific edge's offset. @@ -72,14 +81,16 @@ * numeric value, that value will be used. If no value is provided, one will * be calculated using the element's dimensions and placement. * - * @param {string} edge + * @function + * @name Drupal.displace.calculateOffset + * @param {String} edge * The name of the edge to calculate. Can be 'top', 'right', * 'bottom' or 'left'. * - * @return {number} + * @return {Number} * The viewport displacement distance for the requested edge. */ - function calculateOffset (edge) { + Drupal.displace.calculateOffset = function (edge) { var edgeOffset = 0; var displacingElements = document.querySelectorAll('[data-offset-' + edge + ']'); for (var i = 0, n = displacingElements.length; i < n; i++) { @@ -102,19 +113,39 @@ } return edgeOffset; + }; + + /** + * Determines the viewport offsets. + * + * @private + * @function + * @return {OffsetObject} + * An object whose keys are the for sides an element -- top, right, bottom + * and left. The value of each key is the viewport displacement distance for + * that edge. + */ + function calculateOffsets () { + var calculateOffset = Drupal.displace.calculateOffset; + return { + top: calculateOffset('top'), + right: calculateOffset('right'), + bottom: calculateOffset('bottom'), + left: calculateOffset('left') + }; } /** * Calculates displacement for element based on its dimensions and placement. * - * @param {jQuery} $el + * @param {HTMLElement} el * The jQuery element whose dimensions and placement will be measured. * - * @param {string} edge + * @param {String} edge * The name of the edge of the viewport that the element is associated * with. * - * @return {number} + * @return {Number} * The viewport displacement distance for the requested edge. */ function getRawOffset (el, edge) { @@ -157,19 +188,4 @@ return displacement; } - /** - * Assign the displace function to a property of the Drupal global object. - */ - Drupal.displace = displace; - $.extend(Drupal.displace, { - /** - * Expose offsets to other scripts to avoid having to recalculate offsets - */ - offsets: offsets, - /** - * Expose method to compute a single edge offsets. - */ - calculateOffset: calculateOffset - }); - })(jQuery, Drupal, Drupal.debounce); diff --git a/core/misc/dropbutton/dropbutton.js b/core/misc/dropbutton/dropbutton.js index 516ecfc..1d1cea2 100644 --- a/core/misc/dropbutton/dropbutton.js +++ b/core/misc/dropbutton/dropbutton.js @@ -1,9 +1,13 @@ +/** + * @file + */ (function ($, Drupal) { "use strict"; /** * Process elements with the .dropbutton class on page load. + * @type {Behavior} */ Drupal.behaviors.dropButton = { attach: function (context, settings) { @@ -16,7 +20,7 @@ Drupal.behaviors.dropButton = { } // Initialize all buttons. for (var i = 0, il = $dropbuttons.length; i < il; i++) { - DropButton.dropbuttons.push(new DropButton($dropbuttons[i], settings.dropbutton)); + Drupal.DropButton.dropbuttons.push(new Drupal.DropButton($dropbuttons[i], settings.dropbutton)); } } } @@ -24,6 +28,7 @@ Drupal.behaviors.dropButton = { /** * Delegated callback for opening and closing dropbutton secondary actions. + * @param {Event} e */ function dropbuttonClickHandler (e) { e.preventDefault(); @@ -36,21 +41,29 @@ function dropbuttonClickHandler (e) { * All secondary actions beyond the first in the list are presented in a * dropdown list accessible through a toggle arrow associated with the button. * - * @param {jQuery} $dropbutton - * A jQuery element. - * + * @constructor + * @param {HTMLElement} dropbutton * @param {Object} settings - * A list of options including: - * - {String} title: The text inside the toggle link element. This text is - * hidden from visual UAs. + * @param {String} settings.title + * The text inside the toggle link element. This text is hidden from + * visual UAs. */ -function DropButton (dropbutton, settings) { +Drupal.DropButton = function (dropbutton, settings) { // Merge defaults with settings. var options = $.extend({'title': Drupal.t('List additional actions')}, settings); var $dropbutton = $(dropbutton); + /** + * @type {jQueryObject} + */ this.$dropbutton = $dropbutton; + /** + * @type {jQueryObject} + */ this.$list = $dropbutton.find('.dropbutton'); - // Find actions and mark them. + /** + * Find actions and mark them. + * @type {jQueryObject} + */ this.$actions = this.$list.find('li').addClass('dropbutton-action'); // Add the special dropdown only if there are hidden actions. @@ -81,30 +94,24 @@ function DropButton (dropbutton, settings) { 'focusin.dropbutton': $.proxy(this.focusIn, this) }); } -} +}; /** - * Extend the DropButton constructor. + * Store all processed DropButtons. + * + * @type {Array.} */ -$.extend(DropButton, { - /** - * Store all processed DropButtons. - * - * @type {Array} - */ - dropbuttons: [] -}); +Drupal.DropButton.dropbuttons = []; /** * Extend the DropButton prototype. */ -$.extend(DropButton.prototype, { +$.extend(Drupal.DropButton.prototype, /** @lends Drupal.DropButton# */{ /** * Toggle the dropbutton open and closed. * - * @param {Boolean} show - * (optional) Force the dropbutton to open by passing true or to close by - * passing false. + * @param {Boolean} [show] + * Forces dropbutton to open by passing true or to close by passing false. */ toggle: function (show) { var isBool = typeof show === 'boolean'; @@ -112,6 +119,9 @@ $.extend(DropButton.prototype, { this.$dropbutton.toggleClass('open', show); }, + /** + * @method + */ hoverIn: function () { // Clear any previous timer we were using. if (this.timerID) { @@ -119,46 +129,56 @@ $.extend(DropButton.prototype, { } }, + /** + * @method + */ hoverOut: function () { // Wait half a second before closing. this.timerID = window.setTimeout($.proxy(this, 'close'), 500); }, + /** + * @method + */ open: function () { this.toggle(true); }, + /** + * @method + */ close: function () { this.toggle(false); }, - focusOut: function(e) { + /** + * @param {Event} e + */ + focusOut: function (e) { this.hoverOut.call(this, e); }, + /** + * @param {Event} e + */ focusIn: function(e) { this.hoverIn.call(this, e); } }); -$.extend(Drupal.theme, { - /** - * A toggle is an interactive element often bound to a click handler. - * - * @param {Object} options - * - {String} title: (optional) The HTML anchor title attribute and - * text for the inner span element. - * - * @return {String} - * A string representing a DOM fragment. - */ - dropbuttonToggle: function (options) { - return '
  • '; - } -}); - -// Expose constructor in the public space. -Drupal.DropButton = DropButton; +/** + * A toggle is an interactive element often bound to a click handler. + * + * @param {Object} options + * @param {String} [options.title] + * The HTML anchor title attribute and text for the inner span element. + * + * @return {String} + * A string representing a DOM fragment. + */ +Drupal.theme.dropbuttonToggle = function (options) { + return '
  • '; +}; })(jQuery, Drupal); diff --git a/core/misc/drupal.js b/core/misc/drupal.js index e994ec6..cebdeea 100644 --- a/core/misc/drupal.js +++ b/core/misc/drupal.js @@ -1,3 +1,29 @@ +/** + * @file + * + * Defines the Drupal JS API. + */ + +/** + * A jQuery object. + * + * @typedef jQueryObject + */ + +/** + * Global variable generated by Drupal that holds all the configuration created + * from PHP. + * + * @global + * @var drupalSettings + */ + +/** + * Global Drupal object. + * + * @global + * @namespace + */ window.Drupal = { behaviors: {}, locale: {} }; // Class indicating that JS is enabled; used for styling purpose. @@ -17,9 +43,9 @@ if (window.jQuery) { /** * Custom error type thrown after attach/detach if one or more behaviors failed. * - * @param list + * @param {Array} list * An array of errors thrown during attach/detach. - * @param event + * @param {String} event * A string containing either 'attach' or 'detach'. */ function DrupalBehaviorError(list, event) { @@ -37,21 +63,44 @@ function DrupalBehaviorError(list, event) { DrupalBehaviorError.prototype = new Error(); /** + * @typedef BehaviorAttachCallback + * @type {Function} + * @param {HTMLElement} context + * @param {Object} settings + */ + +/** + * @typedef BehaviorDetachCallback + * @type {Function} + * @param {HTMLElement} context + * @param {Object} settings + * @param {String} trigger + * One of 'unload', 'serialize' or 'move'. + */ + +/** + * @typedef Behavior + * @type {Object} + * @property {BehaviorAttachCallback} attach + * Function run on page load and after an AJAX call. + * @property {BehaviorDetachCallback} detach + * Function run when content is serialized or removed from the page. + */ + + +/** + * Holds all initialization methods. + * + * @namespace Drupal.behaviors + * @type {Object.} + */ + +/** * Attach all registered behaviors to a page element. * * Behaviors are event-triggered actions that attach to page elements, enhancing * default non-JavaScript UIs. Behaviors are registered in the Drupal.behaviors * object using the method 'attach' and optionally also 'detach' as follows: - * @code - * Drupal.behaviors.behaviorName = { - * attach: function (context, settings) { - * ... - * }, - * detach: function (context, settings, trigger) { - * ... - * } - * }; - * @endcode * * Drupal.attachBehaviors is added below to the jQuery.ready event and therefore * runs on initial page load. Developers implementing Ajax in their solutions @@ -60,19 +109,28 @@ DrupalBehaviorError.prototype = new Error(); * the new content. * * Behaviors should use - * @code - * var elements = $(context).find(selector).once('behavior-name'); - * @endcode + * var elements = $(context).find(selector).once('behavior-name'); * to ensure the behavior is attached only once to a given element. (Doing so * enables the reprocessing of given elements, which may be needed on occasion * despite the ability to limit behavior attachment to a particular element.) * - * @param context + * @example + * Drupal.behaviors.behaviorName = { + * attach: function (context, settings) { + * ... + * }, + * detach: function (context, settings, trigger) { + * ... + * } + * }; + * + * @param {HTMLElement} context * An element to attach behaviors to. If none is given, the document element * is used. - * @param settings + * @param {Object} settings * An object containing settings for the current context. If none is given, * the global drupalSettings object is used. + * @see Drupal.detachBehaviors */ Drupal.attachBehaviors = function (context, settings) { context = context || document; @@ -112,15 +170,16 @@ domready(function () { Drupal.attachBehaviors(document, drupalSettings); }); * behaviorName-processed, to ensure the behavior is detached only from * previously processed elements. * - * @param context + * @param {HTMLElement} context * An element to detach behaviors from. If none is given, the document element * is used. - * @param settings + * @param {Object} settings * An object containing settings for the current context. If none given, the * global drupalSettings object is used. - * @param trigger + * @param {String} trigger * A string containing what's causing the behaviors to be detached. The * possible triggers are: + * * - unload: (default) The context element is being removed from the DOM. * - move: The element is about to be moved within the DOM (for example, * during a tabledrag row swap). After the move is completed, @@ -164,7 +223,8 @@ Drupal.detachBehaviors = function (context, settings, trigger) { /** * Helper to test document width for mobile configurations. - * @todo Temporary solution for the mobile initiative. + * + * @deprecated Temporary solution for the mobile initiative. */ Drupal.checkWidthBreakpoint = function (width) { width = width || drupalSettings.widthBreakpoint || 640; @@ -174,11 +234,10 @@ Drupal.checkWidthBreakpoint = function (width) { /** * Encode special characters in a plain-text string for display as HTML. * - * @param str + * @param {String} str * The string to be encoded. - * @return + * @return {String} * The encoded string. - * @ingroup sanitization */ Drupal.checkPlain = function (str) { str = str.toString() @@ -192,21 +251,22 @@ Drupal.checkPlain = function (str) { /** * Replace placeholders with sanitized values in a string. * - * @param str + * @param {String} str * A string with placeholders. - * @param args + * @param {Object} args * An object of replacements pairs to make. Incidences of any key in this * array are replaced with the corresponding value. Based on the first * character of the key, the value is escaped and/or themed: + * * - !variable: inserted as is * - @variable: escape plain text to HTML (Drupal.checkPlain) * - %variable: escape text and theme as a placeholder for user-submitted * content (checkPlain + Drupal.theme('placeholder')) * - * @see Drupal.t() - * @ingroup sanitization + * @return {String} + * @see Drupal.t */ -Drupal.formatString = function(str, args) { +Drupal.formatString = function (str, args) { // Transform arguments before inserting them. for (var key in args) { if (args.hasOwnProperty(key)) { @@ -234,18 +294,18 @@ Drupal.formatString = function(str, args) { * * See the documentation of the server-side t() function for further details. * - * @param str + * @param {String} str * A string containing the English string to translate. - * @param args + * @param {Object.<*>} args * An object of replacements pairs to make after translation. Incidences * of any key in this array are replaced with the corresponding value. - * See Drupal.formatString(). + * See {@link Drupal.formatString}. * - * @param options - * - 'context' (defaults to the empty context): The context the source string - * belongs to. + * @param {Object} options + * @param {String} [options.context=''] + * The context the source string belongs to. * - * @return + * @return {String} * The translated string. */ Drupal.t = function (str, args, options) { @@ -265,6 +325,10 @@ Drupal.t = function (str, args, options) { /** * Returns the URL to a Drupal page. + * + * @param {String} path + * Drupal path to transform to URL. + * @return {String} */ Drupal.url = function (path) { return drupalSettings.path.basePath + drupalSettings.path.scriptPath + path; @@ -278,25 +342,25 @@ Drupal.url = function (path) { * * See the documentation of the server-side format_plural() function for further details. * - * @param count + * @param {Number} count * The item count to display. - * @param singular + * @param {String} singular * The string for the singular case. Please make sure it is clear this is * singular, to ease translation (e.g. use "1 new comment" instead of "1 new"). * Do not use @count in the singular string. - * @param plural + * @param {String} plural * The string for the plural case. Please make sure it is clear this is plural, * to ease translation. Use @count in place of the item count, as in "@count * new comments". - * @param args + * @param {Object} [args] * An object of replacements pairs to make after translation. Incidences * of any key in this array are replaced with the corresponding value. * See Drupal.formatString(). * Note that you do not need to include @count in this array. * This replacement is done automatically for the plural case. - * @param options + * @param {Object} [options] * The options to pass to the Drupal.t() function. - * @return + * @return {String} * A translated string. */ Drupal.formatPlural = function (count, singular, plural, args, options) { @@ -322,6 +386,10 @@ Drupal.formatPlural = function (count, singular, plural, args, options) { * Encodes a Drupal path for use in a URL. * * For aesthetic reasons slashes are not escaped. + * + * @param {String} item + * Unencoded path. + * @return {String} */ Drupal.encodePath = function (item) { return window.encodeURIComponent(item).replace(/%2F/g, '/'); @@ -337,13 +405,14 @@ Drupal.encodePath = function (item) { * * For example, to retrieve the HTML for text that should be emphasized and * displayed as a placeholder inside a sentence, call - * Drupal.theme('placeholder', text). + * `Drupal.theme('placeholder', text)`. * - * @param func + * @namespace + * @param {Function} func * The name of the theme function to call. - * @param ... + * @param {...*} [.] * Additional arguments to pass along to the theme function. - * @return + * @return {*} * Any data the theme function returns. This could be a plain HTML string, * but also a complex object. */ @@ -357,9 +426,9 @@ Drupal.theme = function (func) { /** * Formats text for emphasized display in a placeholder inside a sentence. * - * @param str + * @param {String} str * The text to format (plain-text). - * @return + * @return {String} * The formatted text (html). */ Drupal.theme.placeholder = function (str) { diff --git a/core/misc/form.js b/core/misc/form.js index 9bb9379..7d751b8 100644 --- a/core/misc/form.js +++ b/core/misc/form.js @@ -2,6 +2,14 @@ "use strict"; + +/** + * Event to listen to for reacting to layout changes of fixed elements on the + * page. + * @event summaryUpdated + */ + + /** * Retrieves the summary for the first element. */ @@ -13,9 +21,10 @@ $.fn.drupalGetSummary = function () { /** * Sets the summary for all matched elements. * - * @param callback + * @param {Function} callback * Either a function that will be called each time the summary is * retrieved or a string (which is returned each time). + * @fires summaryUpdated */ $.fn.drupalSetSummary = function (callback) { var self = this; @@ -42,6 +51,8 @@ $.fn.drupalSetSummary = function (callback) { /** * Sends a 'formUpdated' event each time a form element is modified. + * + * @type {Behavior} */ Drupal.behaviors.formUpdated = { attach: function (context) { @@ -96,6 +107,8 @@ Drupal.behaviors.formUpdated = { * * Lastly, all forms submitted via HTTP GET are idempotent by definition of HTTP * standards, so excluded in this implementation. + * + * @type {Behavior} */ Drupal.behaviors.formSingleSubmit = { attach: function () { @@ -118,7 +131,13 @@ Drupal.behaviors.formSingleSubmit = { /** + * When the value of a form input is changed this event is fired. + * @event formUpdated + */ + +/** * Sends a 'formUpdated' event each time a form element is modified. + * @fires formUpdated */ function triggerFormUpdated (element) { $(element).trigger('formUpdated'); @@ -192,6 +211,8 @@ Drupal.behaviors.formUpdated = { /** * Prepopulate form fields with information from the visitor cookie. + * + * @type {Behavior} */ Drupal.behaviors.fillUserInfoFromCookie = { attach: function (context, settings) { diff --git a/core/misc/machine-name.js b/core/misc/machine-name.js index f399e20..aa41f58 100644 --- a/core/misc/machine-name.js +++ b/core/misc/machine-name.js @@ -4,15 +4,17 @@ /** * Attach the machine-readable name form element behavior. + * @type {Behavior} */ Drupal.behaviors.machineName = { /** * Attaches the behavior. * - * @param settings.machineName + * @param {String} settings.machineName * A list of elements to process, keyed by the HTML ID of the form element * containing the human-readable value. Each element is an object defining * the following properties: + * * - target: The HTML ID of the machine name form element. * - suffix: The HTML ID of a container to show the machine name preview in * (usually a field suffix after the human-readable name form element). @@ -144,15 +146,19 @@ Drupal.behaviors.machineName = { /** * Transliterate a human-readable name to a machine name. * - * @param source + * @function Drupal.behaviors.machineName.transliterate + * @monkeypatch + * @param {String} source * A string to transliterate. - * @param settings - * The machine name settings for the corresponding field, containing: - * - replace_pattern: A regular expression (without modifiers) matching - * disallowed characters in the machine name; e.g., '[^a-z0-9]+'. - * - replace: A character to replace disallowed characters with; e.g., '_' - * or '-'. - * - maxlength: The maximum length of the machine name. + * @param {Object} settings + * The machine name settings for the corresponding field. + * @param {RegEx} settings.replace_pattern + * A regular expression (without modifiers) matching + * disallowed characters in the machine name; e.g., '[^a-z0-9]+'. + * @param {String} settings.replace + * A character to replace disallowed characters with; e.g., '_' or '-'. + * @param {Number} settings.maxlength + * The maximum length of the machine name. * * @return * The transliterated source string. diff --git a/core/misc/matchmedia.js b/core/misc/matchmedia.js index a26723a..854884e 100644 --- a/core/misc/matchmedia.js +++ b/core/misc/matchmedia.js @@ -1,17 +1,28 @@ /** + * @file * Polyfill the behavior of window.matchMedia. * - * @see http://dev.w3.org/csswg/cssom-view/#widl-Window-matchMedia-MediaQueryList-DOMString-query + * {@link http://dev.w3.org/csswg/cssom-view/#widl-Window-matchMedia-MediaQueryList-DOMString-query} * * Test whether a CSS media type or media query applies. Register listeners * to MediaQueryList objects. * - * Adapted from https://github.com/paulirish/matchMedia.js with the addition - * of addListener and removeListener. The polyfill referenced above uses - * polling to trigger registered listeners on matchMedia tests. + * Adapted from {@link https://github.com/paulirish/matchMedia.js} with the + * addition of addListener and removeListener. The polyfill referenced above + * uses polling to trigger registered listeners on matchMedia tests. * This polyfill triggers tests on window resize and orientationchange. */ +/** + * matchMedia polyfill. + * + * @global + * @function + * @param {HTMLElement} doc + * @param {window} window + * @param {Object} Drupal + * @return {Function} + */ window.matchMedia = window.matchMedia || (function (doc, window, Drupal) { "use strict"; @@ -63,7 +74,7 @@ window.matchMedia = window.matchMedia || (function (doc, window, Drupal) { * @param {Function} callback * The callback to be invoked when the media query is applicable. * - * @return {Object MediaQueryList} + * @return {MediaQueryList} * A MediaQueryList object that indicates whether the registered media * query applies. The matches property is true when the media query * applies and false when not. The original media query is referenced in diff --git a/core/misc/progress.js b/core/misc/progress.js index e3e000f..a5521e5 100644 --- a/core/misc/progress.js +++ b/core/misc/progress.js @@ -1,3 +1,8 @@ +/** + * @file + * + * Progress bar element. + */ (function ($) { "use strict"; @@ -9,17 +14,47 @@ * method is the function which will perform the HTTP request to get the * progress bar state. Either "GET" or "POST". * - * e.g. pb = new Drupal.ProgressBar('myProgressBar'); - * some_element.appendChild(pb.element); + * @example + * var progressWrapper = document.querySelector('#progress-wrapper'); + * var progressElement = new Drupal.ProgressBar('myProgressBar'); + * progressWrapper.appendChild(progressElement.element); + * + * @constructor + * @param {String} id + * @param {Function} updateCallback + * @param {String} method + * @param {Function} errorCallback + * @return {Drupal.ProgressBar} */ Drupal.ProgressBar = function (id, updateCallback, method, errorCallback) { + /** + * @var + * @type {String} + */ this.id = id; + /** + * @var + * @type {String} + */ this.method = method || 'GET'; + /** + * @function + */ this.updateCallback = updateCallback; + /** + * @function + * @param {Number} percentage + * @param {String} message + * @param {Drupal.ProgressBar} this + */ this.errorCallback = errorCallback; // The WAI-ARIA setting aria-live="polite" will announce changes after users // have completed their current activity and not interrupt the screen reader. + /** + * @var + * @type {jQueryObject} + */ this.element = $('
    ').attr('id', id); this.element.html('
     
    ' + '
    ' + @@ -27,9 +62,14 @@ Drupal.ProgressBar = function (id, updateCallback, method, errorCallback) { '
     
    '); }; -$.extend(Drupal.ProgressBar.prototype, { +$.extend(Drupal.ProgressBar.prototype, /** @lends Drupal.ProgressBar.prototype */ { /** * Set the percentage and status message for the progressbar. + * @name Drupal.ProgressBar#setProgress + * @function + * @param {Number} percentage + * @param {String} message + * @param {String} label */ setProgress: function (percentage, message, label) { if (percentage >= 0 && percentage <= 100) { @@ -45,6 +85,8 @@ $.extend(Drupal.ProgressBar.prototype, { /** * Start monitoring progress via Ajax. + * @function + * @memberof Drupal.ProgressBar# */ startMonitoring: function (uri, delay) { this.delay = delay; @@ -54,6 +96,7 @@ $.extend(Drupal.ProgressBar.prototype, { /** * Stop monitoring progress via Ajax. + * @function */ stopMonitoring: function () { clearTimeout(this.timer); @@ -63,6 +106,7 @@ $.extend(Drupal.ProgressBar.prototype, { /** * Request progress data from server. + * @function */ sendPing: function () { if (this.timer) { @@ -98,6 +142,7 @@ $.extend(Drupal.ProgressBar.prototype, { /** * Display errors on the page. + * @function */ displayError: function (string) { var error = $('
    ').html(string); diff --git a/core/misc/states.js b/core/misc/states.js index 206d521..a17ad43 100644 --- a/core/misc/states.js +++ b/core/misc/states.js @@ -7,18 +7,24 @@ * * Having the local states variable allows us to use the States namespace * without having to always declare "Drupal.states". + * @namespace */ -var states = Drupal.states = { - // An array of functions that should be postponed. +Drupal.states = { + /** + * An array of functions that should be postponed. + * @type {Array.} + */ postponed: [] }; /** * Attaches the states. + * @type {Behavior} */ Drupal.behaviors.states = { attach: function (context, settings) { var $states = $(context).find('[data-drupal-states]'); + var states = Drupal.states; var config, state; for (var i = 0, il = $states.length; i < il; i += 1) { config = JSON.parse($states[i].getAttribute('data-drupal-states')); @@ -43,17 +49,29 @@ Drupal.behaviors.states = { /** * Object representing an element that depends on other elements. * - * @param args - * Object with the following keys (all of which are required): - * - element: A jQuery object of the dependent element - * - state: A State object describing the state that is dependent - * - constraints: An object with dependency specifications. Lists all elements - * that this element depends on. It can be nested and can contain arbitrary - * AND and OR clauses. + * @constructor + * @param {Object} args + * @param {jQueryObject} element + * A jQuery object of the dependent element + * @param {Drupal.states.State} state + * A State object describing the state that is dependent + * @param {Object} constraints + * An object with dependency specifications. Lists all elements + * that this element depends on. It can be nested and can contain arbitrary + * AND and OR clauses. */ -states.Dependent = function (args) { +Drupal.states.Dependent = function (args) { $.extend(this, { values: {}, oldValue: null }, args); + /** + * Cache for the states of this dependee. + * @member Drupal.states.Dependent#values + * @type {Object} + */ + + /** + * @type {Object.} + */ this.dependees = this.getDependees(); for (var selector in this.dependees) { if (this.dependees.hasOwnProperty(selector)) { @@ -67,7 +85,7 @@ states.Dependent = function (args) { * specification from the dependency settings. If the object type can't be * found in this list, the === operator is used by default. */ -states.Dependent.comparisons = { +Drupal.states.Dependent.comparisons = { 'RegExp': function (reference, value) { return reference.test(value); }, @@ -84,13 +102,13 @@ states.Dependent.comparisons = { } }; -states.Dependent.prototype = { +Drupal.states.Dependent.prototype = { /** * Initializes one of the elements this dependent depends on. * - * @param selector + * @param {String} selector * The CSS selector describing the dependee. - * @param dependeeStates + * @param {Object.} dependeeStates * The list of states that have to be monitored for tracking the * dependee's compliance status. */ @@ -101,7 +119,6 @@ states.Dependent.prototype = { self.update(e.data.selector, e.data.state, e.value); } - // Cache for the states of this dependee. this.values[selector] = {}; for (var i in dependeeStates) { @@ -112,7 +129,7 @@ states.Dependent.prototype = { continue; } - state = states.State.sanitize(state); + state = Drupal.states.State.sanitize(state); // Initialize the value of this state. this.values[selector][state.name] = null; @@ -121,7 +138,7 @@ states.Dependent.prototype = { $(selector).on('state:' + state, {selector: selector, state: state}, stateEventHandler); // Make sure the event we just bound ourselves to is actually fired. - new states.Trigger({ selector: selector, state: state }); + new Drupal.states.Trigger({ selector: selector, state: state }); } } }, @@ -129,21 +146,20 @@ states.Dependent.prototype = { /** * Compares a value with a reference value. * - * @param reference + * @param {Object} reference * The value used for reference. - * @param selector + * @param {String} selector * CSS selector describing the dependee. - * @param state + * @param {String} state * A State object describing the dependee's updated state. * - * @return - * true or false. + * @return {Boolean} */ compare: function (reference, selector, state) { var value = this.values[selector][state.name]; - if (reference.constructor.name in states.Dependent.comparisons) { + if (reference.constructor.name in Drupal.states.Dependent.comparisons) { // Use a custom compare function for certain reference value types. - return states.Dependent.comparisons[reference.constructor.name](reference, value); + return Drupal.states.Dependent.comparisons[reference.constructor.name](reference, value); } else { // Do a plain comparison otherwise. @@ -178,8 +194,11 @@ states.Dependent.prototype = { // Only invoke a state change event when the value actually changed. if (value !== this.oldValue) { - // Store the new value so that we can compare later whether the value - // actually changed. + /** + * Store the new value so that we can compare later whether the value + * actually changed. + * @type {String} + */ this.oldValue = value; // Normalize the value to match the normalized state name. @@ -241,14 +260,14 @@ states.Dependent.prototype = { /** * Checks whether the value matches the requirements for this constraint. * - * @param value + * @param {String} value * Either the value of a state or an array/object of constraints. In the * latter case, resolving the constraint continues. - * @param selector + * @param {String} selector * The selector for this constraint. If undefined, there isn't yet a * selector that this constraint applies to. In that case, the state key is * propagates to a selector and resolving continues. - * @param state + * @param {?String} state * The state to check for this constraint. If undefined, resolving * continues. * If both selector and state aren't undefined and valid non-numeric @@ -256,8 +275,7 @@ states.Dependent.prototype = { * performed. This parameter is not a State object but a pristine state * string. * - * @return - * true or false, depending on whether this constraint is satisfied. + * @return {Boolean} */ checkConstraints: function(value, selector, state) { // Normalize the last parameter. If it's non-numeric, we treat it either as @@ -273,7 +291,7 @@ states.Dependent.prototype = { if (state !== null) { // constraints is the actual constraints of an element to check for. - state = states.State.sanitize(state); + state = Drupal.states.State.sanitize(state); return invert(this.compare(value, selector, state), state.invert); } else { @@ -284,6 +302,7 @@ states.Dependent.prototype = { /** * Gathers information about all required triggers. + * @return {Object} */ getDependees: function() { var cache = {}; @@ -310,10 +329,17 @@ states.Dependent.prototype = { } }; -states.Trigger = function (args) { +/** + * @param {Object} args + * @constructor + */ +Drupal.states.Trigger = function (args) { $.extend(this, args); - if (this.state in states.Trigger.states) { + if (this.state in Drupal.states.Trigger.states) { + /** + * @type {jQueryObject} + */ this.element = $(this.selector); // Only call the trigger initializer when it wasn't yet attached to this @@ -324,9 +350,12 @@ states.Trigger = function (args) { } }; -states.Trigger.prototype = { +Drupal.states.Trigger.prototype = { + /** + * @method + */ initialize: function () { - var trigger = states.Trigger.states[this.state]; + var trigger = Drupal.states.Trigger.states[this.state]; if (typeof trigger === 'function') { // We have a custom trigger initialization function. @@ -344,6 +373,10 @@ states.Trigger.prototype = { this.element.data('trigger:' + this.state, true); }, + /** + * @param event + * @param valueFn + */ defaultTrigger: function (event, valueFn) { var oldValue = valueFn.call(this.element); @@ -357,7 +390,7 @@ states.Trigger.prototype = { } }, this)); - states.postponed.push($.proxy(function () { + Drupal.states.postponed.push($.proxy(function () { // Trigger the event once for initialization purposes. this.element.trigger({ type: 'state:' + this.state, value: oldValue, oldValue: null }); }, this)); @@ -369,9 +402,14 @@ states.Trigger.prototype = { * of an element. Whenever an element depends on the state of another element, * one of these trigger functions is added to the dependee so that the * dependent element can be updated. + * + * @namespace */ -states.Trigger.states = { - // 'empty' describes the state to be monitored +Drupal.states.Trigger.states = { + /** + * 'empty' describes the state to be monitored. + * @type {Object} + */ empty: { // 'keyup' is the (native DOM) event that we watch for. 'keyup': function () { @@ -380,7 +418,9 @@ states.Trigger.states = { return this.val() === ''; } }, - + /** + * @type {Object} + */ checked: { 'change': function () { // prop() and attr() only takes the first element into account. To support @@ -398,7 +438,10 @@ states.Trigger.states = { } }, - // For radio buttons, only return the value if the radio button is selected. + /** + * For radio buttons, only return the value if the radio button is selected. + * @type {Object} + */ value: { 'keyup': function () { // Radio buttons share the same :input[name="key"] selector. @@ -418,6 +461,9 @@ states.Trigger.states = { } }, + /** + * @type {Object} + */ collapsed: { 'collapsed': function(e) { return (typeof e !== 'undefined' && 'value' in e) ? e.value : !this.is('[open]'); @@ -428,9 +474,19 @@ states.Trigger.states = { /** * A state object is used for describing the state and performing aliasing. + * + * @constructor + * @param {String} state */ -states.State = function(state) { - // We may need the original unresolved name later. +Drupal.states.State = function (state) { + /** + * We may need the original unresolved name later. + * @member {String} Drupal.states.State#pristine + */ + /** + * @member {String} Drupal.states.State#name + */ + this.pristine = this.name = state; // Normalize the state name. @@ -442,8 +498,8 @@ states.State = function(state) { } // Replace the state with its normalized name. - if (this.name in states.State.aliases) { - this.name = states.State.aliases[this.name]; + if (this.name in Drupal.states.State.aliases) { + this.name = Drupal.states.State.aliases[this.name]; } else { break; @@ -453,21 +509,23 @@ states.State = function(state) { /** * Creates a new State object by sanitizing the passed value. + * @param {String} state */ -states.State.sanitize = function (state) { - if (state instanceof states.State) { +Drupal.states.State.sanitize = function (state) { + if (state instanceof Drupal.states.State) { return state; } else { - return new states.State(state); + return new Drupal.states.State(state); } }; /** * This list of aliases is used to normalize states and associates negated names * with their respective inverse state. + * @type {Object} */ -states.State.aliases = { +Drupal.states.State.aliases = { 'enabled': '!disabled', 'invisible': '!visible', 'invalid': '!valid', @@ -482,11 +540,15 @@ states.State.aliases = { 'readwrite': '!readonly' }; -states.State.prototype = { +Drupal.states.State.prototype = { + /** + * @type {Boolean} + */ invert: false, /** * Ensures that just using the state object returns the name. + * @return {String} */ toString: function() { return this.name; @@ -499,7 +561,6 @@ states.State.prototype = { * bubble up to these handlers. We use this system so that themes and modules * can override these state change handlers for particular parts of a page. */ - $(document).on('state:disabled', function (e) { // Only act when this change was triggered by a dependency and not by the // element monitoring itself. diff --git a/core/misc/tabbingmanager.js b/core/misc/tabbingmanager.js index 0507120..d2aeef8 100644 --- a/core/misc/tabbingmanager.js +++ b/core/misc/tabbingmanager.js @@ -9,31 +9,38 @@ /** * Provides an API for managing page tabbing order modifications. + * + * @constructor */ function TabbingManager () { - // Tabbing sets are stored as a stack. The active set is at the top of the - // stack. We use a JavaScript array as if it were a stack; we consider the - // first element to be the bottom and the last element to be the top. This - // allows us to use JavaScript's built-in Array.push() and Array.pop() - // methods. + /** + * Tabbing sets are stored as a stack. The active set is at the top of the + * stack. We use a JavaScript array as if it were a stack; we consider the + * first element to be the bottom and the last element to be the top. This + * allows us to use JavaScript's built-in Array.push() and Array.pop() + * methods. + * + * @type {Array.} + */ this.stack = []; } /** * Add public methods to the TabbingManager class. */ -$.extend(TabbingManager.prototype, { +$.extend(TabbingManager.prototype, /** @lends TabbingManager# */ { /** * Constrain tabbing to the specified set of elements only. * * Makes elements outside of the specified set of elements unreachable via the * tab key. * - * @param jQuery elements + * @method TabbingManager.prototype.constrain + * @param {jQueryObject} elements * The set of elements to which tabbing should be constrained. Can also be * a jQuery-compatible selector string. * - * @return TabbingContext + * @return {TabbingContext} */ constrain: function (elements) { // Deactivate all tabbingContexts to prepare for the new constraint. A @@ -97,7 +104,7 @@ $.extend(TabbingManager.prototype, { * stored so that they might be restored later when this tabbingContext * is deactivated. * - * @param TabbingContext tabbingContext + * @param {TabbingContext} tabbingContext * The TabbingContext instance that has been activated. */ activate: function (tabbingContext) { @@ -136,7 +143,7 @@ $.extend(TabbingManager.prototype, { * Elements that were made untabble have their original tabindex and autfocus * values restored. * - * @param TabbingContext tabbingContext + * @param {TabbingContext} tabbingContext * The TabbingContext instance that has been deactivated. */ deactivate: function (tabbingContext) { @@ -150,9 +157,9 @@ $.extend(TabbingManager.prototype, { /** * Records the tabindex and autofocus values of an untabbable element. * - * @param jQuery $set + * @param {jQueryObject} $set * The set of elements that have been disabled. - * @param Number level + * @param {Number} level * The stack level for which the tabindex attribute should be recorded. */ recordTabindex: function ($el, level) { @@ -167,9 +174,9 @@ $.extend(TabbingManager.prototype, { /** * Restores the tabindex and autofocus values of a reactivated element. * - * @param jQuery $el + * @param {jQueryObject} $el * The element that is being reactivated. - * @param Number level + * @param {Number} level * The stack level for which the tabindex attribute should be restored. */ restoreTabindex: function ($el, level) { @@ -211,8 +218,10 @@ $.extend(TabbingManager.prototype, { * * This constraint can be removed with the release() method. * - * @param Object options + * @constructor + * @param {Object} options * A set of initiating values that include: + * * - Number level: The level in the TabbingManager's stack of this * tabbingContext. * - jQuery $tabbableElements: The DOM elements that should be reachable via @@ -238,7 +247,7 @@ function TabbingContext (options) { /** * Add public methods to the TabbingContext class. */ -$.extend(TabbingContext.prototype, { +$.extend(TabbingContext.prototype, /** @lends TabbinbContext# */ { /** * Releases this TabbingContext. * @@ -286,6 +295,11 @@ $.extend(TabbingContext.prototype, { if (Drupal.tabbingManager) { return; } +/** + * Provides an API for managing page tabbing order modifications. + * + * @type {TabbingManager} + */ Drupal.tabbingManager = new TabbingManager(); diff --git a/core/misc/tabledrag.js b/core/misc/tabledrag.js index 68be8f6..b3289b1 100644 --- a/core/misc/tabledrag.js +++ b/core/misc/tabledrag.js @@ -18,6 +18,8 @@ var showWeight = JSON.parse(localStorage.getItem('Drupal.tableDrag.showWeight')) * Created tableDrag instances may be modified with custom behaviors by * overriding the .onDrag, .onDrop, .row.onSwap, and .row.onIndent methods. * See blocks.js for an example of adding additional functionality to tableDrag. + * + * @type {Behavior} */ Drupal.behaviors.tableDrag = { attach: function (context, settings) { @@ -40,36 +42,81 @@ Drupal.behaviors.tableDrag = { /** * Constructor for the tableDrag object. Provides table and field manipulation. * - * @param table + * @constructor + * @param {HTMLElement} table * DOM object for the table to be made draggable. - * @param tableSettings + * @param {Object} tableSettings * Settings for the table added via drupal_add_dragtable(). */ Drupal.tableDrag = function (table, tableSettings) { var self = this; var $table = $(table); - // Required object variables. + /** + * @type {jQueryObject} + */ this.$table = $(table); + /** + * @type {HTMLElement} + */ this.table = table; + /** + * @type {Object} + */ this.tableSettings = tableSettings; + /** + * @type {?HTMLElement} + */ this.dragObject = null; // Used to hold information about a current drag operation. + /** + * @type {?HTMLElement} + */ this.rowObject = null; // Provides operations for row manipulation. + /** + * @type {?HTMLElement} + */ this.oldRowElement = null; // Remember the previous element. + /** + * @type {Number} + */ this.oldY = 0; // Used to determine up or down direction from last mouse move. + /** + * @type {Boolean} + */ this.changed = false; // Whether anything in the entire table has changed. + /** + * @type {Number} + */ this.maxDepth = 0; // Maximum amount of allowed parenting. + /** + * @type {Number} + */ this.rtl = $(this.table).css('direction') === 'rtl' ? -1 : 1; // Direction of the table. // Configure the scroll settings. + /** + * @type {{amount: Number, interval: Number, trigger: Number}} + */ this.scrollSettings = { amount: 4, interval: 50, trigger: 70 }; + /** + * @type {?Number} + */ this.scrollInterval = null; + /** + * @type {Number} + */ this.scrollY = 0; + /** + * @type {Number} + */ this.windowHeight = 0; - // Check this table's settings to see if there are parent relationships in - // this table. For efficiency, large sections of code can be skipped if we - // don't need to track horizontal movement and indentations. + /** + * Check this table's settings to see if there are parent relationships in + * this table. For efficiency, large sections of code can be skipped if we + * don't need to track horizontal movement and indentations. + * @type {Boolean} + */ this.indentEnabled = false; for (var group in tableSettings) { if (tableSettings.hasOwnProperty(group)) { @@ -86,7 +133,11 @@ Drupal.tableDrag = function (table, tableSettings) { } } if (this.indentEnabled) { - this.indentCount = 1; // Total width of indents, set in makeDraggable. + /** + * Total width of indents, set in makeDraggable. + * @type {number} + */ + this.indentCount = 1; // Find the width of indentations to measure mouse movements against. // Because the table doesn't need to start with any indentations, we // manually append 2 indentations in the first draggable row, measure @@ -95,6 +146,9 @@ Drupal.tableDrag = function (table, tableSettings) { var testRow = $('').addClass('draggable').appendTo(table); var testCell = $('').appendTo(testRow).prepend(indent).prepend(indent); var $indentation = testCell.find('.indentation'); + /** + * @type {number} + */ this.indentAmount = $indentation.get(1).offsetLeft - $indentation.get(0).offsetLeft; testRow.remove(); } @@ -211,7 +265,7 @@ Drupal.tableDrag.prototype.addColspanClass = function(columnIndex) { /** * Hide or display weight columns. Triggers an event on change. * - * @param bool displayWeight + * @param {bool} displayWeight * 'true' will show weight columns. */ Drupal.tableDrag.prototype.displayColumns = function (displayWeight) { @@ -486,11 +540,11 @@ Drupal.tableDrag.prototype.makeDraggable = function (item) { /** * Pointer event initiator, creates drag object and information. * - * @param jQuery.Event event + * @param {Event} event * The event object that trigger the drag. - * @param Drupal.tableDrag self + * @param {Drupal.tableDrag} self * The drag handle. - * @param DOM item + * @param {DOM} item * The item that that is being dragged. */ Drupal.tableDrag.prototype.dragStart = function (event, self, item) { diff --git a/core/misc/tableheader.js b/core/misc/tableheader.js index 2519304..f861274 100644 --- a/core/misc/tableheader.js +++ b/core/misc/tableheader.js @@ -4,6 +4,8 @@ /** * Attaches sticky table headers. + * + * @type {Behavior} */ Drupal.behaviors.tableHeader = { attach: function (context) { @@ -11,6 +13,10 @@ Drupal.behaviors.tableHeader = { } }; +/** + * @param {String} position + * @returns {Number} + */ function scrollValue(position) { return document.documentElement[position] || document.body[position]; } @@ -75,7 +81,8 @@ $(document).on({ * TableHeader will make the current table header stick to the top of the page * if the table is very long. * - * @param table + * @name Drupal.TableHeader + * @param {HTMLElement} table * DOM object for the table to add a sticky header to. * * @constructor @@ -112,7 +119,8 @@ $.extend(TableHeader, { /** * This will store the state of all processed tables. * - * @type {Array} + * @name Drupal.TableHeader.tables + * @type {Array.} */ tables: [] }); @@ -120,7 +128,7 @@ $.extend(TableHeader, { /** * Extend TableHeader prototype. */ -$.extend(TableHeader.prototype, { +$.extend(TableHeader.prototype, /** @lends Drupal.TableHeader.prototype */ { /** * Minimum height in pixels for the table to have a sticky header. */ @@ -166,8 +174,9 @@ $.extend(TableHeader.prototype, { /** * Set absolute position of sticky. * - * @param offsetTop - * @param offsetLeft + * @param {Number} offsetTop + * @param {Number} offsetLeft + * @return {jQueryObject} */ stickyPosition: function (offsetTop, offsetLeft) { var css = {}; @@ -182,6 +191,8 @@ $.extend(TableHeader.prototype, { /** * Returns true if sticky is currently visible. + * + * @return {Boolean} */ checkStickyVisible: function () { var scrollTop = scrollValue('scrollTop'); @@ -202,7 +213,7 @@ $.extend(TableHeader.prototype, { * * This function is throttled to once every 250ms to avoid unnecessary calls. * - * @param event + * @param {Event} e */ onScroll: function (e) { this.checkStickyVisible(); @@ -213,8 +224,7 @@ $.extend(TableHeader.prototype, { /** * Event handler: recalculates position of the sticky table header. - * - * @param event + * @param {Event} event * Event being triggered. */ recalculateSticky: function (event) { diff --git a/core/misc/tableresponsive.js b/core/misc/tableresponsive.js index 4f45dee..687a947 100644 --- a/core/misc/tableresponsive.js +++ b/core/misc/tableresponsive.js @@ -4,13 +4,14 @@ /** * Attach the tableResponsive function to Drupal.behaviors. + * @type {Behavior} */ Drupal.behaviors.tableResponsive = { attach: function (context, settings) { var $tables = $(context).find('table.responsive-enabled').once('tableresponsive'); if ($tables.length) { for (var i = 0, il = $tables.length; i < il; i++) { - TableResponsive.tables.push(new TableResponsive($tables[i])); + Drupal.TableResponsive.tables.push(new Drupal.TableResponsive($tables[i])); } } } @@ -19,22 +20,47 @@ Drupal.behaviors.tableResponsive = { /** * The TableResponsive object optimizes table presentation for all screen sizes. * + * @classdesc * A responsive table hides columns at small screen sizes, leaving the most * important columns visible to the end user. Users should not be prevented from * accessing all columns, however. This class adds a toggle to a table with * hidden columns that exposes the columns. Exposing the columns will likely * break layouts, but it provides the user with a means to access data, which * is a guiding principle of responsive design. + * + * @constructor + * @fires resize.tableresponsive + * @param {HTMLElement} table */ -function TableResponsive (table) { +Drupal.TableResponsive = function (table) { + /** + * @type {HTMLElement} + */ this.table = table; + /** + * + * @type {jQueryObject} + */ this.$table = $(table); + /** + * @type {String} + */ this.showText = Drupal.t('Show all columns'); + /** + * @type {String} + */ this.hideText = Drupal.t('Hide unimportant columns'); - // Store a reference to the header elements of the table so that the DOM is - // traversed only once to find them. + /** + * Store a reference to the header elements of the table so that the DOM is + * traversed only once to find them. + * + * @type {jQueryObject} + */ this.$headers = this.$table.find('th'); - // Add a link before the table for users to show or hide weight columns. + /** + * Add a link before the table for users to show or hide weight columns. + * @type {jQueryObject} + */ this.$link = $('') .attr('title', Drupal.t('Show table cells that were hidden to make the table fit within a small screen.')) .on('click', $.proxy(this, 'eventhandlerToggleColumns')); @@ -45,14 +71,13 @@ function TableResponsive (table) { $(window) .on('resize.tableresponsive', $.proxy(this, 'eventhandlerEvaluateColumnVisibility')) .trigger('resize.tableresponsive'); -} +}; /** * Extend the TableResponsive function with a list of managed tables. + * @type {Array.} */ -$.extend(TableResponsive, { - tables: [] -}); +Drupal.TableResponsive.tables = []; /** * Associates an action link with the table that will show hidden columns. @@ -60,7 +85,10 @@ $.extend(TableResponsive, { * Columns are assumed to be hidden if their header has the class priority-low * or priority-medium. */ -$.extend(TableResponsive.prototype, { +$.extend(Drupal.TableResponsive.prototype, /** @lends Drupal.TableResponsive# */ { + /** + * @param {Event} e + */ eventhandlerEvaluateColumnVisibility: function (e) { var pegged = parseInt(this.$link.data('pegged'), 10); var hiddenLength = this.$headers.filter('.priority-medium:hidden, .priority-low:hidden').length; @@ -76,8 +104,13 @@ $.extend(TableResponsive.prototype, { this.$link.hide().text(this.hideText); } }, - // Toggle the visibility of columns classed with either 'priority-low' or - // 'priority-medium'. + /** + * Toggle the visibility of columns classed with either 'priority-low' or + * 'priority-medium'. + * + * @fires resize.tableresponsive + * @param {Event} e + */ eventhandlerToggleColumns: function (e) { e.preventDefault(); var self = this; @@ -133,7 +166,5 @@ $.extend(TableResponsive.prototype, { } } }); -// Make the TableResponsive object available in the Drupal namespace. -Drupal.TableResponsive = TableResponsive; })(jQuery, Drupal, window); diff --git a/core/misc/timezone.js b/core/misc/timezone.js index 01f1820..c1bf630 100644 --- a/core/misc/timezone.js +++ b/core/misc/timezone.js @@ -4,6 +4,7 @@ /** * Set the client's system time zone as default values of form fields. + * @type {Behavior} */ Drupal.behaviors.setTimezone = { attach: function (context, settings) { diff --git a/core/misc/vertical-tabs.js b/core/misc/vertical-tabs.js index d45bcac..62594d1 100644 --- a/core/misc/vertical-tabs.js +++ b/core/misc/vertical-tabs.js @@ -12,6 +12,8 @@ * 'verticalTabCallback' (with jQuery.data() attached to the details), * which is called every time the user performs an update to a form * element inside the tab pane. + * + * @type {Behavior} */ Drupal.behaviors.verticalTabs = { attach: function (context) { @@ -79,13 +81,30 @@ Drupal.behaviors.verticalTabs = { /** * The vertical tab object represents a single tab within a tab group. * - * @param settings - * An object with the following keys: - * - title: The name of the tab. - * - details: The jQuery object of the details element that is the tab pane. + * @constructor + * @param {Object} settings + * @param {String} settings.title + * The name of the tab. + * @param {jQueryObject} details + * The jQuery object of the details element that is the tab pane. */ Drupal.verticalTab = function (settings) { var self = this; + /** + * @member {String} Drupal.verticalTab#title + */ + /** + * @member {jQueryObject} Drupal.verticalTab#details + */ + /** + * @member {jQueryObject} Drupal.verticalTab#item + */ + /** + * @member {jQueryObject} Drupal.verticalTab#link + */ + /** + * @member {jQueryObject} Drupal.verticalTab#summary + */ $.extend(this, settings, Drupal.theme('verticalTab', settings)); this.link.attr('href', '#' + settings.details.attr('id')); @@ -191,14 +210,14 @@ Drupal.verticalTab.prototype = { /** * Theme function for a vertical tab. * - * @param settings - * An object with the following keys: - * - title: The name of the tab. - * @return + * @param {Object} settings + * @param {String} settings.title The name of the tab. + * @return {Object} * This function has to return an object with at least these keys: + * * - item: The root tab jQuery element * - link: The anchor tag that acts as the clickable area of the tab - * (jQuery version) + * (jQuery version) * - summary: The jQuery element that contains the tab summary */ Drupal.theme.verticalTab = function (settings) { diff --git a/core/modules/block/block.js b/core/modules/block/block.js index 4ddcf4a..18bda0e 100644 --- a/core/modules/block/block.js +++ b/core/modules/block/block.js @@ -1,9 +1,13 @@ +/** + * @file + */ (function ($, window) { "use strict"; /** * Provide the summary information for the block settings vertical tabs. + * @type {Behavior} */ Drupal.behaviors.blockSettingsSummary = { attach: function () { @@ -45,6 +49,7 @@ Drupal.behaviors.blockSettingsSummary = { * * This behavior is dependent on the tableDrag behavior, since it uses the * objects initialized in that behavior to update the row. + * @type {Behavior} */ Drupal.behaviors.blockDrag = { attach: function (context, settings) { diff --git a/core/modules/block/custom_block/custom_block.js b/core/modules/block/custom_block/custom_block.js index fb0905a..6ca51a5 100644 --- a/core/modules/block/custom_block/custom_block.js +++ b/core/modules/block/custom_block/custom_block.js @@ -2,11 +2,13 @@ * @file * Defines Javascript behaviors for the custom_block module. */ - (function ($) { "use strict"; +/** + * @type {Behavior} + */ Drupal.behaviors.customBlockDetailsSummaries = { attach: function (context) { var $context = $(context); diff --git a/core/modules/block/js/block.admin.js b/core/modules/block/js/block.admin.js index 5c657d4..064e6ec 100644 --- a/core/modules/block/js/block.admin.js +++ b/core/modules/block/js/block.admin.js @@ -1,3 +1,6 @@ +/** + * @file + */ (function ($, Drupal) { "use strict"; @@ -8,6 +11,7 @@ * Text search input: input.block-filter-text * Target element: input.block-filter-text[data-element] * Source text: .block-filter-text-source + * @type {Behavior} */ Drupal.behaviors.blockFilterByText = { attach: function (context, settings) { @@ -70,6 +74,7 @@ Drupal.behaviors.blockFilterByText = { /** * Highlights the block that was just placed into the block listing. + * @type {Behavior} */ Drupal.behaviors.blockHighlightPlacement = { attach: function (context, settings) { diff --git a/core/modules/book/book.js b/core/modules/book/book.js index f2d36ad..d84cc2c 100644 --- a/core/modules/book/book.js +++ b/core/modules/book/book.js @@ -2,11 +2,13 @@ * @file * Javascript behaviors for the Book module. */ - (function ($) { "use strict"; +/** + * @type {Behavior} + */ Drupal.behaviors.bookDetailsSummaries = { attach: function (context) { $(context).find('.book-outline-form').drupalSetSummary(function (context) { diff --git a/core/modules/ckeditor/js/ckeditor.admin.js b/core/modules/ckeditor/js/ckeditor.admin.js index 0e8f5b1..48c2b5b 100644 --- a/core/modules/ckeditor/js/ckeditor.admin.js +++ b/core/modules/ckeditor/js/ckeditor.admin.js @@ -8,6 +8,9 @@ Drupal.ckeditor = Drupal.ckeditor || {}; +/** + * @type {Behavior} + */ Drupal.behaviors.ckeditorAdmin = { attach: function (context) { // Process the CKEditor configuration fragment once. @@ -69,6 +72,7 @@ Drupal.behaviors.ckeditorAdmin = { /** * CKEditor configuration UI methods of Backbone objects. + * @namespace */ Drupal.ckeditor = { @@ -199,10 +203,10 @@ Drupal.ckeditor = { * 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. */ diff --git a/core/modules/ckeditor/js/ckeditor.drupalimage.admin.js b/core/modules/ckeditor/js/ckeditor.drupalimage.admin.js index 91ead76..a15a54f 100644 --- a/core/modules/ckeditor/js/ckeditor.drupalimage.admin.js +++ b/core/modules/ckeditor/js/ckeditor.drupalimage.admin.js @@ -1,9 +1,13 @@ +/** + * @file + */ (function ($, Drupal, drupalSettings) { "use strict"; /** * Provides the summary for the "drupalimage" plugin settings vertical tab. + * @type {Behavior} */ Drupal.behaviors.ckeditorDrupalImageSettingsSummary = { attach: function () { diff --git a/core/modules/ckeditor/js/ckeditor.js b/core/modules/ckeditor/js/ckeditor.js index d6baf17..a0a4634 100644 --- a/core/modules/ckeditor/js/ckeditor.js +++ b/core/modules/ckeditor/js/ckeditor.js @@ -2,6 +2,9 @@ "use strict"; +/** + * @type {Behavior} + */ Drupal.editors.ckeditor = { attach: function (element, format) { @@ -179,6 +182,9 @@ Drupal.editors.ckeditor = { }; +/** + * @namespace + */ Drupal.ckeditor = { /** * Variable storing the current dialog's save callback. @@ -191,16 +197,16 @@ Drupal.ckeditor = { * 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 c10b046..adf978f 100644 --- a/core/modules/ckeditor/js/ckeditor.stylescombo.admin.js +++ b/core/modules/ckeditor/js/ckeditor.stylescombo.admin.js @@ -1,3 +1,6 @@ +/** + * @file + */ (function ($, Drupal, drupalSettings) { "use strict"; @@ -9,6 +12,7 @@ * 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 {Behavior} */ Drupal.behaviors.ckeditorStylesComboSettings = { attach: function (context) { @@ -39,16 +43,16 @@ Drupal.behaviors.ckeditorStylesComboSettings = { /** * Builds the "stylesSet" configuration part of the CKEditor JS settings. * - * @see \Drupal\ckeditor\Plugin\ckeditor\plugin\StylesCombo::generateStylesSetSetting() + * see \Drupal\ckeditor\Plugin\ckeditor\plugin\StylesCombo::generateStylesSetSetting() * * Note that this is a more forgiving implementation than the PHP version: the * parsing works identically, but instead of failing on invalid styles, we * just ignore those. * - * @param String sstyles + * @param {String} sstyles * The "styles" setting. * - * @return array + * @return {array} * An array containing the "stylesSet" configuration. */ _generateStylesSetSetting: function (styles) { @@ -92,6 +96,7 @@ Drupal.behaviors.ckeditorStylesComboSettings = { /** * Provides the summary for the "stylescombo" plugin settings vertical tab. + * @type {Behavior} */ Drupal.behaviors.ckeditorStylesComboSettingsSummary = { attach: function () { diff --git a/core/modules/color/color.js b/core/modules/color/color.js index 704fc1c..9b5dc7b 100644 --- a/core/modules/color/color.js +++ b/core/modules/color/color.js @@ -2,11 +2,13 @@ * @file * Attaches the behaviors for the Color module. */ - (function ($) { "use strict"; +/** + * @type {Behavior} + */ Drupal.behaviors.color = { attach: function (context, settings) { var i, j, colors; diff --git a/core/modules/color/preview.js b/core/modules/color/preview.js index b15a7b6..6331a24 100644 --- a/core/modules/color/preview.js +++ b/core/modules/color/preview.js @@ -2,12 +2,23 @@ * @file * Attaches preview-related behavior for the Color module. */ - (function ($) { "use strict"; + /** + * @namespace + */ Drupal.color = { + /** + * + * @param {jQueryObject} context + * @param {Object} settings + * @param {jQueryObject} form + * @param {Object} farb + * @param {Array.} height + * @param {Array.} width + */ callback: function(context, settings, form, farb, height, width) { // Solid background. form.find('#preview').css('backgroundColor', form.find('#palette input[name="palette[base]"]').val()); diff --git a/core/modules/comment/comment-entity-form.js b/core/modules/comment/comment-entity-form.js index e068ef5..211ee9c 100644 --- a/core/modules/comment/comment-entity-form.js +++ b/core/modules/comment/comment-entity-form.js @@ -7,6 +7,9 @@ "use strict"; +/** + * @type {Behavior} + */ Drupal.behaviors.commentFieldsetSummaries = { attach: function (context) { var $context = $(context); diff --git a/core/modules/comment/js/comment-by-viewer.js b/core/modules/comment/js/comment-by-viewer.js index 06d5b82..dabc1ab 100644 --- a/core/modules/comment/js/comment-by-viewer.js +++ b/core/modules/comment/js/comment-by-viewer.js @@ -1,4 +1,5 @@ /** + * @file * Attaches behaviors for the Comment module's "by-viewer" class. */ (function ($, Drupal, drupalSettings) { @@ -7,6 +8,7 @@ /** * Add 'by-viewer' class to comments written by the current user. + * @type {Behavior} */ Drupal.behaviors.commentByViewer = { attach: function (context) { diff --git a/core/modules/comment/js/comment-new-indicator.js b/core/modules/comment/js/comment-new-indicator.js index 9b47dd9..9a9dc8e 100644 --- a/core/modules/comment/js/comment-new-indicator.js +++ b/core/modules/comment/js/comment-new-indicator.js @@ -1,14 +1,16 @@ /** + * @file * Attaches behaviors for the Comment module's "new" indicator. * * May only be loaded for authenticated users, with the History module enabled. */ -(function ($, Drupal, window) { +(function ($, Drupal) { "use strict"; /** * Render "new" comment indicators wherever necessary. + * @type {Behavior} */ Drupal.behaviors.commentNewIndicator = { attach: function (context) { @@ -79,4 +81,4 @@ function processCommentNewIndicators($placeholders) { }); } -})(jQuery, Drupal, window); +})(jQuery, Drupal); diff --git a/core/modules/comment/js/node-new-comments-link.js b/core/modules/comment/js/node-new-comments-link.js index 443b4fe..6977c2a 100644 --- a/core/modules/comment/js/node-new-comments-link.js +++ b/core/modules/comment/js/node-new-comments-link.js @@ -1,4 +1,5 @@ /** + * @file * Attaches behaviors for the Comment module's "X new comments" link. * * May only be loaded for authenticated users, with the History module enabled. @@ -9,6 +10,7 @@ /** * Render "X new comments" links wherever necessary. + * @type {Behavior} */ Drupal.behaviors.nodeNewCommentsLink = { attach: function (context) { diff --git a/core/modules/content_translation/content_translation.admin.js b/core/modules/content_translation/content_translation.admin.js index 42ec2bd..10aae57 100644 --- a/core/modules/content_translation/content_translation.admin.js +++ b/core/modules/content_translation/content_translation.admin.js @@ -1,9 +1,13 @@ +/** + * @file + */ (function ($, Drupal, drupalSettings) { "use strict"; /** * Forces applicable options to be checked as translatable. + * @type {Behavior} */ Drupal.behaviors.contentTranslationDependentOptions = { attach: function (context) { @@ -32,6 +36,12 @@ Drupal.behaviors.contentTranslationDependentOptions = { } } }, + /** + * @todo Move out of behavior object + * @param $fields + * @param dependent_columns + * @param $changed + */ check: function ($fields, dependent_columns, $changed) { var $element = $changed; var column; @@ -65,6 +75,7 @@ Drupal.behaviors.contentTranslationDependentOptions = { /** * Makes field translatability inherit bundle translatability. + * @type {Behavior} */ Drupal.behaviors.contentTranslation = { attach: function (context) { diff --git a/core/modules/contextual/js/contextual.js b/core/modules/contextual/js/contextual.js index 92ecbd7..919b336 100644 --- a/core/modules/contextual/js/contextual.js +++ b/core/modules/contextual/js/contextual.js @@ -35,10 +35,10 @@ if (cachedPermissionsHash !== permissionsHash) { /** * Initializes a contextual link: updates its DOM, sets up model and views * - * @param jQuery $contextual + * @param {jQueryObject} $contextual * A contextual links placeholder DOM element, containing the actual * contextual links as rendered by the server. - * @param string html + * @param {string} html * The server-side rendered HTML for this contextual link. */ function initContextual ($contextual, html) { @@ -97,7 +97,7 @@ function initContextual ($contextual, html) { * * This only deals with two levels of nesting; deeper levels are not touched. * - * @param jQuery $contextual + * @param {jQueryObject} $contextual * A contextual links placeholder DOM element, containing the actual * contextual links as rendered by the server. */ @@ -137,7 +137,10 @@ function adjustIfNestedAndOverlapping ($contextual) { * * Events * Contextual triggers an event that can be used by other scripts. + * * - drupalContextualLinkAdded: Triggered when a contextual link is added. + * + * @type {Behavior} */ Drupal.behaviors.contextual = { attach: function (context) { @@ -199,23 +202,36 @@ Drupal.behaviors.contextual = { } }; +/** + * Model and View definitions. + * @namespace + */ Drupal.contextual = { - // The Drupal.contextual.View instances associated with each list element of - // contextual links. + /** + * The Drupal.contextual.View instances associated with each list element of + * contextual links. + * @type {Array} + */ views: [], - // The Drupal.contextual.RegionView instances associated with each contextual - // region element. + /** + * The Drupal.contextual.RegionView instances associated with each contextual + * region element. + * @type {Array.} + */ regionViews: [] }; -// A Backbone.Collection of Drupal.contextual.StateModel instances. +/** + * A Backbone.Collection of Drupal.contextual.Model instances. + * @type {Backbone.Collection.} + */ Drupal.contextual.collection = new Backbone.Collection([], { model: Drupal.contextual.StateModel }); /** * A trigger is an interactive element often bound to a click handler. * - * @return String + * @return {String} * A string representing a DOM fragment. */ Drupal.theme.contextualTrigger = function () { diff --git a/core/modules/contextual/js/contextual.toolbar.js b/core/modules/contextual/js/contextual.toolbar.js index 0c6a8b8..6bd4154 100644 --- a/core/modules/contextual/js/contextual.toolbar.js +++ b/core/modules/contextual/js/contextual.toolbar.js @@ -16,7 +16,7 @@ var strings = { /** * Initializes a contextual link: updates its DOM, sets up model and views * - * @param DOM links + * @param {HTMLElement} context * A contextual links DOM element as rendered by the server. */ function initContextualToolbar (context) { @@ -31,7 +31,7 @@ function initContextualToolbar (context) { // @see Drupal.contextualToolbar.VisualView.persist() isViewing: localStorage.getItem('Drupal.contextualToolbar.isViewing') !== 'false' }, { - contextualCollection: Drupal.contextual.collection, + contextualCollection: Drupal.contextual.collection }); var viewOptions = { @@ -45,6 +45,7 @@ function initContextualToolbar (context) { /** * Attaches contextual's edit toolbar tab behavior. + * @type {Behavior} */ Drupal.behaviors.contextualToolbar = { attach: function (context) { @@ -56,15 +57,24 @@ Drupal.behaviors.contextualToolbar = { /** * Model and View definitions. + * @namespace */ Drupal.contextualToolbar = { - // The Drupal.contextualToolbar.Model instance. + /** + * The Drupal.contextualToolbar.Model instance. + * @type {Drupal.contextualToolbar.Model} + */ model: null, /** * Models the state of the edit mode toggle. + * @name Drupal.contextualToolbar.Model + * @constructor */ - Model: Backbone.Model.extend({ + Model: Backbone.Model.extend(/** @lends Drupal.contextualToolbar.Model# */{ + /** + * @type {Object} + */ defaults: { // Indicates whether the toggle is currently in "view" or "edit" mode. isViewing: true, @@ -79,14 +89,11 @@ Drupal.contextualToolbar = { }, /** - * {@inheritdoc} - * - * @param Object attrs - * @param Object options - * An object with the following option: - * - Backbone.collection contextualCollection: the collection of - * Drupal.contextual.Model models that represent the contextual links - * on the page. + * @param {Object} attrs + * @param {Object} options + * @param {Backbone.collection.} options.contextualCollection + * collection of Drupal.contextual.Model models that represent the + * contextual links on the page. */ initialize: function (attrs, options) { // Respond to new/removed contextual links. @@ -110,9 +117,9 @@ Drupal.contextualToolbar = { /** * Tracks the number of contextual link models in the collection. * - * @param Drupal.contextual.Model affectedModel + * @param {Drupal.contextual.Model} affectedModel * The contextual links model that was added or removed. - * @param Backbone.Collection contextualCollection + * @param {Backbone.Collection} contextualCollection * The collection of contextual link models. */ countCountextualLinks: function (contextualModel, contextualCollection) { @@ -122,9 +129,9 @@ Drupal.contextualToolbar = { /** * Lock newly added contextual links if edit mode is enabled. * - * @param Drupal.contextual.Model addedContextualModel + * @param {Drupal.contextual.Model} addedContextualModel * The contextual links model that was added. - * @param Backbone.Collection contextualCollection + * @param {Backbone.Collection} contextualCollection * The collection of contextual link models. */ lockNewContextualLinks: function (contextualModel, contextualCollection) { @@ -135,18 +142,17 @@ Drupal.contextualToolbar = { /** * Automatically updates visibility of the view/edit mode toggle. + * @method */ updateVisibility: function () { this.set('isVisible', this.get('contextualCount') > 0); } }), - /** - * Renders the visual view of the edit mode toggle. Listens to mouse & touch. - * - * Handles edit mode toggle interactions. - */ - VisualView: Backbone.View.extend({ + VisualView: Backbone.View.extend(/** @lends Drupal.contextualToolbar.VisualView# */ { + /** + * @return {Object} + */ events: function () { // Prevents delay and simulated mouse events. var touchEndToClick = function (event) { @@ -163,7 +169,12 @@ Drupal.contextualToolbar = { }, /** - * {@inheritdoc} + * Renders the visual view of the edit mode toggle. Listens to mouse & touch. + * + * Handles edit mode toggle interactions. + * + * @constructs Drupal.contextualToolbar.VisualView + * @augments Backbone.View */ initialize: function () { this.listenTo(this.model, 'change', this.render); @@ -171,7 +182,7 @@ Drupal.contextualToolbar = { }, /** - * {@inheritdoc} + * @method */ render: function () { // Render the visibility. @@ -188,9 +199,9 @@ Drupal.contextualToolbar = { * isViewing === true is the default, so only stores in localStorage when * it's not the default value (i.e. false). * - * @param Drupal.contextualToolbar.Model model + * @param {Drupal.contextualToolbar.Model} model * A Drupal.contextualToolbar.Model model. - * @param bool isViewing + * @param {Boolean} isViewing * The value of the isViewing attribute in the model. */ persist: function (model, isViewing) { @@ -203,15 +214,17 @@ Drupal.contextualToolbar = { } }), - /** - * Renders the aural view of the edit mode toggle (i.e.screen reader support). - */ - AuralView: Backbone.View.extend({ - // Tracks whether the tabbing constraint announcement has been read once yet. + AuralView: Backbone.View.extend(/** @lends Drupal.contextualToolbar.AuralView# */ { + /** + * Tracks whether the tabbing constraint announcement has been read once yet. + * @type {Boolean} + */ announcedOnce: false, /* - * {@inheritdoc} + * Renders the aural view of the edit mode toggle (i.e.screen reader support). + * @constructs Drupal.contextualToolbar.AuralView + * @augments Backbone.View */ initialize: function (options) { this.options = options; @@ -223,7 +236,7 @@ Drupal.contextualToolbar = { }, /** - * {@inheritdoc} + * @method */ render: function () { // Render the state. @@ -235,9 +248,9 @@ Drupal.contextualToolbar = { /** * Limits tabbing to the contextual links and edit mode toolbar tab. * - * @param Drupal.contextualToolbar.Model model + * @param {Drupal.contextualToolbar.Model} model * A Drupal.contextualToolbar.Model model. - * @param bool isViewing + * @param {Boolean} isViewing * The value of the isViewing attribute in the model. */ manageTabbing: function () { @@ -270,7 +283,7 @@ Drupal.contextualToolbar = { /** * Responds to esc and tab key press events. * - * @param jQuery.Event event + * @param {Event} event */ onKeypress: function (event) { // The first tab key press is tracked so that an annoucement about tabbing diff --git a/core/modules/contextual/js/models/StateModel.js b/core/modules/contextual/js/models/StateModel.js index dc633f2..ad36025 100644 --- a/core/modules/contextual/js/models/StateModel.js +++ b/core/modules/contextual/js/models/StateModel.js @@ -9,20 +9,55 @@ /** * Models the state of a contextual link's trigger, list & region. + * + * @constructor + * @augments Bacbbone.Model */ -Drupal.contextual.StateModel = Backbone.Model.extend({ - +Drupal.contextual.StateModel = Backbone.Model.extend(/** @lends Drupal.contextual.StateModel# */{ + /** + * @type {Object} + */ defaults: { - // The title of the entity to which these contextual links apply. + /** + * The title of the entity to which these contextual links apply. + * + * @name Drupal.contextual.StateModel#title + * @type {String} + * @virtual + */ title: '', - // Represents if the contextual region is being hovered. + /** + * Represents if the contextual region is being hovered. + * + * @name Drupal.contextual.StateModel#regionIsHovered + * @type {Boolean} + * @virtual + */ regionIsHovered: false, - // Represents if the contextual trigger or options have focus. + /** + * Represents if the contextual trigger or options have focus. + * + * @name Drupal.contextual.StateModel#hasFocus + * @type {Boolean} + * @virtual + */ hasFocus: false, - // Represents if the contextual options for an entity are available to - // be selected (i.e. whether the list of options is visible). + /** + * Represents if the contextual options for an entity are available to + * be selected (i.e. whether the list of options is visible). + * + * @name Drupal.contextual.StateModel#isOpen + * @type {Boolean} + * @virtual + */ isOpen: false, - // When the model is locked, the trigger remains active. + /** + * When the model is locked, the trigger remains active. + * + * @name Drupal.contextual.StateModel#isLocked + * @type {Boolean} + * @virtual + */ isLocked: false }, diff --git a/core/modules/contextual/js/views/AuralView.js b/core/modules/contextual/js/views/AuralView.js index 9ce04c1..5697b27 100644 --- a/core/modules/contextual/js/views/AuralView.js +++ b/core/modules/contextual/js/views/AuralView.js @@ -2,18 +2,17 @@ * @file * A Backbone View that provides the aural view of a contextual link. */ - (function (Drupal, Backbone) { "use strict"; -/** - * Renders the aural view of a contextual link (i.e. screen reader support). - */ -Drupal.contextual.AuralView = Backbone.View.extend({ - +Drupal.contextual.AuralView = Backbone.View.extend(/** @lends Drupal.contextual.AuralView# */ { /** - * {@inheritdoc} + * Renders the aural view of a contextual link (i.e. screen reader support). + * + * @constructs Drupal.contextual.AuralView + * @augments Backbone.View + * @param {Object} options */ initialize: function (options) { this.options = options; @@ -28,7 +27,7 @@ Drupal.contextual.AuralView = Backbone.View.extend({ }, /** - * {@inheritdoc} + * @method */ render: function () { var isOpen = this.model.get('isOpen'); diff --git a/core/modules/contextual/js/views/KeyboardView.js b/core/modules/contextual/js/views/KeyboardView.js index ec55523..5f01c1c 100644 --- a/core/modules/contextual/js/views/KeyboardView.js +++ b/core/modules/contextual/js/views/KeyboardView.js @@ -2,15 +2,14 @@ * @file * A Backbone View that provides keyboard interaction for a contextual link. */ - (function (Drupal, Backbone) { "use strict"; -/** - * Provides keyboard interaction for a contextual link. - */ -Drupal.contextual.KeyboardView = Backbone.View.extend({ +Drupal.contextual.KeyboardView = Backbone.View.extend(/** @lends Drupal.contextual.KeyboardView# */ { + /** + * @type {Object} + */ events: { 'focus .trigger': 'focus', 'focus .contextual-links a': 'focus', @@ -26,7 +25,10 @@ Drupal.contextual.KeyboardView = Backbone.View.extend({ }, /** - * {@inheritdoc} + * Provides keyboard interaction for a contextual link. + * + * @constructs Drupal.contextual.KeyboardView + * @augments Backbone.View */ initialize: function () { // The timer is used to create a delay before dismissing the contextual diff --git a/core/modules/contextual/js/views/RegionView.js b/core/modules/contextual/js/views/RegionView.js index c29ce47..6f46daf 100644 --- a/core/modules/contextual/js/views/RegionView.js +++ b/core/modules/contextual/js/views/RegionView.js @@ -7,11 +7,10 @@ "use strict"; -/** - * Renders the visual view of a contextual region element. - */ -Drupal.contextual.RegionView = Backbone.View.extend({ - +Drupal.contextual.RegionView = Backbone.View.extend(/** @lends Drupal.contextual.RegionView# */ { + /** + * @return {Object} + */ events: function () { var mapping = { mouseenter: function () { this.model.set('regionIsHovered', true); }, @@ -27,14 +26,17 @@ Drupal.contextual.RegionView = Backbone.View.extend({ }, /** - * {@inheritdoc} + * Renders the visual view of a contextual region element. + * + * @constructs Drupal.contextual.RegionView + * @augments Backbone.View */ initialize: function () { this.listenTo(this.model, 'change:hasFocus', this.render); }, /** - * {@inheritdoc} + * @method */ render: function () { this.$el.toggleClass('focus', this.model.get('hasFocus')); diff --git a/core/modules/contextual/js/views/VisualView.js b/core/modules/contextual/js/views/VisualView.js index 3c9119b..c05e504 100644 --- a/core/modules/contextual/js/views/VisualView.js +++ b/core/modules/contextual/js/views/VisualView.js @@ -7,11 +7,11 @@ "use strict"; -/** - * Renders the visual view of a contextual link. Listens to mouse & touch. - */ -Drupal.contextual.VisualView = Backbone.View.extend({ +Drupal.contextual.VisualView = Backbone.View.extend(/** @lends Drupal.contextual.VisualView# */ { + /** + * @return {Object} + */ events: function () { // Prevents delay and simulated mouse events. var touchEndToClick = function (event) { @@ -32,14 +32,17 @@ Drupal.contextual.VisualView = Backbone.View.extend({ }, /** - * {@inheritdoc} + * Renders the visual view of a contextual link. Listens to mouse & touch. + * + * @constructs Drupal.contextual.VisualView + * @augments Backbone.View */ initialize: function () { this.listenTo(this.model, 'change', this.render); }, /** - * {@inheritdoc} + * @method */ render: function () { var isOpen = this.model.get('isOpen'); diff --git a/core/modules/edit/js/edit.js b/core/modules/edit/js/edit.js index 127fbbe..da6a429 100644 --- a/core/modules/edit/js/edit.js +++ b/core/modules/edit/js/edit.js @@ -3,11 +3,13 @@ * Attaches behavior for the Edit module. * * 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 * * To achieve this, there are several queues: + * * - fieldsMetadataQueue: fields whose metadata still needs to be fetched. * - fieldsAvailableQueue: queue of fields whose metadata is known, and for * which it has been confirmed that the user has permission to edit them. @@ -63,6 +65,9 @@ var contextualLinksQueue = []; */ var entityInstancesTracker = {}; +/** + * @type {Behavior} + */ Drupal.behaviors.edit = { attach: function (context) { // Initialize the Edit app once per page load. @@ -114,40 +119,81 @@ Drupal.behaviors.edit = { } }; +/** + * @namespace + */ Drupal.edit = { - // A Drupal.edit.AppView instance. + /** + * @type {?Drupal.edit.AppView} + */ app: null, + /** + * @type {Object} + * @prop {Drupal.edit.EntityCollection} entities + * All in-place editable entities on the page + * @prop {Drupal.edit.FieldCollection} fields + * All in-place editable fields on the page + */ collections: { - // All in-place editable entities (Drupal.edit.EntityModel) on the page. entities: null, - // All in-place editable fields (Drupal.edit.FieldModel) on the page. fields: null }, - // In-place editors will register themselves in this object. + /** + * In-place editors will register themselves in this object. + * @type {Object.} + */ 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 + * @returns {Boolean} + */ has: function (fieldID) { return storage.getItem(this._prefixFieldID(fieldID)) !== null; }, + /** + * @param {String} fieldID + * @param {*} metadata + */ add: function (fieldID, metadata) { storage.setItem(this._prefixFieldID(fieldID), JSON.stringify(metadata)); }, + /** + * @param {String} fieldID + * @param {String} key + * @returns {*} + */ get: function (fieldID, key) { var metadata = JSON.parse(storage.getItem(this._prefixFieldID(fieldID))); return (key === undefined) ? metadata : metadata[key]; }, + /** + * @param {String} fieldID + * @returns {String} + */ _prefixFieldID: function (fieldID) { return 'Drupal.edit.metadata.' + fieldID; }, + /** + * @param {String} fieldID + * @returns {String} + */ _unprefixFieldID: function (fieldID) { // Strip "Drupal.edit.metadata.", which is 21 characters long. return fieldID.substring(21); }, + /** + * @param {Array} fieldIDs + * @returns {Array} + */ intersection: function (fieldIDs) { var prefixedFieldIDs = _.map(fieldIDs, this._prefixFieldID); var intersection = _.intersection(prefixedFieldIDs, _.keys(sessionStorage)); @@ -200,10 +246,10 @@ $(document).on('drupalContextualLinkAdded', function (event, data) { /** * Extracts the entity ID from a field ID. * - * @param String fieldID + * @param {String} fieldID * A field ID: a string of the format * `////`. - * @return String + * @return {String} * An entity ID: a string of the format `/`. */ function extractEntityID (fieldID) { @@ -213,7 +259,7 @@ function extractEntityID (fieldID) { /** * Initialize the Edit app. * - * @param DOM bodyElement + * @param {HTMLElement} bodyElement * This document's body element. */ function initEdit (bodyElement) { @@ -233,7 +279,7 @@ function initEdit (bodyElement) { /** * Assigns the entity an instance ID. * - * @param DOM entityElement. + * @param {HTMLElement} entityElement. * A Drupal Entity API entity's DOM element with a data-edit-entity-id * attribute. */ @@ -254,7 +300,7 @@ function processEntity (entityElement) { /** * 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-edit-field-id attribute. */ function processField (fieldElement) { @@ -305,13 +351,13 @@ function processField (fieldElement) { /** * 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) { @@ -341,7 +387,7 @@ function initializeField (fieldElement, fieldID, entityID, entityInstanceID) { * * 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. */ @@ -380,7 +426,7 @@ function fetchMissingMetadata (callback) { * Missing in-place editors are those whose fields are actively being used on * 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. */ @@ -428,8 +474,9 @@ function loadMissingEditors (callback) { /** * 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: an Edit entity identifier, e.g. "node/1" or * "custom_block/5". * - String entityInstanceID: an Edit entity instance identifier, e.g. 0, 1 @@ -438,7 +485,8 @@ function loadMissingEditors (callback) { * - 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 + * + * @return {Boolean} * 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 @@ -539,7 +587,7 @@ function initializeEntityContextualLink (contextualLink) { * * Note: this will not delete an entity that is actively being in-place edited. * - * @param jQuery $context + * @param {jQueryObject} $context * The context within which to delete. */ function deleteContainedModelsAndQueues($context) { diff --git a/core/modules/edit/js/editors/formEditor.js b/core/modules/edit/js/editors/formEditor.js index 9687f58..e94a24b 100644 --- a/core/modules/edit/js/editors/formEditor.js +++ b/core/modules/edit/js/editors/formEditor.js @@ -7,16 +7,26 @@ "use strict"; -Drupal.edit.editors.form = Drupal.edit.EditorView.extend({ +/** + * @class + * @augments Drupal.edit.EditorView + */ +Drupal.edit.editors.form = Drupal.edit.EditorView.extend(/** @lends Drupal.edit.editors.form# */{ - // Tracks the form container DOM element that is used while in-place editing. + /** + * Tracks the form container DOM element that is used while in-place editing. + * @type {?jQueryObject} + */ $formContainer: null, - // Holds the Drupal.ajax object + /** + * Holds the Drupal.ajax object + * @type {?Drupal.ajax} + */ formSaveAjax: null, /** - * {@inheritdoc} + * @method */ stateChange: function (fieldModel, state) { var from = fieldModel.previous('state'); @@ -53,7 +63,7 @@ Drupal.edit.editors.form = Drupal.edit.EditorView.extend({ }, /** - * {@inheritdoc} + * @method */ getEditUISettings: function () { return { padding: true, unifiedToolbar: true, fullWidthToolbar: true, popup: true }; @@ -153,7 +163,7 @@ Drupal.edit.editors.form = Drupal.edit.EditorView.extend({ }, /** - * {@inheritdoc} + * @method */ save: function () { var $formContainer = this.$formContainer; @@ -211,7 +221,7 @@ Drupal.edit.editors.form = Drupal.edit.EditorView.extend({ }, /** - * {@inheritdoc} + * @method */ showValidationErrors: function () { this.$formContainer diff --git a/core/modules/edit/js/editors/plainTextEditor.js b/core/modules/edit/js/editors/plainTextEditor.js index 9f1dc47..d776ea5 100644 --- a/core/modules/edit/js/editors/plainTextEditor.js +++ b/core/modules/edit/js/editors/plainTextEditor.js @@ -2,18 +2,20 @@ * @file * contentEditable-based in-place editor for plain text content. */ - (function ($, _, Drupal) { "use strict"; -Drupal.edit.editors.plain_text = Drupal.edit.EditorView.extend({ - - // Stores the textual DOM element that is being in-place edited. +Drupal.edit.editors.plain_text = Drupal.edit.EditorView.extend(/** @lends Drupal.edit.editors.plain_text# */ { + /** + * Stores the textual DOM element that is being in-place edited. + * @type {?jQueryObject} + */ $textElement: null, /** - * {@inheritdoc} + * @constructs Drupal.edit.editors.plain_text + * @augments Drupal.edit.EditorView */ initialize: function (options) { Drupal.edit.EditorView.prototype.initialize.call(this, options); @@ -45,14 +47,14 @@ Drupal.edit.editors.plain_text = Drupal.edit.EditorView.extend({ }, /** - * {@inheritdoc} + * @method */ getEditedElement: function () { return this.$textElement; }, /** - * {@inheritdoc} + * @method */ stateChange: function (fieldModel, state, options) { var from = fieldModel.previous('state'); @@ -97,14 +99,14 @@ Drupal.edit.editors.plain_text = Drupal.edit.EditorView.extend({ }, /** - * {@inheritdoc} + * @method */ getEditUISettings: function () { return { padding: true, unifiedToolbar: false, fullWidthToolbar: false, popup: false }; }, /** - * {@inheritdoc} + * @method */ revert: function () { this.$textElement.html(this.model.get('originalValue')); diff --git a/core/modules/edit/js/models/AppModel.js b/core/modules/edit/js/models/AppModel.js index 91af8d0..d261627 100644 --- a/core/modules/edit/js/models/AppModel.js +++ b/core/modules/edit/js/models/AppModel.js @@ -9,17 +9,41 @@ "use strict"; -Drupal.edit.AppModel = Backbone.Model.extend({ - +/** + * @class + * @augments Backbone.Model + */ +Drupal.edit.AppModel = Backbone.Model.extend(/** @lends Drupal.edit.AppModel# */ { + /** + * @type {Object} + * @prop {?Drupal.edit.FieldModel} highlightedField + * @prop {?Drupal.edit.FieldModel} activeField + * @prop {?Drupal.dialog} activeModal + */ defaults: { - // The currently state = 'highlighted' Drupal.edit.FieldModel, if any. - // @see Drupal.edit.FieldModel.states + /** + * The currently state = 'highlighted' Drupal.edit.FieldModel, if any. + * {@linkto Drupal.edit.FieldModel.states} + * @name Drupal.edit.AppModel#highlightedField + * @type {?Drupal.edit.FieldModel} + * @virtual + */ highlightedField: null, - // The currently state = 'active' Drupal.edit.FieldModel, if any. - // @see Drupal.edit.FieldModel.states + /** + * The currently state = 'active' Drupal.edit.FieldModel, if any. + * {@linkto Drupal.edit.FieldModel.states} + * @name Drupal.edit.AppModel#activeField + * @type {?Drupal.edit.FieldModel} + * @virtual + */ 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. + * @name Drupal.edit.AppModel#activeModal + * @type {?Drupal.dialog} + * @virtual + */ activeModal: null } diff --git a/core/modules/edit/js/models/BaseModel.js b/core/modules/edit/js/models/BaseModel.js index d7870b6..9cf3007 100644 --- a/core/modules/edit/js/models/BaseModel.js +++ b/core/modules/edit/js/models/BaseModel.js @@ -7,10 +7,13 @@ "use strict"; -Drupal.edit.BaseModel = Backbone.Model.extend({ +Drupal.edit.BaseModel = Backbone.Model.extend(/** @lends Drupal.edit.BaseModel# */ { /** - * {@inheritdoc} + * @constructs Drupal.edit.BaseModel + * @augments Backbone.Model + * + * @param {Object} options */ initialize: function (options) { this.__initialized = true; @@ -18,7 +21,10 @@ Drupal.edit.BaseModel = Backbone.Model.extend({ }, /** - * {@inheritdoc} + * @param {*} key + * @param {*} val + * @param {Object} options + * @returns {Backbone.Model} */ set: function (key, val, options) { if (this.__initialized) { diff --git a/core/modules/edit/js/models/EditorModel.js b/core/modules/edit/js/models/EditorModel.js index fe18681..5446ceb 100644 --- a/core/modules/edit/js/models/EditorModel.js +++ b/core/modules/edit/js/models/EditorModel.js @@ -9,16 +9,37 @@ "use strict"; -Drupal.edit.EditorModel = Backbone.Model.extend({ - +/** + * @class + * @augments Backbone.Model + */ +Drupal.edit.EditorModel = Backbone.Model.extend(/** @lends Drupal.edit.EditorModel# */ { + /** + * @type {Object} + */ 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. + /** + * 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. + * @name Drupal.edit.EditorModel#originalValue + * @type {?*} + * @virtual + */ originalValue: null, - // Analogous to originalValue, but the current value. + /** + * Analogous to originalValue, but the current value. + * @name Drupal.edit.EditorModel#currentValue + * @type {?*} + * @virtual + */ currentValue: null, - // Stores any validation errors to be rendered. + /** + * Stores any validation errors to be rendered. + * @name Drupal.edit.EditorModel#validationErrors + * @type {?Array|String} + * @virtual + */ validationErrors: null } diff --git a/core/modules/edit/js/models/EntityModel.js b/core/modules/edit/js/models/EntityModel.js index 2e592e3..c7b8a41 100644 --- a/core/modules/edit/js/models/EntityModel.js +++ b/core/modules/edit/js/models/EntityModel.js @@ -7,56 +7,125 @@ "use strict"; -Drupal.edit.EntityModel = Drupal.edit.BaseModel.extend({ +Drupal.edit.EntityModel = Drupal.edit.BaseModel.extend(/** @lends Drupal.edit.FieldModel# */{ + /** + * @type {Object} + */ 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. + /** + * 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. + * @name Drupal.edit.EntityModel#el + * @type {?HTMLElement} + * @virtual + */ el: null, - // An entity ID, of the form "/", e.g. "node/1". + /** + * An entity ID, of the form `/`, e.g. `node/1`. + * @name Drupal.edit.EntityModel#entityID + * @type {?String} + * @virtual + */ entityID: null, - // An entity instance ID. The first intance 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 intance of a specific entity (i.e. with + * a given entity ID) is assigned 0, the second 1, and so on. + * @name Drupal.edit.EntityModel#entityInstanceID + * @type {?Number} + * @virtual + */ entityInstanceID: null, - // The unique ID of this entity instance on the page, of the form "/[entity instance ID]", e.g. "node/1[0]". + /** + * The unique ID of this entity instance on the page, of the form + * `/[entity instance ID]`, e.g. `node/1[0]`. + * @name Drupal.edit.EntityModel#id + * @type {?String} + * @virtual + */ id: null, - // The label of the entity. + /** + * The label of the entity. + * @name Drupal.edit.EntityModel#label + * @type {?String} + * @virtual + */ label: null, - // A Drupal.edit.FieldCollection for all fields of this entity. + /** + * A Drupal.edit.FieldCollection for all fields of this entity. + * @name Drupal.edit.EntityModel#fields + * @type {?Drupal.edit.FieldCollection} + * @virtual + */ 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. + /** + * 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. + * @name Drupal.edit.EntityModel#isActive + * @type {Boolean} + * @virtual + */ isActive: false, - // Whether one or more fields have already been stored in TempStore. + /** + * Whether one or more fields have already been stored in TempStore. + * @name Drupal.edit.EntityModel#inTempStore + * @type {Boolean} + * @virtual + */ inTempStore: false, - // Whether one or more fields have already been stored in TempStore *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. + /** + * Whether one or more fields have already been stored in TempStore *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. + * @name Drupal.edit.EntityModel#isDirty + * @type {Boolean} + * @virtual + */ 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. + * @name Drupal.edit.EntityModel#isCommitting + * @type {Boolean} + * @virtual + */ isCommitting: false, - // The current processing state of an entity. + /** + * The current processing state of an entity. + * @name Drupal.edit.EntityModel#state + * @type {String} + * @virtual + */ state: 'closed', - // The IDs of the fields whose new values have been stored in TempStore. 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. + /** + * The IDs of the fields whose new values have been stored in TempStore. 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. + * @name Drupal.edit.EntityModel#fieldsInTempStore + * @type {Array} + * @virtual + */ 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. + * @name Drupal.edit.EntityModel#reload + * @type {Boolean} + * @virtual + */ reload: false }, /** - * @inheritdoc + * @constructs Drupal.edit.EntityModel + * @augments Backbone.Model */ initialize: function () { this.set('fields', new Drupal.edit.FieldCollection()); @@ -75,10 +144,10 @@ Drupal.edit.EntityModel = Drupal.edit.BaseModel.extend({ /** * Updates FieldModels' states when an EntityModel change occurs. * - * @param Drupal.edit.EntityModel entityModel - * @param String state + * @param {Drupal.edit.EntityModel} entityModel + * @param {String} state * The state of the associated entity. One of Drupal.edit.EntityModel.states. - * @param Object options + * @param {Object} options */ stateChange: function (entityModel, state, options) { var to = state; @@ -193,12 +262,12 @@ Drupal.edit.EntityModel = Drupal.edit.BaseModel.extend({ * * Helper function. * - * @param Drupal.edit.EntityModel entityModel + * @param {Drupal.edit.EntityModel} entityModel * The model of the entity for which a field's state attribute has changed. - * @param Drupal.edit.FieldModel fieldModel + * @param {Drupal.edit.FieldModel} fieldModel * The model of the field whose state attribute has changed. * - * @see fieldStateChange() + * @see Drupal.edit.EntityModel#fieldStateChange */ _updateInTempStoreAttributes: function (entityModel, fieldModel) { var current = fieldModel.get('state'); @@ -230,9 +299,9 @@ Drupal.edit.EntityModel = Drupal.edit.BaseModel.extend({ /** * Reacts to state changes in this entity's fields. * - * @param Drupal.edit.FieldModel fieldModel + * @param {Drupal.edit.FieldModel} fieldModel * The model of the field whose state attribute changed. - * @param String state + * @param {String} state * The state of the associated field. One of Drupal.edit.FieldModel.states. */ fieldStateChange: function (fieldModel, state) { @@ -351,7 +420,7 @@ Drupal.edit.EntityModel = Drupal.edit.BaseModel.extend({ /** * 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. @@ -400,12 +469,11 @@ Drupal.edit.EntityModel = Drupal.edit.BaseModel.extend({ }, /** - * {@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 @@ -488,9 +556,9 @@ Drupal.edit.EntityModel = Drupal.edit.BaseModel.extend({ }, /** - * @param Array acceptedFieldStates - * @see validate() - * @return Boolean + * @param {Array} acceptedFieldStates + * @see Drupal.edit.EntityModel#validate + * @return {Boolean} */ _fieldsHaveAcceptableStates: function (acceptedFieldStates) { var accept = true; @@ -511,7 +579,7 @@ Drupal.edit.EntityModel = Drupal.edit.BaseModel.extend({ }, /** - * @inheritdoc + * @method */ destroy: function (options) { Drupal.edit.BaseModel.prototype.destroy.call(this, options); @@ -525,18 +593,19 @@ Drupal.edit.EntityModel = Drupal.edit.BaseModel.extend({ }, /** - * {@inheritdoc} + * @method */ sync: function () { // We don't use REST updates to sync. return; } -}, { +}, /** @lends Drupal.edit.EntityModel */{ /** * A list (sequence) of all possible states an entity can be in during * in-place editing. + * @type {Array} */ states: [ // Initial state, like field's 'inactive' OR the user has just finished @@ -593,11 +662,11 @@ Drupal.edit.EntityModel = Drupal.edit.BaseModel.extend({ /** * Indicates whether the 'from' state comes before the 'to' state. * - * @param String from + * @param {String} from * One of Drupal.edit.EntityModel.states. - * @param String to + * @param {String} to * One of Drupal.edit.EntityModel.states. - * @return Boolean + * @return {Boolean} */ followsStateSequence: function (from, to) { return _.indexOf(this.states, from) < _.indexOf(this.states, to); @@ -605,7 +674,13 @@ Drupal.edit.EntityModel = Drupal.edit.BaseModel.extend({ }); -Drupal.edit.EntityCollection = Backbone.Collection.extend({ +/** + * @class + */ +Drupal.edit.EntityCollection = Backbone.Collection.extend(/** @lends Drupal.edit.EntityCollection# */ { + /** + * @type {Drupal.edit.EntityModel} + */ model: Drupal.edit.EntityModel }); diff --git a/core/modules/edit/js/models/FieldModel.js b/core/modules/edit/js/models/FieldModel.js index ea537a0..a114aab 100644 --- a/core/modules/edit/js/models/FieldModel.js +++ b/core/modules/edit/js/models/FieldModel.js @@ -7,62 +7,125 @@ "use strict"; -/** - * State of an in-place editable field in the DOM. - */ -Drupal.edit.FieldModel = Drupal.edit.BaseModel.extend({ +Drupal.edit.FieldModel = Drupal.edit.BaseModel.extend(/** @lends Drupal.edit.FieldModel# */{ + /** + * @type {Object} + */ 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. + * @name Drupal.edit.FieldModel#el + * @type {?HTMLElement} + * @virtual + */ el: null, - // A field ID, of the form - // "////", e.g. - // "node/1/field_tags/und/full". + /** + * A field ID, of the form + * `////`, e.g. + * `node/1/field_tags/und/full`. + * @name Drupal.edit.FieldModel#fieldID + * @type {?String} + * @virtual + */ fieldID: null, - // The unique ID of this field within its entity instance on the page, of - // the form "////[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 instance ID]`, + * e.g. "node/1/field_tags/und/full[0]". + * @name Drupal.edit.FieldModel#id + * @type {?String} + * @virtual + */ id: null, - // A Drupal.edit.EntityModel. Its "fields" attribute, which is a - // FieldCollection, is automatically updated to include this FieldModel. + /** + * A Drupal.edit.EntityModel. Its "fields" attribute, which is a + * FieldCollection, is automatically updated to include this FieldModel. + * @name Drupal.edit.FieldModel#entity + * @type {?Drupal.edit.EntityModel} + * @virtual + */ entity: null, - // This field's metadata as returned by the EditController::metadata(). + /** + * This field's metadata as returned by the EditController::metadata(). + * @name Drupal.edit.FieldModel#metadata + * @type {?Object} + * @virtual + */ 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 + * @name Drupal.edit.FieldModel#acceptStateChange + * @type {?Function} + * @virtual + */ acceptStateChange: null, - // A logical field ID, of the form - // "///", 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 + * `///`, 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`. + * @name Drupal.edit.FieldModel#logicalFieldID + * @type {?String} + * @virtual + */ 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.edit.FieldModel.states. + /** + * 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: {@linkto Drupal.edit.FieldModel.states} + * @name Drupal.edit.FieldModel#state + * @type {String} + * @virtual + */ 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. + * @name Drupal.edit.FieldModel#isChanged + * @type {Boolean} + * @virtual + */ 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. + * @name Drupal.edit.FieldModel#inTempStore + * @type {Boolean} + * @virtual + */ inTempStore: false, - // The full HTML representation of this field (with the element that has - // the data-edit-field-id as the outer element). Used to propagate changes - // from this field instance to other instances of the same field. + /** + * The full HTML representation of this field (with the element that has + * the data-edit-field-id as the outer element). Used to propagate changes + * from this field instance to other instances of the same field. + * @name Drupal.edit.FieldModel#html + * @type {?String} + * @virtual + */ 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. + * @name Drupal.edit.FieldModel#htmlForOtherViewModes + * @type {Object.} + * @virtual + */ htmlForOtherViewModes: null }, /** - * {@inheritdoc} + * State of an in-place editable field in the DOM. + * + * @constructs Drupal.edit.FieldModel + * @augments Backbone.Model */ initialize: function (options) { // Store the original full HTML representation of this field. @@ -79,7 +142,7 @@ Drupal.edit.FieldModel = Drupal.edit.BaseModel.extend({ }, /** - * {@inheritdoc} + * @param options */ destroy: function (options) { if (this.get('state') !== 'inactive') { @@ -89,7 +152,7 @@ Drupal.edit.FieldModel = Drupal.edit.BaseModel.extend({ }, /** - * {@inheritdoc} + * @method */ sync: function () { // We don't use REST updates to sync. @@ -97,7 +160,8 @@ Drupal.edit.FieldModel = Drupal.edit.BaseModel.extend({ }, /** - * {@inheritdoc} + * @param {Object} attrs + * @param {object} options */ validate: function (attrs, options) { var current = this.get('state'); @@ -117,7 +181,7 @@ Drupal.edit.FieldModel = Drupal.edit.BaseModel.extend({ /** * Extracts the entity ID from this field's ID. * - * @return String + * @return {String} * An entity ID: a string of the format `/`. */ getEntityID: function () { @@ -127,7 +191,7 @@ Drupal.edit.FieldModel = Drupal.edit.BaseModel.extend({ /** * Extracts the view mode ID from this field's ID. * - * @return String + * @return {String} * A view mode ID. */ getViewMode: function () { @@ -137,7 +201,7 @@ Drupal.edit.FieldModel = Drupal.edit.BaseModel.extend({ /** * Find other instances of this field with different view modes. * - * @return Array + * @return {Array} * An array containing view mode IDs. */ findOtherViewModes: function () { @@ -164,11 +228,12 @@ Drupal.edit.FieldModel = Drupal.edit.BaseModel.extend({ return otherViewModes; } -}, { +}, /** @lends Drupal.edit.FieldModel */ { /** * A list (sequence) of all possible states a field can be in during in-place * editing. + * @type {Array} */ states: [ // The field associated with this FieldModel is linked to an EntityModel; @@ -241,11 +306,11 @@ Drupal.edit.FieldModel = Drupal.edit.BaseModel.extend({ /** * Indicates whether the 'from' state comes before the 'to' state. * - * @param String from + * @param {String} from * One of Drupal.edit.FieldModel.states. - * @param String to + * @param {String} to * One of Drupal.edit.FieldModel.states. - * @return Boolean + * @return {Boolean} */ followsStateSequence: function (from, to) { return _.indexOf(this.states, from) < _.indexOf(this.states, to); @@ -253,7 +318,14 @@ Drupal.edit.FieldModel = Drupal.edit.BaseModel.extend({ }); -Drupal.edit.FieldCollection = Backbone.Collection.extend({ +/** + * @constructor + * @augments Backbone.Collection + */ +Drupal.edit.FieldCollection = Backbone.Collection.extend(/** @lends Drupal.edit.FieldCollection# */ { + /** + * @type {Drupal.edit.FieldModel} + */ model: Drupal.edit.FieldModel }); diff --git a/core/modules/edit/js/theme.js b/core/modules/edit/js/theme.js index fdd0fbb..e7fc8e5 100644 --- a/core/modules/edit/js/theme.js +++ b/core/modules/edit/js/theme.js @@ -10,10 +10,11 @@ /** * Theme function for a "backstage" for the Edit module. * - * @param Object settings + * @param {Object} settings * An object with the following keys: - * - String id: the id to apply to the backstage. - * @return String + * @param {String} settings.id + * The id to apply to the backstage. + * @return {String} * The corresponding HTML. */ Drupal.theme.editBackstage = function (settings) { @@ -25,10 +26,10 @@ Drupal.theme.editBackstage = function (settings) { /** * Theme function for a toolbar container of the 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 + * id to apply to the toolbar container. + * @return {String} * The corresponding HTML. */ Drupal.theme.editEntityToolbar = function (settings) { @@ -47,11 +48,12 @@ Drupal.theme.editEntityToolbar = function (settings) { /** * Theme function for a toolbar container of the 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.editEntityToolbarLabel = function (settings) { @@ -61,7 +63,7 @@ Drupal.theme.editEntityToolbarLabel = function (settings) { /** * Element that defines a containing box of the placement of the entity toolbar. * - * @return String + * @return {String} * The corresponding HTML. */ Drupal.theme.editEntityToolbarFence = function () { @@ -71,10 +73,10 @@ Drupal.theme.editEntityToolbarFence = function () { /** * Theme function for a toolbar container of the 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.editFieldToolbar = function (settings) { @@ -84,12 +86,14 @@ Drupal.theme.editFieldToolbar = function (settings) { /** * Theme function for a toolbar toolgroup of the 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.prototype.editButtons(). - * @return String + * @param {Object} settings + * @param {String} [settings.id] + * id of the toolgroup + * @param {String} settings.classes + * class of the toolgroup. + * @param {Array} settings.buttons + * {@linkto Drupal.theme.prototype.editButtons}. + * @return {String} * The corresponding HTML. */ Drupal.theme.editToolgroup = function (settings) { @@ -112,13 +116,15 @@ Drupal.theme.editToolgroup = function (settings) { * * Can be used for the buttons both in the toolbar toolgroups and in the modal. * - * @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 + * @param {Object} settings + * @param {Array.} settings.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} * The corresponding HTML. */ Drupal.theme.editButtons = function (settings) { @@ -146,11 +152,12 @@ Drupal.theme.editButtons = function (settings) { /** * Theme function for a form container of the 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.editFormContainer = function (settings) { diff --git a/core/modules/edit/js/util.js b/core/modules/edit/js/util.js index da7656e..d88421a 100644 --- a/core/modules/edit/js/util.js +++ b/core/modules/edit/js/util.js @@ -7,19 +7,30 @@ "use strict"; -Drupal.edit.util = Drupal.edit.util || {}; +/** + * @namespace + */ +Drupal.edit.util = {}; +/** + * @namespace + */ Drupal.edit.util.constants = {}; +/** + * @const + * @type {string} + */ Drupal.edit.util.constants.transitionEnd = "transitionEnd.edit webkitTransitionEnd.edit transitionend.edit msTransitionEnd.edit oTransitionEnd.edit"; /** * Converts a field id into a formatted url path. * - * @param String id + * @param {String} id * The id of an editable field. For example, 'node/1/body/und/full'. - * @param String urlFormat + * @param {String} urlFormat * The Controller route for field processing. For example, - * '/edit/form/%21entity_type/%21id/%21field_name/%21langcode/%21view_mode'. + * `/edit/form/%21entity_type/%21id/%21field_name/%21langcode/%21view_mode`. + * @return {String} */ Drupal.edit.util.buildUrl = function (id, urlFormat) { var parts = id.split('/'); @@ -35,9 +46,9 @@ Drupal.edit.util.buildUrl = function (id, urlFormat) { /** * 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.edit.util.networkErrorModal = function (title, message) { @@ -64,6 +75,9 @@ Drupal.edit.util.networkErrorModal = function (title, message) { networkErrorModal.showModal(); }; +/** + * @namespace + */ Drupal.edit.util.form = { /** @@ -72,8 +86,9 @@ Drupal.edit.util.form = { * 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 @@ -82,10 +97,12 @@ Drupal.edit.util.form = { * 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 TempStore should be used or reset. - * @param Function callback + * + * @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. + * @return {Drupal.ajax} */ load: function (options, callback) { var $el = options.$el; @@ -127,13 +144,13 @@ Drupal.edit.util.form = { /** * Creates a Drupal.ajax instance that is used to save a form. * - * @param Object options + * @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 + * @return {Drupal.ajax} * A Drupal.ajax instance. */ ajaxifySaving: function (options, $submit) { @@ -164,7 +181,7 @@ Drupal.edit.util.form = { /** * Cleans up the Drupal.ajax instance that is used to save the form. * - * @param Drupal.ajax ajax + * @param {Drupal.ajax} ajax * A Drupal.ajax that was returned by Drupal.edit.form.ajaxifySaving(). */ unajaxifySaving: function (ajax) { diff --git a/core/modules/edit/js/views/AppView.js b/core/modules/edit/js/views/AppView.js index 599ba2b..85463e1 100644 --- a/core/modules/edit/js/views/AppView.js +++ b/core/modules/edit/js/views/AppView.js @@ -17,16 +17,15 @@ // makes it impossible for Edit to know where to restore the original HTML. var reload = false; -Drupal.edit.AppView = Backbone.View.extend({ +Drupal.edit.AppView = Backbone.View.extend(/** @lends Drupal.edit.AppView# */{ /** - * {@inheritdoc} - * - * @param Object options - * An object with the following keys: - * - Drupal.edit.AppModel model: the application state model - * - Drupal.edit.EntityCollection entitiesCollection: all on-page entities - * - Drupal.edit.FieldCollection fieldsCollection: all on-page fields + * @constructs Drupal.edit.AppView + * @augments Backbone.View + * @param {Object} options + * @param {Drupal.edit.AppModel} options.model the application state model + * @param {Drupal.edit.EntityCollection} options.entitiesCollection all on-page entities + * @param {Drupal.edit.FieldCollection} options.fieldsCollection all on-page fields */ initialize: function (options) { // AppView's configuration for handling states. @@ -56,9 +55,9 @@ Drupal.edit.AppView = Backbone.View.extend({ /** * Handles setup/teardown and state changes when the active entity changes. * - * @param Drupal.edit.EntityModel entityModel + * @param {Drupal.edit.EntityModel} entityModel * An instance of the EntityModel class. - * @param String state + * @param {String} state * The state of the associated field. One of Drupal.edit.EntityModel.states. */ appStateChange: function (entityModel, state) { @@ -111,13 +110,13 @@ Drupal.edit.AppView = Backbone.View.extend({ * * 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.edit.FieldModel fieldModel + * @param {Drupal.edit.FieldModel} fieldModel * The fieldModel to which this change applies. */ acceptEditorStateChange: function (from, to, context, fieldModel) { @@ -244,7 +243,7 @@ Drupal.edit.AppView = Backbone.View.extend({ * * Must happen before the fieldModel's state is changed to 'candidate'. * - * @param Drupal.edit.FieldModel fieldModel + * @param {Drupal.edit.FieldModel} fieldModel * The field for which an in-place editor must be set up. */ setupEditor: function (fieldModel) { @@ -293,7 +292,7 @@ Drupal.edit.AppView = Backbone.View.extend({ * * Must happen after the fieldModel's state is changed to 'inactive'. * - * @param Drupal.edit.FieldModel fieldModel + * @param {Drupal.edit.FieldModel} fieldModel * The field for which an in-place editor must be torn down. */ teardownEditor: function (fieldModel) { @@ -320,7 +319,7 @@ Drupal.edit.AppView = Backbone.View.extend({ /** * Asks the user to confirm whether he wants to stop editing via a modal. * - * @see acceptEditorStateChange() + * @see Drupal.edit.AppView#acceptEditorStateChange */ confirmEntityDeactivation: function (entityModel) { var that = this; @@ -390,8 +389,8 @@ Drupal.edit.AppView = Backbone.View.extend({ /** * Reacts to field state changes; tracks global state. * - * @param Drupal.edit.FieldModel fieldModel - * @param String state + * @param {Drupal.edit.FieldModel} fieldModel + * @param {String} state * The state of the associated field. One of Drupal.edit.FieldModel.states. */ editorStateChange: function (fieldModel, state) { @@ -422,15 +421,15 @@ Drupal.edit.AppView = Backbone.View.extend({ /** * Render an updated field (a field whose 'html' attribute changed). * - * @param Drupal.edit.FieldModel fieldModel + * @param {Drupal.edit.FieldModel} fieldModel * The FieldModel whose 'html' attribute changed. - * @param String html + * @param {String} html * The updated 'html' attribute. - * @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 {Object} options + * @param {Boolean} 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. @@ -484,17 +483,17 @@ Drupal.edit.AppView = Backbone.View.extend({ /** * Propagates the changes to an updated field to all instances of that field. * - * @param Drupal.edit.FieldModel updatedField + * @param {Drupal.edit.FieldModel} updatedField * The FieldModel whose 'html' attribute changed. - * @param String html + * @param {String} html * The updated 'html' attribute. - * @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 {Object} options + * @param {Boolean} options.propagation + * Whether this change to the 'html' attribute + * occurred because of the propagation of changes to another instance of + * this field. * - * @see Drupal.edit.AppView.renderUpdatedField() + * @see Drupal.edit.AppView#renderUpdatedField */ propagateUpdatedField: function (updatedField, html, options) { // Don't propagate field updates that themselves were caused by propagation. @@ -537,7 +536,7 @@ Drupal.edit.AppView = Backbone.View.extend({ * * This happens when a field was modified, saved and hence rerendered. * - * @param Drupal.edit.FieldModel fieldModel + * @param {Drupal.edit.FieldModel} fieldModel * A field that was just added to the collection of fields. */ rerenderedFieldToCandidate: function (fieldModel) { @@ -559,7 +558,7 @@ Drupal.edit.AppView = Backbone.View.extend({ * EntityModel Collection change handler, called on change:isActive, enforces * a single active entity. * - * @param Drupal.edit.EntityModel + * @param {Drupal.edit.EntityModel} changedEntityModel * The entityModel instance whose active state has changed. */ enforceSingleActiveEntity: function (changedEntityModel) { diff --git a/core/modules/edit/js/views/ContextualLinkView.js b/core/modules/edit/js/views/ContextualLinkView.js index 65a6077..8405bfc 100644 --- a/core/modules/edit/js/views/ContextualLinkView.js +++ b/core/modules/edit/js/views/ContextualLinkView.js @@ -7,8 +7,11 @@ "use strict"; -Drupal.edit.ContextualLinkView = Backbone.View.extend({ +Drupal.edit.ContextualLinkView = Backbone.View.extend(/** @lends Drupal.edit.ContextualLinkView# */ { + /** + * @return {Object} + */ events: function () { // Prevents delay and simulated mouse events. function touchEndToClick (event) { @@ -25,13 +28,15 @@ Drupal.edit.ContextualLinkView = Backbone.View.extend({ }, /** - * {@inheritdoc} - * - * @param Object options - * An object with the following keys: - * - Drupal.edit.EntityModel model: the associated entity's model - * - Drupal.edit.AppModel appModel: the application state model - * - strings: the strings for the "Quick edit" link + * @constructs Drupal.edit.ContextualLinkView + * @augments Backbone.View + * @param {Object} options + * @param {Drupal.edit.EntityModel} options.model + * the associated entity's model + * @param {Drupal.edit.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. @@ -43,7 +48,8 @@ Drupal.edit.ContextualLinkView = Backbone.View.extend({ }, /** - * {@inheritdoc} + * @param {Drupal.edit.EntityModel} entityModel + * @param {Boolean} isActive */ render: function (entityModel, isActive) { this.$el.find('a').attr('aria-pressed', isActive); diff --git a/core/modules/edit/js/views/EditorView.js b/core/modules/edit/js/views/EditorView.js index a00432d..9951433 100644 --- a/core/modules/edit/js/views/EditorView.js +++ b/core/modules/edit/js/views/EditorView.js @@ -7,44 +7,48 @@ "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.edit.editors.form and Drupal.edit.editors.plain_text for - * examples. - * - * @see Drupal.edit.EditorModel - */ -Drupal.edit.EditorView = Backbone.View.extend({ +Drupal.edit.EditorView = Backbone.View.extend(/** @lends Drupal.edit.EditorView# */ { /** - * {@inheritdoc} - * * 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. * * If you override this method, you should call this method (the parent - * class' initialize()) first, like this: + * class' initialize()) first. + * @example * Drupal.edit.EditorView.prototype.initialize.call(this, options); * - * For an example, @see Drupal.edit.editors.plain_text. + * @see Drupal.edit.editors.plain_text + * + * @classdesc + * 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. * - * @param Object options - * An object with the following keys: - * - Drupal.edit.EditorModel model: the in-place editor state model - * - Drupal.edit.FieldModel fieldModel: the field model + * Look at Drupal.edit.editors.form and Drupal.edit.editors.plain_text for + * examples. + * + * @see Drupal.edit.EditorModel + * + * @constructs Drupal.edit.EditorView + * @augments Backbone.View + * + * @param {Object} options + * @param {Drupal.edit.EditorModel} options.model the in-place editor state model + * @param {Drupal.edit.FieldModel} options.fieldModel the field model */ initialize: function (options) { + /** + * @type {Drupal.edit.FieldModel} + */ this.fieldModel = options.fieldModel; this.listenTo(this.fieldModel, 'change:state', this.stateChange); }, /** - * {@inheritdoc} + * @method */ remove: function () { // The el property is the field, which should not be removed. Remove the @@ -63,9 +67,9 @@ Drupal.edit.EditorView = Backbone.View.extend({ * 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.edit.editors.plain_text. + * @see Drupal.edit.editors.plain_text * - * @return jQuery + * @return {jQueryObject} * A jQuery-wrapped DOM element. */ getEditedElement: function () { @@ -74,10 +78,11 @@ Drupal.edit.EditorView = Backbone.View.extend({ /** * Returns 3 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. * - Boolean unifiedToolbar: provides the in-place editor with the ability to - * insert its own toolbar UI into Edit's tightly integrated toolbar. + * insert its own toolbar UI into Edit's tightly integrated toolbar. * - Boolean fullWidthToolbar: indicates whether Edit's tightly integrated * toolbar should consume the full width of the element, rather than being * just long enough to accommodate a label. @@ -89,8 +94,8 @@ Drupal.edit.EditorView = Backbone.View.extend({ /** * Determines the actions to take given a change of state. * - * @param Drupal.edit.FieldModel fieldModel - * @param String state + * @param {Drupal.edit.FieldModel} fieldModel + * @param {String} state * The state of the associated field. One of Drupal.edit.FieldModel.states. */ stateChange: function (fieldModel, state) { diff --git a/core/modules/edit/js/views/EntityDecorationView.js b/core/modules/edit/js/views/EntityDecorationView.js index ad107f9..8934ee3 100644 --- a/core/modules/edit/js/views/EntityDecorationView.js +++ b/core/modules/edit/js/views/EntityDecorationView.js @@ -7,10 +7,11 @@ "use strict"; -Drupal.edit.EntityDecorationView = Backbone.View.extend({ +Drupal.edit.EntityDecorationView = Backbone.View.extend(/** @lends Drupal.edit.EntityDecorationView# */ { /** - * {@inheritdoc} + * @constructs Drupal.edit.EntityDecorationView + * @augments Backbone.View * * Associated with the DOM root node of an editable entity. */ @@ -19,14 +20,14 @@ Drupal.edit.EntityDecorationView = Backbone.View.extend({ }, /** - * {@inheritdoc} + * @method */ render: function () { this.$el.toggleClass('edit-entity-active', this.model.get('isActive')); }, /** - * {@inheritdoc} + * @method */ remove: function () { this.setElement(null); diff --git a/core/modules/edit/js/views/EntityToolbarView.js b/core/modules/edit/js/views/EntityToolbarView.js index 889335a..796e4f0 100644 --- a/core/modules/edit/js/views/EntityToolbarView.js +++ b/core/modules/edit/js/views/EntityToolbarView.js @@ -7,10 +7,16 @@ "use strict"; -Drupal.edit.EntityToolbarView = Backbone.View.extend({ +Drupal.edit.EntityToolbarView = Backbone.View.extend(/** @lends Drupal.edit.EntityToolbarView# */ { + /** + * @type {?jQueryObject} + */ _fieldToolbarRoot: null, + /** + * @return {Object} + */ events: function () { var map = { 'click button.action-save': 'onClickSave', @@ -21,11 +27,20 @@ Drupal.edit.EntityToolbarView = Backbone.View.extend({ }, /** - * {@inheritdoc} + * @constructs Drupal.edit.EntityToolbarView + * @augments Backbone.View + * @param {Object} options + * @param {Drupal.edit.appModel} options.appModel */ initialize: function (options) { var that = this; + /** + * @type {Drupal.edit.appModel} + */ this.appModel = options.appModel; + /** + * @type {jQueryObject} + */ this.$entity = $(this.model.get('el')); // Rerender whenever the entity state changes. @@ -57,7 +72,7 @@ Drupal.edit.EntityToolbarView = Backbone.View.extend({ }, /** - * {@inheritdoc} + * @method */ render: function () { if (this.model.get('isActive')) { @@ -69,6 +84,9 @@ Drupal.edit.EntityToolbarView = Backbone.View.extend({ // The fence will define a area on the screen that the entity toolbar // will be position within. if ($body.children('#edit-toolbar-fence').length === 0) { + /** + * @type {jQueryObject} + */ this.$fence = $(Drupal.theme('editEntityToolbarFence')) .css(Drupal.displace()) .appendTo($body); @@ -114,7 +132,7 @@ Drupal.edit.EntityToolbarView = Backbone.View.extend({ }, /** - * {@inheritdoc} + * @method */ remove: function () { // Remove additional DOM elements controlled by this View. @@ -130,7 +148,7 @@ Drupal.edit.EntityToolbarView = Backbone.View.extend({ /** * Repositions the entity toolbar on window scroll and resize. * - * @param jQuery.Eevent event + * @param {jQuery.Eevent} event */ windowChangeHandler: function (event) { this.position(); @@ -139,8 +157,8 @@ Drupal.edit.EntityToolbarView = Backbone.View.extend({ /** * Determines the actions to take given a change of state. * - * @param Drupal.edit.FieldModel model - * @param String state + * @param {Drupal.edit.FieldModel} model + * @param {String} state * The state of the associated field. One of Drupal.edit.FieldModel.states. */ fieldStateChange: function (model, state) { @@ -218,18 +236,21 @@ Drupal.edit.EntityToolbarView = Backbone.View.extend({ * 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. + * object contains the following properties + * @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. @@ -305,7 +326,7 @@ Drupal.edit.EntityToolbarView = Backbone.View.extend({ /** * Set the model state to 'saving' when the save button is clicked. * - * @param jQuery event + * @param {Event} event */ onClickSave: function (event) { event.stopPropagation(); @@ -317,7 +338,7 @@ Drupal.edit.EntityToolbarView = Backbone.View.extend({ /** * Sets the model state to candidate when the cancel button is clicked. * - * @param jQuery event + * @param {Event} event */ onClickCancel: function (event) { event.preventDefault(); @@ -329,7 +350,7 @@ Drupal.edit.EntityToolbarView = Backbone.View.extend({ * * Without this, it may reposition itself, away from the user's cursor! * - * @param jQuery event + * @param {Event} event */ onMouseenter: function (event) { clearTimeout(this.timer); @@ -378,7 +399,7 @@ Drupal.edit.EntityToolbarView = Backbone.View.extend({ /** * Returns the DOM element that fields will attach their toolbars to. * - * @return jQuery + * @return {jQueryObject} * The DOM element that fields will attach their toolbars to. */ getToolbarRoot: function () { @@ -424,9 +445,9 @@ Drupal.edit.EntityToolbarView = Backbone.View.extend({ /** * 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. */ @@ -437,9 +458,9 @@ Drupal.edit.EntityToolbarView = Backbone.View.extend({ /** * 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. */ @@ -450,9 +471,9 @@ Drupal.edit.EntityToolbarView = Backbone.View.extend({ /** * Finds a toolgroup. * - * @param String toolgroup + * @param {String} toolgroup * A toolgroup name. - * @return jQuery + * @return {jQueryObject} * The toolgroup DOM element. */ _find: function (toolgroup) { @@ -462,7 +483,7 @@ Drupal.edit.EntityToolbarView = Backbone.View.extend({ /** * Shows a toolgroup. * - * @param String toolgroup + * @param {String} toolgroup * A toolgroup name. */ show: function (toolgroup) { diff --git a/core/modules/edit/js/views/FieldDecorationView.js b/core/modules/edit/js/views/FieldDecorationView.js index 4172840..405a36a 100644 --- a/core/modules/edit/js/views/FieldDecorationView.js +++ b/core/modules/edit/js/views/FieldDecorationView.js @@ -7,10 +7,16 @@ "use strict"; -Drupal.edit.FieldDecorationView = Backbone.View.extend({ +Drupal.edit.FieldDecorationView = Backbone.View.extend(/** @lends Drupal.edit.FieldDecorationView# */ { + /** + * @type {?Boolean} + */ _widthAttributeIsEmpty: null, + /** + * @type {Object} + */ events: { 'mouseenter.edit' : 'onMouseEnter', 'mouseleave.edit' : 'onMouseLeave', @@ -20,13 +26,15 @@ Drupal.edit.FieldDecorationView = Backbone.View.extend({ }, /** - * {@inheritdoc} - * - * @param Object options - * An object with the following keys: - * - Drupal.edit.EditorView editorView: the editor object view. + * @constructs Drupal.edit.FieldDecorationView + * @augments Backbone.View + * @param {Object} options + * @param {Drupal.edit.EditorView} options.editorView the editor object view. */ initialize: function (options) { + /** + * @type {Drupal.edit.EditorView} + */ this.editorView = options.editorView; this.listenTo(this.model, 'change:state', this.stateChange); @@ -34,7 +42,7 @@ Drupal.edit.FieldDecorationView = Backbone.View.extend({ }, /** - * {@inheritdoc} + * @method */ remove: function () { // The el property is the field, which should not be removed. Remove the @@ -46,8 +54,8 @@ Drupal.edit.FieldDecorationView = Backbone.View.extend({ /** * Determines the actions to take given a change of state. * - * @param Drupal.edit.FieldModel model - * @param String state + * @param {Drupal.edit.FieldModel} model + * @param {String} state * The state of the associated field. One of Drupal.edit.FieldModel.states. */ stateChange: function (model, state) { @@ -108,7 +116,7 @@ Drupal.edit.FieldDecorationView = Backbone.View.extend({ /** * Starts hover; transitions to 'highlight' state. * - * @param jQuery event + * @param {Event} event */ onMouseEnter: function (event) { var that = this; @@ -119,7 +127,7 @@ Drupal.edit.FieldDecorationView = Backbone.View.extend({ /** * Stops hover; transitions to 'candidate' state. * - * @param jQuery event + * @param {Event} event */ onMouseLeave: function (event) { var that = this; @@ -130,7 +138,7 @@ Drupal.edit.FieldDecorationView = Backbone.View.extend({ /** * Transition to 'activating' stage. * - * @param jQuery event + * @param {Event} event */ onClick: function (event) { this.model.set('state', 'activating'); @@ -292,7 +300,7 @@ Drupal.edit.FieldDecorationView = Backbone.View.extend({ /** * Gets the background color of an element (or the inherited one). * - * @param DOM $e + * @param {HTMLElement} $e */ _getBgColor: function ($e) { var c; @@ -316,7 +324,7 @@ Drupal.edit.FieldDecorationView = Backbone.View.extend({ * Convert extraneous values and information into numbers ready for * subtraction. * - * @param DOM $e + * @param {HTMLElement} $e */ _getPositionProperties: function ($e) { var p, @@ -336,10 +344,10 @@ Drupal.edit.FieldDecorationView = Backbone.View.extend({ }, /** - * Replaces blank or 'auto' CSS "position: " values with "0px". + * Replaces blank or `auto` CSS `position: ` values with `0px`. * - * @param String pos - * (optional) The value for a CSS position declaration. + * @param {String} [pos] + * The value for a CSS position declaration. */ _replaceBlankPosition: function (pos) { if (pos === 'auto' || !pos) { diff --git a/core/modules/edit/js/views/FieldToolbarView.js b/core/modules/edit/js/views/FieldToolbarView.js index 67e567a..def7e9c 100644 --- a/core/modules/edit/js/views/FieldToolbarView.js +++ b/core/modules/edit/js/views/FieldToolbarView.js @@ -7,18 +7,31 @@ "use strict"; -Drupal.edit.FieldToolbarView = Backbone.View.extend({ +Drupal.edit.FieldToolbarView = Backbone.View.extend(/** @lends Drupal.edit.FieldToolbarView# */ { - // The edited element, as indicated by EditorView.getEditedElement(). + /** + * The edited element, as indicated by EditorView.getEditedElement(). + * @type {jQueryObject} + */ $editedElement: null, - // A reference to the in-place editor. + /** + * A reference to the in-place editor. + * @type {Drupal.edit.EditorView} + */ editorView: null, + /** + * @type {String} + */ _id: null, /** - * {@inheritdoc} + * @constructs Drupal.edit.FieldToolbarView + * @augments Backbone.View + * @param {Object} options + * @param {jQueryObject} options.$editedElement + * @param {Drupal.edit.EditorView} options.editorView */ initialize: function (options) { this.$editedElement = options.$editedElement; @@ -32,7 +45,7 @@ Drupal.edit.FieldToolbarView = Backbone.View.extend({ }, /** - * {@inheritdoc} + * @method */ render: function () { // Render toolbar and set it as the view's element. @@ -49,8 +62,8 @@ Drupal.edit.FieldToolbarView = Backbone.View.extend({ /** * Determines the actions to take given a change of state. * - * @param Drupal.edit.FieldModel model - * @param String state + * @param {Drupal.edit.FieldModel} model + * @param {String} state * The state of the associated field. One of Drupal.edit.FieldModel.states. */ stateChange: function (model, state) { @@ -120,7 +133,7 @@ Drupal.edit.FieldToolbarView = Backbone.View.extend({ * * 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 +145,7 @@ Drupal.edit.FieldToolbarView = Backbone.View.extend({ * * 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 +157,7 @@ Drupal.edit.FieldToolbarView = Backbone.View.extend({ * * 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 +167,9 @@ Drupal.edit.FieldToolbarView = Backbone.View.extend({ /** * Finds a toolgroup. * - * @param String toolgroup + * @param {String} toolgroup * A toolgroup name. - * @return jQuery + * @return {jQuery} */ _find: function (toolgroup) { return this.$el.find('.edit-toolgroup.' + toolgroup); @@ -165,7 +178,7 @@ Drupal.edit.FieldToolbarView = Backbone.View.extend({ /** * Shows a toolgroup. * - * @param String toolgroup + * @param {String} toolgroup * A toolgroup name. */ show: function (toolgroup) { diff --git a/core/modules/editor/js/editor.admin.js b/core/modules/editor/js/editor.admin.js index ab0c714..7b037df 100644 --- a/core/modules/editor/js/editor.admin.js +++ b/core/modules/editor/js/editor.admin.js @@ -7,10 +7,13 @@ * to automatically adjust their settings based on the editor configuration. */ -(function ($, _, Drupal, document) { +(function ($, _, Drupal) { "use strict"; +/** + * @namespace + */ Drupal.editorConfiguration = { /** @@ -20,7 +23,7 @@ Drupal.editorConfiguration = { * 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. */ addedFeature: function (feature) { @@ -34,7 +37,7 @@ Drupal.editorConfiguration = { * 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. */ removedFeature: function (feature) { @@ -45,13 +48,13 @@ Drupal.editorConfiguration = { * 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 tag instead - * of the tag. + * For example when the "Bold" button is configured to use the `` tag instead + * of the `` 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. */ modifiedFeature: function (feature) { @@ -69,11 +72,11 @@ Drupal.editorConfiguration = { * 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 {Boolean} * Whether the given feature is allowed by the current filters. */ featureIsAllowedByFilters: function (feature) { @@ -83,6 +86,7 @@ Drupal.editorConfiguration = { * feature's rules' requirements. * * This generates an object of this form: + * * var universe = { * a: { * 'touchedByAllowedPropertyRule': false, @@ -119,8 +123,8 @@ Drupal.editorConfiguration = { * applying "allowed tag property value" restrictions for this particular * tag. * - * @see findPropertyValueOnTag() - * @see filterStatusAllowsFeature() + * @see findPropertyValueOnTag + * @see filterStatusAllowsFeature */ function generateUniverseFromFeatureRequirements (feature) { var properties = ['attributes', 'styles', 'classes']; @@ -383,7 +387,7 @@ Drupal.editorConfiguration = { * by building the universe of potential values from the feature's require- * ments and then checking whether anything in the filter prevents that. * - * @see generateUniverseFromFeatureRequirements() + * @see generateUniverseFromFeatureRequirements */ function filterStatusAllowsFeature (filterStatus, feature) { // An inactive filter by definition allows the feature. @@ -489,23 +493,24 @@ Drupal.editorConfiguration = { /** * A text editor feature object. Initialized with the feature name. * - * Contains a set of HTML rules (Drupal.EditorFeatureHTMLRule objects) that + * 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). * * 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 tag, + * cases. For example: a "table" feature would probably require the `
    ` tag, * and might allow for e.g. the "summary" attribute on that tag. However, the - * table feature would also require the and ` and `
    tags, but it doesn't make + * table feature would also require the `
    ` 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 + * HTML rules must be added with the `addHTMLRule()` method. A feature that has * zero HTML rules does not create or modify HTML. * - * @param String name + * @constructor + * @param {String} name * The name of the feature. * * @see Drupal.EditorFeatureHTMLRule @@ -518,7 +523,7 @@ Drupal.EditorFeature = function (name) { /** * 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) { @@ -527,9 +532,10 @@ Drupal.EditorFeature.prototype.addHTMLRule = function (rule) { /** * Constructor for an editor feature HTML rule. Intended to be used in - * combination with Drupal.EditorFeature. + * 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 @@ -544,10 +550,12 @@ Drupal.EditorFeature.prototype.addHTMLRule = function (rule) { * representation instead of the Drupal-defined representation for HTML rules. * * Examples: - * - tags: [''] - * - attributes: ['href', 'alt'] - * - styles: ['color', 'text-decoration'] - * - classes: ['external', 'internal'] + * + * - tags: `['']` + * - attributes: `['href', 'alt']` + * - styles: `['color', 'text-decoration']` + * - classes: `['external', 'internal']` + * @constructor */ Drupal.EditorFeatureHTMLRule = function () { this.required = { tags: [], attributes: [], styles: [], classes: [] }; @@ -571,7 +579,8 @@ Drupal.EditorFeatureHTMLRule = function () { * 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 @@ -585,7 +594,7 @@ Drupal.FilterStatus = function (name) { /** * 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) { @@ -597,6 +606,7 @@ Drupal.FilterStatus.prototype.addHTMLRule = function (rule) { * Drupal.FilterStatus. * * 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. @@ -604,6 +614,7 @@ Drupal.FilterStatus.prototype.addHTMLRule = function (rule) { * 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 @@ -613,39 +624,46 @@ Drupal.FilterStatus.prototype.addHTMLRule = function (rule) { * "allowed" subkey to whitelist specific property values, and similarly use * the "forbidden" subkey to blacklist specific property values. * - * 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. - * { + * + * @example + * // Whitelist the "p", "strong" and "a" HTML tags: + * { + * tags: ['p', 'strong', 'a'], + * allow: true, + * restrictedTags: { * tags: [], - * allow: null, - * restrictedTags: { - * tags: ['a'], - * allowed: { attributes: ['href'], styles: [], classes: ['external'] }, - * forbidden: { attributes: ['target'], styles: [], classes: [] } - * } + * allowed: { attributes: [], styles: [], classes: [] }, + * forbidden: { attributes: [], 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: [] } - * } + * } + * + * @example + * // 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: [] } * } + * } + * + * @example + * // 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: [] } + * } + * } + * + * @constructor */ Drupal.FilterHTMLRule = function () { return { @@ -663,7 +681,8 @@ Drupal.FilterHTMLRule = function () { /** * Tracks the configuration of all text filters in Drupal.FilterStatus objects - * for Drupal.editorConfiguration.featureIsAllowedByFilters(). + * for {@linkto Drupal.editorConfiguration.featureIsAllowedByFilters}. + * @namespace */ Drupal.filterConfiguration = { @@ -677,8 +696,9 @@ Drupal.filterConfiguration = { * 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 Drupal.FilterHTMLRule objects. + * form and implement `Drupal.filterSettings[filterID].getRules()`, which should + * return an array of `Drupal.FilterHTMLRule` objects. + * @namespace */ liveSettingParsers: {}, @@ -709,6 +729,7 @@ Drupal.filterConfiguration = { /** * Initializes Drupal.filterConfiguration. + * @type {Behavior} */ Drupal.behaviors.initializeFilterConfiguration = { attach: function (context, settings) { @@ -729,4 +750,4 @@ Drupal.behaviors.initializeFilterConfiguration = { } }; -})(jQuery, _, Drupal, document); +})(jQuery, _, Drupal); diff --git a/core/modules/editor/js/editor.dialog.js b/core/modules/editor/js/editor.dialog.js index 35dd4be..63026ed 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. */ diff --git a/core/modules/editor/js/editor.formattedTextEditor.js b/core/modules/editor/js/editor.formattedTextEditor.js index 19439b9..baee796 100644 --- a/core/modules/editor/js/editor.formattedTextEditor.js +++ b/core/modules/editor/js/editor.formattedTextEditor.js @@ -8,28 +8,41 @@ * For example, assuming that a hypothetical editor's name was "Magical Editor" * and its editor.js API implementation lived at Drupal.editors.magical, this * JavaScript would use: - * - Drupal.editors.magical.attachInlineEditor() + * + * - `Drupal.editors.magical.attachInlineEditor()` */ (function ($, Drupal, drupalSettings) { "use strict"; -Drupal.edit.editors.editor = Drupal.edit.EditorView.extend({ +Drupal.edit.editors.editor = Drupal.edit.EditorView.extend(/** @lends Drupal.edit.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 {?Boolean} + */ 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 {?*} + */ 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 {?jQueryObject} + */ $textElement: null, /** - * {@inheritdoc} + * @constructs Drupal.edit.editors.editor */ initialize: function (options) { Drupal.edit.EditorView.prototype.initialize.call(this, options); @@ -46,14 +59,14 @@ Drupal.edit.editors.editor = Drupal.edit.EditorView.extend({ }, /** - * {@inheritdoc} + * @method */ getEditedElement: function () { return this.$textElement; }, /** - * {@inheritdoc} + * @method */ stateChange: function (fieldModel, state) { var editorModel = this.model; @@ -135,14 +148,14 @@ Drupal.edit.editors.editor = Drupal.edit.EditorView.extend({ }, /** - * {@inheritdoc} + * @method */ getEditUISettings: function () { return { padding: true, unifiedToolbar: true, fullWidthToolbar: true, popup: false }; }, /** - * {@inheritdoc} + * @method */ revert: function () { this.$textElement.html(this.model.get('originalValue')); @@ -154,7 +167,7 @@ Drupal.edit.editors.editor = Drupal.edit.EditorView.extend({ * More accurately: it re-processes processed 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 62733f4..182f19b 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 {jQueryObject} $formatSelector * A text format selector DOM element. * - * @return DOM + * @return {DOM} * The text area DOM element. */ function findFieldForFormatSelector ($formatSelector) { @@ -24,12 +24,12 @@ function findFieldForFormatSelector ($formatSelector) { /** * Changes the text editor on the text area for the given text format selector. * - * @param jQuery $formatSelector + * @param {jQueryObject} $formatSelector * A text format selector DOM element. - * @param String activeFormatID + * @param {String} activeFormatID * The currently active text format; its associated text editor will be * detached. - * @param String newFormatID + * @param {String} newFormatID * The text format we're changing to; its associated text editor will be * attached. */ @@ -49,7 +49,7 @@ function changeTextEditor ($formatSelector, activeFormatID, newFormatID) { /** * Handles changes in text format. * - * @param jQuery.Event event + * @param {Event} event */ function onTextFormatChange (event) { var $select = $(event.target); @@ -116,11 +116,13 @@ function onTextFormatChange (event) { /** * Initialize an empty object for editors to place their attachment code. + * @namespace */ Drupal.editors = {}; /** * Enables editors on text_format elements. + * @type {Behavior} */ Drupal.behaviors.editor = { attach: function (context, settings) { @@ -182,6 +184,10 @@ Drupal.behaviors.editor = { } }; +/** + * @param {Object} field + * @param {Object} format + */ Drupal.editorAttach = function (field, format) { if (format.editor) { // HTML5 validation cannot ever work for WYSIWYG editors, because WYSIWYG @@ -204,6 +210,12 @@ Drupal.editorAttach = function (field, format) { } }; +/** + * + * @param {Object} field + * @param {Object} format + * @param {String} trigger + */ Drupal.editorDetach = function (field, format, trigger) { if (format.editor) { // Restore the HTML5 validation "required" attribute if it was removed in diff --git a/core/modules/field_ui/field_ui.js b/core/modules/field_ui/field_ui.js index 9297462..fbced73 100644 --- a/core/modules/field_ui/field_ui.js +++ b/core/modules/field_ui/field_ui.js @@ -7,6 +7,9 @@ "use strict"; +/** + * @type {Behavior} + */ Drupal.behaviors.fieldUIDisplayOverview = { attach: function (context, settings) { $(context).find('table#field-display-overview').once('field-display-overview', function() { @@ -15,9 +18,15 @@ Drupal.behaviors.fieldUIDisplayOverview = { } }; +/** + * @namespace + */ Drupal.fieldUIOverview = { /** * Attaches the fieldUIOverview behavior. + * @param {HTMLElement} table + * @param {*} rowsData + * @param {*} rowHandlers */ attach: function (table, rowsData, rowHandlers) { var tableDrag = Drupal.tableDrag[table.id]; @@ -93,11 +102,7 @@ Drupal.fieldUIOverview = { /** * Refreshes placeholder rows in empty regions while a row is being dragged. * - * Copied from block.js. - * - * @param table - * The table DOM element. - * @param rowObject + * @param {HTMLElement} draggedRow * The tableDrag rowObject for the row being dragged. */ onSwap: function (draggedRow) { @@ -130,7 +135,7 @@ Drupal.fieldUIOverview = { * The #ajax behavior is therefore not attached directly to the selects, but * triggered manually through a hidden #ajax 'Refresh' button. * - * @param rows + * @param {Object} rows * A hash object, whose keys are the names of the rows to refresh (they * will receive the 'ajax-new-content' effect on the server side), and * whose values are the DOM element in the row that should get an Ajax @@ -169,6 +174,7 @@ Drupal.fieldUIOverview = { /** * Row handlers for the 'Manage display' screen. + * @namespace */ Drupal.fieldUIDisplayOverview = {}; @@ -177,9 +183,10 @@ Drupal.fieldUIDisplayOverview = {}; * * This handler is used for both fields and 'extra fields' rows. * - * @param row + * @constructor + * @param {HTMLElement} row * The row DOM element. - * @param data + * @param {Object} data * Additional data to be populated in the constructed object. */ Drupal.fieldUIDisplayOverview.field = function (row, data) { @@ -208,17 +215,18 @@ Drupal.fieldUIDisplayOverview.field.prototype = { * * This function is called when the row is moved to a different region, as a * result of either : + * * - a drag-and-drop action (the row's form elements then probably need to be * updated accordingly) * - user input in one of the form elements watched by the - * Drupal.fieldUIOverview.onChange change listener. + * `Drupal.fieldUIOverview.onChange` change listener. * - * @param region + * @param {String} region * The name of the new region for the row. - * @return + * @return {Object} * A hash object indicating which rows should be Ajax-updated as a result * of the change, in the format expected by - * Drupal.displayOverview.AJAXRefreshRows(). + * {@link Drupal.displayOverview.AJAXRefreshRows} */ regionChange: function (region) { diff --git a/core/modules/file/file.js b/core/modules/file/file.js index 89f46c1..c32d97c 100644 --- a/core/modules/file/file.js +++ b/core/modules/file/file.js @@ -13,6 +13,7 @@ /** * Attach behaviors to managed file element upload fields. + * @type {Behavior} */ Drupal.behaviors.fileValidateAutoAttach = { attach: function (context, settings) { @@ -45,6 +46,7 @@ Drupal.behaviors.fileValidateAutoAttach = { /** * Attach behaviors to managed file element upload fields. + * @type {Behavior} */ Drupal.behaviors.fileAutoUpload = { attach: function (context) { @@ -59,6 +61,7 @@ Drupal.behaviors.fileAutoUpload = { /** * Attach behaviors to the file upload and remove buttons. + * @type {Behavior} */ Drupal.behaviors.fileButtons = { attach: function (context) { @@ -75,6 +78,7 @@ Drupal.behaviors.fileButtons = { /** * Attach behaviors to links within managed file elements. + * @type {Behavior} */ Drupal.behaviors.filePreviewLinks = { attach: function (context) { @@ -87,10 +91,12 @@ Drupal.behaviors.filePreviewLinks = { /** * File upload utility functions. + * @namespace */ -Drupal.file = Drupal.file || { +Drupal.file = { /** * Client-side file input validation of file extensions. + * @param {Event} event */ validateExtension: function (event) { event.preventDefault(); @@ -120,12 +126,14 @@ Drupal.file = Drupal.file || { }, /** * Trigger the upload_button mouse event to auto-upload as a managed file. + * @param {Event} event */ triggerUploadButton: function (event){ $(event.target).closest('.form-managed-file').find('.form-submit').trigger('mousedown'); }, /** * Prevent file uploads when using buttons not intended to upload. + * @param {Event} event */ disableFields: function (event){ var $clickedButton = $(this); @@ -157,6 +165,7 @@ Drupal.file = Drupal.file || { }, /** * Add progress bar support if possible. + * @param {Event} event */ progressBar: function (event) { var $clickedButton = $(this); @@ -179,6 +188,7 @@ Drupal.file = Drupal.file || { }, /** * Open links to files within forms in a new window. + * @param {Event} event */ openInNewWindow: function (event) { event.preventDefault(); diff --git a/core/modules/filter/filter.admin.js b/core/modules/filter/filter.admin.js index cde65a5..f904a4f 100644 --- a/core/modules/filter/filter.admin.js +++ b/core/modules/filter/filter.admin.js @@ -7,6 +7,9 @@ "use strict"; +/** + * @type {Behavior} + */ Drupal.behaviors.filterStatus = { attach: function (context, settings) { var $context = $(context); diff --git a/core/modules/filter/filter.filter_html.admin.js b/core/modules/filter/filter.filter_html.admin.js index ba256f0..9a3bc26 100644 --- a/core/modules/filter/filter.filter_html.admin.js +++ b/core/modules/filter/filter.filter_html.admin.js @@ -12,7 +12,13 @@ * enabling buttons that are not allowed by this filter's configuration. */ if (Drupal.filterConfiguration) { + /** + * @type {Object} + */ Drupal.filterConfiguration.liveSettingParsers.filter_html = { + /** + * @return {Array.} + */ getRules: function () { var currentValue = $('#edit-filters-filter-html-settings-allowed-html').val(); var rules = [], rule; @@ -35,7 +41,11 @@ if (Drupal.filterConfiguration) { } }; } - +/** + * + * @todo remove everything from the behavior object. + * @type {Behavior} + */ Drupal.behaviors.filterFilterHtmlUpdating = { // The form item containg the "Allowed HTML tags" setting. @@ -113,12 +123,12 @@ Drupal.behaviors.filterFilterHtmlUpdating = { * The filter_html filter is only concerned with the required tags, not with * any properties, nor with each feature's "allowed" tags. * - * @param Array userAllowedTags + * @param {Array} userAllowedTags * The list of user-defined allowed tags. - * @param Object newFeatures + * @param {Object} newFeatures * A list of Drupal.EditorFeature objects' rules, keyed by their name. * - * @return Array + * @return {Array} * A list of new allowed tags. */ _calculateAutoAllowedTags: function (userAllowedTags, newFeatures) { @@ -140,10 +150,10 @@ Drupal.behaviors.filterFilterHtmlUpdating = { /** * Parses the value of this.$allowedHTMLFormItem. * - * @param String setting + * @param {String} setting * The string representation of the setting. e.g. "


    " * - * @return Array + * @return {Array} * The array representation of the setting. e.g. ['p', 'br', 'a'] */ _parseSetting: function (setting) { @@ -153,10 +163,10 @@ Drupal.behaviors.filterFilterHtmlUpdating = { /** * Generates the value of this.$allowedHTMLFormItem. * - * @param Array setting + * @param {Array} setting * The array representation of the setting. e.g. ['p', 'br', 'a'] * - * @return Array + * @return {Array} * The string representation of the setting. e.g. "


    " */ _generateSetting: function (tags) { @@ -168,9 +178,9 @@ Drupal.behaviors.filterFilterHtmlUpdating = { /** * Theme function for the filter_html update message. * - * @param Array tags + * @param {Array} tags * An array of the new tags that are to be allowed. - * @return + * @return {String} * The corresponding HTML. */ Drupal.theme.filterFilterHTMLUpdateMessage = function (tags) { diff --git a/core/modules/filter/filter.js b/core/modules/filter/filter.js index 2bab50b..d7f43c7 100644 --- a/core/modules/filter/filter.js +++ b/core/modules/filter/filter.js @@ -9,6 +9,7 @@ /** * Displays the guidelines of the selected text format automatically. + * @type {Behavior} */ Drupal.behaviors.filterGuidelines = { attach: function (context) { diff --git a/core/modules/history/js/history.js b/core/modules/history/js/history.js index 4fab216..1ae7972 100644 --- a/core/modules/history/js/history.js +++ b/core/modules/history/js/history.js @@ -1,4 +1,5 @@ /** + * @file * JavaScript API for the History module, with client-side caching. * * May only be loaded for authenticated users, with the History module enabled. @@ -19,14 +20,17 @@ if (drupalSettings.history && drupalSettings.history.lastReadTimestamps) { embeddedLastReadTimestamps = drupalSettings.history.lastReadTimestamps; } +/** + * @namespace + */ Drupal.history = { /** * Fetch "last read" timestamps for the given nodes. * - * @param Array nodeIDs + * @param {Array} nodeIDs * An array of node IDs. - * @param Function callback + * @param {Function} callback * A callback that is called after the requested timestamps were fetched. */ fetchTimestamps: function (nodeIDs, callback) { @@ -55,10 +59,10 @@ Drupal.history = { /** * Get the last read timestamp for the given node. * - * @param Number|String nodeID + * @param {Number|String} nodeID * A node ID. * - * @return Number + * @return {Number} * A UNIX timestamp. */ getLastRead: function (nodeID) { @@ -72,7 +76,7 @@ Drupal.history = { /** * Marks a node as read, store the last read timestamp in client-side storage. * - * @param Number|String nodeID + * @param {Number|String} nodeID * A node ID. */ markAsRead: function (nodeID) { @@ -98,12 +102,12 @@ Drupal.history = { * Any content that was published before the oldest known reading also never * gets a "new" or "updated" indicator, because it must've been read already. * - * @param Number|String nodeID + * @param {Number|String} nodeID * A node ID. - * @param Number contentTimestamp + * @param {Number} contentTimestamp * The time at which some content (e.g. a comment) was published. * - * @return Boolean + * @return {Boolean} * Whether a server check is necessary for the given node and its timestamp. */ needsServerCheck: function (nodeID, contentTimestamp) { diff --git a/core/modules/language/language.admin.js b/core/modules/language/language.admin.js index 41623cf..a66d956 100644 --- a/core/modules/language/language.admin.js +++ b/core/modules/language/language.admin.js @@ -4,6 +4,7 @@ /** * Makes language negotiation inherit user interface negotiation. + * @type {Behavior} */ Drupal.behaviors.negotiationLanguage = { attach: function () { diff --git a/core/modules/locale/locale.admin.js b/core/modules/locale/locale.admin.js index f5d8cf2..5b75493 100644 --- a/core/modules/locale/locale.admin.js +++ b/core/modules/locale/locale.admin.js @@ -1,9 +1,13 @@ +/** + * @file + */ (function ($, Drupal) { "use strict"; /** * Marks changes of translations + * @type {Behavior} */ Drupal.behaviors.localeTranslateDirty = { attach: function () { @@ -42,6 +46,7 @@ Drupal.behaviors.localeTranslateDirty = { /** * Show/hide the description details on Available translation updates page. + * @type {Behavior} */ Drupal.behaviors.hideUpdateInformation = { attach: function (context, settings) { @@ -75,9 +80,19 @@ Drupal.behaviors.hideUpdateInformation = { }; $.extend(Drupal.theme, { + /** + * @function + * @name Drupal.theme.localeTranslateChangedMarker + * @return {String} + */ localeTranslateChangedMarker: function () { return '*'; }, + /** + * @function + * @name Drupal.theme.localeTranslateChangedWarning + * @return {String} + */ localeTranslateChangedWarning: function () { return '

    '; } diff --git a/core/modules/locale/locale.bulk.js b/core/modules/locale/locale.bulk.js index eec2837..4e4f2d9 100644 --- a/core/modules/locale/locale.bulk.js +++ b/core/modules/locale/locale.bulk.js @@ -1,3 +1,6 @@ +/** + * @file + */ (function ($, Drupal) { "use strict"; @@ -6,6 +9,7 @@ * Select the language code of an imported file based on its filename. * * This only works if the file name ends with "LANGCODE.po". + * @type {Behavior} */ Drupal.behaviors.importLanguageCodeSelector = { attach: function (context, settings) { diff --git a/core/modules/locale/locale.datepicker.js b/core/modules/locale/locale.datepicker.js index b23e57d..8a6b41d 100644 --- a/core/modules/locale/locale.datepicker.js +++ b/core/modules/locale/locale.datepicker.js @@ -9,6 +9,7 @@ /** * Attaches language support to the jQuery UI datepicker component. + * @type {Behavior} */ Drupal.behaviors.localeDatepicker = { attach: function(context, settings) { diff --git a/core/modules/locale/tests/locale_test.js b/core/modules/locale/tests/locale_test.js index d29680d..023e8b3 100644 --- a/core/modules/locale/tests/locale_test.js +++ b/core/modules/locale/tests/locale_test.js @@ -1,4 +1,5 @@ /** + * @ignore * @file * JavaScript for locale_test.module. */ diff --git a/core/modules/menu/menu.admin.js b/core/modules/menu/menu.admin.js index 8512971..87e2472 100644 --- a/core/modules/menu/menu.admin.js +++ b/core/modules/menu/menu.admin.js @@ -1,7 +1,13 @@ +/** + * @file + */ (function ($) { "use strict"; +/** + * @type {Behavior} + */ Drupal.behaviors.menuChangeParentItems = { attach: function (context, settings) { var $menu = $('#edit-menu'); diff --git a/core/modules/menu/menu.js b/core/modules/menu/menu.js index c9e14b5..eb7761f 100644 --- a/core/modules/menu/menu.js +++ b/core/modules/menu/menu.js @@ -1,7 +1,13 @@ +/** + * @file + */ (function ($) { "use strict"; +/** + * @type {Behavior} + */ Drupal.behaviors.menuDetailsSummaries = { attach: function (context) { $(context).find('.menu-link-form').drupalSetSummary(function (context) { @@ -18,6 +24,7 @@ Drupal.behaviors.menuDetailsSummaries = { /** * Automatically fill in a menu link title, if possible. + * @type {Behavior} */ Drupal.behaviors.menuLinkAutomaticTitle = { attach: function (context) { diff --git a/core/modules/node/content_types.js b/core/modules/node/content_types.js index f6a545b..8db10ae 100644 --- a/core/modules/node/content_types.js +++ b/core/modules/node/content_types.js @@ -6,7 +6,9 @@ (function ($) { "use strict"; - +/** + * @type {Behavior} + */ Drupal.behaviors.contentTypes = { attach: function (context) { var $context = $(context); diff --git a/core/modules/node/node.js b/core/modules/node/node.js index f0b5a38..dbf4cf2 100644 --- a/core/modules/node/node.js +++ b/core/modules/node/node.js @@ -7,6 +7,9 @@ "use strict"; +/** + * @type {Behavior} + */ Drupal.behaviors.nodeDetailsSummaries = { attach: function (context) { var $context = $(context); diff --git a/core/modules/node/node.preview.js b/core/modules/node/node.preview.js index 3be74e2..433e5ab 100644 --- a/core/modules/node/node.preview.js +++ b/core/modules/node/node.preview.js @@ -5,6 +5,7 @@ /** * Disabling all links (except local fragment identifiers such as href="#frag") * in node previews to prevent users from leaving the page. + * @type {Behavior} */ Drupal.behaviors.nodePreviewDestroyLinks = { attach: function (context) { diff --git a/core/modules/path/path.js b/core/modules/path/path.js index 7349d12..d8af9b7 100644 --- a/core/modules/path/path.js +++ b/core/modules/path/path.js @@ -6,6 +6,9 @@ "use strict"; +/** + * @type {Behavior} + */ Drupal.behaviors.pathDetailsSummaries = { attach: function (context) { $(context).find('.path-form').drupalSetSummary(function (context) { diff --git a/core/modules/shortcut/shortcut.admin.js b/core/modules/shortcut/shortcut.admin.js index c95e4fd..d4656e3 100644 --- a/core/modules/shortcut/shortcut.admin.js +++ b/core/modules/shortcut/shortcut.admin.js @@ -5,6 +5,7 @@ /** * Make it so when you enter text into the "New set" textfield, the * corresponding radio button gets selected. + * @type {Behavior} */ Drupal.behaviors.newSet = { attach: function (context, settings) { diff --git a/core/modules/simpletest/simpletest.js b/core/modules/simpletest/simpletest.js index aa422ed..2fd538d 100644 --- a/core/modules/simpletest/simpletest.js +++ b/core/modules/simpletest/simpletest.js @@ -4,6 +4,7 @@ /** * Add the cool table collapsing on the testing overview page. + * @type {Behavior} */ Drupal.behaviors.simpleTestMenuCollapse = { attach: function (context) { @@ -60,6 +61,7 @@ Drupal.behaviors.simpleTestMenuCollapse = { /** * Select/deselect all the inner checkboxes when the outer checkboxes are * selected/deselected. + * @type {Behavior} */ Drupal.behaviors.simpleTestSelectAll = { attach: function (context) { @@ -108,6 +110,7 @@ Drupal.behaviors.simpleTestSelectAll = { * Text search input: input.table-filter-text * Target table: input.table-filter-text[data-table] * Source text: .table-filter-text-source + * @type {Behavior} */ Drupal.behaviors.simpletestTableFilterByText = { attach: function (context) { diff --git a/core/modules/statistics/statistics.js b/core/modules/statistics/statistics.js index 5d66655..653ee62 100644 --- a/core/modules/statistics/statistics.js +++ b/core/modules/statistics/statistics.js @@ -1,3 +1,6 @@ +/** + * @file + */ (function ($, Drupal, drupalSettings) { "use strict"; diff --git a/core/modules/system/system.js b/core/modules/system/system.js index 18f7e7a..26c43da 100644 --- a/core/modules/system/system.js +++ b/core/modules/system/system.js @@ -1,3 +1,6 @@ +/** + * @file + */ (function ($, Drupal, drupalSettings) { "use strict"; @@ -9,6 +12,7 @@ var ids = []; * When a field is filled out, apply its value to other fields that will likely * use the same value. In the installer this is used to populate the * administrator e-mail address with the same value as the site e-mail address. + * @type {Behavior} */ Drupal.behaviors.copyFieldValue = { attach: function (context) { @@ -37,9 +41,9 @@ Drupal.behaviors.copyFieldValue = { /** * Event handler that fill the target element with the specified value. * - * @param e + * @param {Event} e * Event object. - * @param value + * @param {String} value * Custom value from jQuery trigger. */ valueTargetCopyHandler: function (e, value) { diff --git a/core/modules/system/system.modules.js b/core/modules/system/system.modules.js index 4d97652..e6fbd22 100644 --- a/core/modules/system/system.modules.js +++ b/core/modules/system/system.modules.js @@ -11,6 +11,7 @@ * Text search input: input.table-filter-text * Target table: input.table-filter-text[data-table] * Source text: .table-filter-text-source + * @type {Behavior} */ Drupal.behaviors.tableFilterByText = { attach: function (context, settings) { diff --git a/core/modules/system/tests/modules/common_test/js/shorthand.js b/core/modules/system/tests/modules/common_test/js/shorthand.js index 7f3b1d5..a3a6abd 100644 --- a/core/modules/system/tests/modules/common_test/js/shorthand.js +++ b/core/modules/system/tests/modules/common_test/js/shorthand.js @@ -1,4 +1,6 @@ /** + * @ignore + * @file * JavaScript file for the 'Shorthand' plugin. * * This file is intentionally blank. It is used to test that nominating diff --git a/core/modules/taxonomy/taxonomy.js b/core/modules/taxonomy/taxonomy.js index 19d42df..68a766f 100644 --- a/core/modules/taxonomy/taxonomy.js +++ b/core/modules/taxonomy/taxonomy.js @@ -1,3 +1,6 @@ +/** + * @file + */ (function ($) { "use strict"; @@ -7,6 +10,7 @@ * * This behavior is dependent on the tableDrag behavior, since it uses the * objects initialized in that behavior to update the row. + * @type {Behavior} */ Drupal.behaviors.termDrag = { attach: function (context, settings) { diff --git a/core/modules/text/text.js b/core/modules/text/text.js index 78a180a..96d36ed 100644 --- a/core/modules/text/text.js +++ b/core/modules/text/text.js @@ -1,9 +1,13 @@ +/** + * @file + */ (function ($) { "use strict"; /** * Auto-hide summary textarea if empty and show hide and unhide links. + * @type {Behavior} */ Drupal.behaviors.textSummary = { attach: function (context, settings) { diff --git a/core/modules/toolbar/js/escapeAdmin.js b/core/modules/toolbar/js/escapeAdmin.js index 72a9fb8..034e84c 100644 --- a/core/modules/toolbar/js/escapeAdmin.js +++ b/core/modules/toolbar/js/escapeAdmin.js @@ -23,6 +23,8 @@ if (!pathInfo.currentPathIsAdmin && !/destination=/.test(window.location.search) * * Back to site link points to the last non-administrative page the user visited * within the same browser tab. + * + * @type {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 0b05575..634ee95 100644 --- a/core/modules/toolbar/js/models/MenuModel.js +++ b/core/modules/toolbar/js/models/MenuModel.js @@ -9,9 +9,20 @@ /** * Backbone Model for collapsible menus. + * + * @constructor + * @augments Backbone.Model */ -Drupal.toolbar.MenuModel = Backbone.Model.extend({ +Drupal.toolbar.MenuModel = Backbone.Model.extend(/** @lends Drupal.toolbar.MenuModel# */ { + /** + * @type {Object} + */ defaults: { + /** + * @name Drupal.toolbar.MenuModel#subtrees + * @type {Object} + * @virtual + */ subtrees: {} } }); diff --git a/core/modules/toolbar/js/models/ToolbarModel.js b/core/modules/toolbar/js/models/ToolbarModel.js index 4384fbf..8d14fd4 100644 --- a/core/modules/toolbar/js/models/ToolbarModel.js +++ b/core/modules/toolbar/js/models/ToolbarModel.js @@ -9,43 +9,119 @@ /** * Backbone model for the toolbar. + * + * @constructor + * @augments Backbone.Model */ -Drupal.toolbar.ToolbarModel = Backbone.Model.extend({ +Drupal.toolbar.ToolbarModel = Backbone.Model.extend(/** @lends Drupal.toolbar.ToolbarModel# */ { + /** + * @type {Object} + */ 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'. + /** + * 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'. + * + * @name Drupal.toolbar.ToolbarModel#activeTab + * @type {HTMLElement} + * @virtual + */ 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'. + * + * @name Drupal.toolbar.ToolbarModel#activeTray + * @type {HTMLElement} + * @virtual + */ 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. + * + * @name Drupal.toolbar.ToolbarModel#isOriented + * @type {Boolean} + * @virtual + */ isOriented: false, - // Indicates whether the toolbar is positioned absolute (false) or fixed - // (true). + /** + * Indicates whether the toolbar is positioned absolute (false) or fixed + * (true). + * + * @name Drupal.toolbar.ToolbarModel#isFixed + * @type {Boolean} + * @virtual + */ 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. + * + * @name Drupal.toolbar.ToolbarModel#areSubtreesLoaded + * @type {Boolean} + * @virtual + */ 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. + * + * @name Drupal.toolbar.ToolbarModel#isViewportOverflowConstrained + * @type {Boolean} + * @virtual + */ isViewportOverflowConstrained: false, - // The orientation of the active tray. + /** + * The orientation of the active tray. + * + * @name Drupal.toolbar.ToolbarModel#orientation + * @type {String} + * @virtual + */ 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. + * + * @name Drupal.toolbar.ToolbarModel#locked + * @type {Boolean} + * @virtual + */ locked: false, - // Indicates whether the tray orientation toggle is visible. + /** + * Indicates whether the tray orientation toggle is visible. + * + * @name Drupal.toolbar.ToolbarModel#isTrayToggleVisible + * @type {Boolean} + * @virtual + */ isTrayToggleVisible: false, - // The height of the toolbar. + /** + * The height of the toolbar. + * + * @name Drupal.toolbar.ToolbarModel#height + * @type {Null|Number} + * @virtual + */ 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. + * + * @name Drupal.toolbar.ToolbarModel#offsets + * @type {Object} + * @prop {Number} top + * @prop {Number} right + * @prop {Number} bottom + * @prop {Number} left + * @virtual + */ offsets: { top: 0, right: 0, @@ -55,7 +131,9 @@ Drupal.toolbar.ToolbarModel = Backbone.Model.extend({ }, /** - * {@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 452abe7..f69e3b8 100644 --- a/core/modules/toolbar/js/toolbar.js +++ b/core/modules/toolbar/js/toolbar.js @@ -1,5 +1,5 @@ /** - * @file toolbar.js + * @file * * Defines the behavior of the Drupal administration toolbar. */ @@ -8,8 +8,7 @@ "use strict"; // Merge run-time settings with the defaults. -var options = $.extend( - { +var options = $.extend({ breakpoints: { 'module.toolbar.narrow': '', 'module.toolbar.standard': '', @@ -33,6 +32,8 @@ var options = $.extend( * directly to a resource or toggle the visibility of a tray. * * Modules register tabs with hook_toolbar(). + * + * @type {Behavior} */ Drupal.behaviors.toolbar = { @@ -129,16 +130,26 @@ Drupal.behaviors.toolbar = { /** * Toolbar methods of Backbone objects. + * @namespace */ Drupal.toolbar = { - // 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: {}, - // A hash of MediaQueryList objects tracked by the toolbar. + /** + * A hash of MediaQueryList objects tracked by the toolbar. + * @type {Object} + */ mql: {}, /** @@ -146,13 +157,15 @@ Drupal.toolbar = { * * A deferred object that is resolved by an inlined JavaScript callback. * - * JSONP callback. - * @see toolbar_subtrees_jsonp(). + * @type {jQuery.Deferred} */ setSubtrees: new $.Deferred(), /** * Respond to configured narrow media query changes. + * @param {Drupal.toolbar.ToolbarModel} model + * @param {String} label + * @param {matchMedia} mql */ mediaQueryChangeHandler: function (model, label, mql) { switch (label) { diff --git a/core/modules/toolbar/js/toolbar.menu.js b/core/modules/toolbar/js/toolbar.menu.js index 7e5c38a..1d57ff2 100644 --- a/core/modules/toolbar/js/toolbar.menu.js +++ b/core/modules/toolbar/js/toolbar.menu.js @@ -2,7 +2,8 @@ * Builds a nested accordion widget. * * Invoke on an HTML list element with the jQuery plugin pattern. - * - For example, $('.menu').drupalToolbarMenu(); + * + * - For example, `$('.menu').drupalToolbarMenu();` */ (function ($, Drupal, drupalSettings) { @@ -38,7 +39,7 @@ var activeItem = Drupal.url(drupalSettings.path.currentPath); /** * Toggle the open/close state of a list is a menu. * - * @param {jQuery} $item + * @param {jQueryObject} $item * The li item to be toggled. * * @param {Boolean} switcher @@ -66,7 +67,7 @@ var activeItem = Drupal.url(drupalSettings.path.currentPath); * classed with .toolbar-box. The .toolbar-box div provides a positioning * context for the item list toggle. * - * @param {jQuery} $menu + * @param {jQueryObject} $menu * The root of the menu to be initialized. */ function initItems ($menu) { @@ -94,7 +95,7 @@ var activeItem = Drupal.url(drupalSettings.path.currentPath); * This function is called recursively on each sub level of lists elements * until the depth of the menu is exhausted. * - * @param {jQuery} $lists + * @param {jQueryObject} $lists * A jQuery object of ul elements. * * @param {Integer} level @@ -114,7 +115,7 @@ var activeItem = Drupal.url(drupalSettings.path.currentPath); * Marks the trail of the active link in the menu back to the root of the * menu with .active-trail. * - * @param {jQuery} $menu + * @param {jQueryObject} $menu * The root of the menu. */ function openActiveItem ($menu) { diff --git a/core/modules/toolbar/js/views/BodyVisualView.js b/core/modules/toolbar/js/views/BodyVisualView.js index 515b363..0703cbe 100644 --- a/core/modules/toolbar/js/views/BodyVisualView.js +++ b/core/modules/toolbar/js/views/BodyVisualView.js @@ -2,25 +2,23 @@ * @file * A Backbone view for the body element. */ - (function ($, Drupal, Backbone) { "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 Drupal.toolbar.BodyVisualView + * @augments Backbone.View */ initialize: function () { this.listenTo(this.model, 'change:orientation change:offsets change:activeTray change:isOriented change:isFixed change:isViewportOverflowConstrained', this.render); }, /** - * {@inheritdoc} + * @method */ render: function () { var $body = $('body'); diff --git a/core/modules/toolbar/js/views/MenuVisualView.js b/core/modules/toolbar/js/views/MenuVisualView.js index 42ec983..86fd2fe 100644 --- a/core/modules/toolbar/js/views/MenuVisualView.js +++ b/core/modules/toolbar/js/views/MenuVisualView.js @@ -2,24 +2,23 @@ * @file * A Backbone view for the collapsible menus. */ - (function ($,Backbone, Drupal) { "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 Drupal.toolbar.MenuVisualView + * @augments Backbone.View */ initialize: function () { this.listenTo(this.model, 'change:subtrees', this.render); }, /** - * {@inheritdoc} + * @method */ 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 2f312e2..05d7e79 100644 --- a/core/modules/toolbar/js/views/ToolbarAuralView.js +++ b/core/modules/toolbar/js/views/ToolbarAuralView.js @@ -2,18 +2,18 @@ * @file * A Backbone view for the aural feedback of the toolbar. */ - (function (Backbone, Drupal) { "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 Drupal.toolbar.ToolbarAuralView + * @augments Backbone.View + * @param {Object} options + * @param {Object} options.strings */ initialize: function (options) { this.strings = options.strings; @@ -25,8 +25,8 @@ Drupal.toolbar.ToolbarAuralView = Backbone.View.extend({ /** * 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 +38,8 @@ Drupal.toolbar.ToolbarAuralView = Backbone.View.extend({ /** * Announces a changed active tray. * - * @param Drupal.Toolbar.ToolbarModel model - * @param Element orientation + * @param {Drupal.toolbar.ToolbarModel} model + * @param {Element} orientation * 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 be2264b..20a93f7 100644 --- a/core/modules/toolbar/js/views/ToolbarVisualView.js +++ b/core/modules/toolbar/js/views/ToolbarVisualView.js @@ -2,23 +2,29 @@ * @file * A Backbone view for the toolbar element. */ - (function ($, Drupal, drupalSettings, Backbone) { "use strict"; -/** - * Backbone view for the toolbar element. - */ -Drupal.toolbar.ToolbarVisualView = Backbone.View.extend({ +Drupal.toolbar.ToolbarVisualView = Backbone.View.extend(/** @lends Drupal.toolbar.ToolbarVisualView# */ { + /** + * @type {Object} + */ events: { 'click .toolbar-bar .toolbar-tab': 'onTabClick', 'click .toolbar-toggle-orientation button': 'onOrientationToggleClick' }, /** - * {@inheritdoc} + * Backbone view for the toolbar element. + * + * @constructs Drupal.toolbar.ToolbarVisualView + * @augments Backbone.View + * @param {Object} options + * @param {Object} options.strings + * @param {String} options.strings.vertical + * @param {String} options.strings.horizontal */ initialize: function (options) { this.strings = options.strings; @@ -27,7 +33,10 @@ Drupal.toolbar.ToolbarVisualView = Backbone.View.extend({ this.listenTo(this.model, 'change:mqMatches', this.onMediaQueryChange); this.listenTo(this.model, 'change:offsets', this.adjustPlacement); - // Add the tray orientation toggles. + /** + * Add the tray orientation toggles. + * @type {jQueryObject} + */ this.$el .find('.toolbar-tray .toolbar-lining') .append(Drupal.theme('toolbarOrientationToggle')); @@ -38,7 +47,7 @@ Drupal.toolbar.ToolbarVisualView = Backbone.View.extend({ }, /** - * {@inheritdoc} + * @method */ render: function () { this.updateTabs(); @@ -71,7 +80,7 @@ Drupal.toolbar.ToolbarVisualView = Backbone.View.extend({ /** * Responds to a toolbar tab click. * - * @param jQuery.Event event + * @param {Event} event */ onTabClick: function (event) { // If this tab has a tray associated with it, it is considered an @@ -90,7 +99,7 @@ Drupal.toolbar.ToolbarVisualView = Backbone.View.extend({ /** * Toggles the orientation of a toolbar tray. * - * @param jQuery.Event event + * @param {Event} event */ onOrientationToggleClick: function (event) { var orientation = this.model.get('orientation'); diff --git a/core/modules/tour/js/tour.js b/core/modules/tour/js/tour.js index 0f7a8fd..be4c90a 100644 --- a/core/modules/tour/js/tour.js +++ b/core/modules/tour/js/tour.js @@ -13,6 +13,7 @@ var queryString = decodeURI(window.location.search); * Attaches the tour's toolbar tab behavior. * * It uses the query string for: + * * - tour: When ?tour=1 is present, the tour will start automatically * after the page has loaded. * - tips: Pass ?tips=class in the url to filter the available tips to @@ -20,6 +21,7 @@ var queryString = decodeURI(window.location.search); * * Example: * http://example.com/foo?tour=1&tips=bar + * @type {Behavior} */ Drupal.behaviors.tour = { attach: function (context) { @@ -47,12 +49,31 @@ Drupal.behaviors.tour = { } }; -Drupal.tour = Drupal.tour || { models: {}, views: {}}; +/** + * @namespace + */ +Drupal.tour = { + /** + * @namespace + */ + models: {}, + /** + * @namespace + */ + views: {} +}; /** * Backbone Model for tours. + * @class */ -Drupal.tour.models.StateModel = Backbone.Model.extend({ +Drupal.tour.models.StateModel = Backbone.Model.extend(/** @lends Drupal.tour.models.StateModel# */ { + /** + * @type {Object} + * @prop {Array} tour + * @prop {Boolean} isActive + * @prop {Array} activeTour + */ defaults: { // Indicates whether the Drupal root window has a tour. tour: [], @@ -65,14 +86,12 @@ Drupal.tour.models.StateModel = Backbone.Model.extend({ /** * Handles edit mode toggle interactions. + * @class */ -Drupal.tour.views.ToggleTourView = Backbone.View.extend({ +Drupal.tour.views.ToggleTourView = Backbone.View.extend(/** @lends Drupal.tour.views.ToggleTourView# */ { events: { 'click': 'onClick' }, - /** - * Implements Backbone Views' initialize(). - */ initialize: function () { this.listenTo(this.model, 'change:tour change:isActive', this.render); this.listenTo(this.model, 'change:isActive', this.toggleTour); @@ -80,6 +99,7 @@ Drupal.tour.views.ToggleTourView = Backbone.View.extend({ /** * Implements Backbone Views' render(). + * return {Drupal.tour.views.ToggleTourView} */ render: function () { // Render the visibility. @@ -125,7 +145,7 @@ Drupal.tour.views.ToggleTourView = Backbone.View.extend({ /** * Gets the tour. * - * @return jQuery + * @return {jQueryObject} * A jQuery element pointing to a
      containing tour items. */ _getTour: function () { @@ -135,7 +155,7 @@ Drupal.tour.views.ToggleTourView = Backbone.View.extend({ /** * Gets the relevant document as a jQuery element. * - * @return jQuery + * @return {jQueryObject} * A jQuery element pointing to the document within which a tour would be * started given the current state. */ @@ -153,13 +173,13 @@ Drupal.tour.views.ToggleTourView = Backbone.View.extend({ * The above will filter out tips that do not have a matching page element or * don't have the "bar" class. * - * @param jQuery $tour + * @param {jQueryObject} $tour * A jQuery element pointing to a
        containing tour items. - * @param jQuery $document + * @param {jQueryObject} $document * A jQuery element pointing to the document within which the elements * should be sought. * - * @see _getDocument() + * @see _getDocument */ _removeIrrelevantTourItems: function ($tour, $document) { var removals = false; diff --git a/core/modules/user/user.js b/core/modules/user/user.js index 7b1ccfa..9a41554 100644 --- a/core/modules/user/user.js +++ b/core/modules/user/user.js @@ -1,3 +1,6 @@ +/** + * @file + */ (function ($) { "use strict"; @@ -5,6 +8,7 @@ /** * Attach handlers to evaluate the strength of any password fields and to check * that its confirmation is correct. + * @type {Behavior} */ Drupal.behaviors.password = { attach: function (context, settings) { @@ -85,6 +89,21 @@ Drupal.behaviors.password = { * Evaluate the strength of a user's password. * * Returns the estimated strength and the relevant output message. + * @param {String} password + * @param {Object} translate + * @param {String} translate.username + * @param {String} translate.tooShort + * @param {String} translate.addLowerCase + * @param {String} translate.addUpperCase + * @param {String} translate.addNumbers + * @param {String} translate.addPunctuation + * @param {String} translate.sameAsUsername + * @param {String} translate.weak + * @param {String} translate.fair + * @param {String} translate.good + * @param {String} translate.strong + * @param {String} translate.hasWeaknesses + * @return {Object} */ Drupal.evaluatePasswordStrength = function (password, translate) { var indicatorText, indicatorColor, weaknesses = 0, strength = 100, msg = []; @@ -173,6 +192,7 @@ Drupal.evaluatePasswordStrength = function (password, translate) { /** * Field instance settings screen: force the 'Display on registration form' * checkbox checked whenever 'Required' is checked. + * @type {Behavior} */ Drupal.behaviors.fieldUserRegistration = { attach: function (context, settings) { diff --git a/core/modules/user/user.permissions.js b/core/modules/user/user.permissions.js index 850dd88..9558fd6 100644 --- a/core/modules/user/user.permissions.js +++ b/core/modules/user/user.permissions.js @@ -1,9 +1,13 @@ +/** + * @file + */ (function ($) { "use strict"; /** * Shows checked and disabled checkboxes for inherited permissions. + * @type {Behavior} */ Drupal.behaviors.permissions = { attach: function (context) { diff --git a/core/modules/views/js/ajax_view.js b/core/modules/views/js/ajax_view.js index c8a3d7b..6b595e1 100644 --- a/core/modules/views/js/ajax_view.js +++ b/core/modules/views/js/ajax_view.js @@ -8,6 +8,7 @@ /** * Attaches the AJAX behavior to Views exposed filter forms and key View links. + * @type {Behavior} */ Drupal.behaviors.ViewsAjaxView = {}; Drupal.behaviors.ViewsAjaxView.attach = function() { @@ -21,14 +22,25 @@ Drupal.behaviors.ViewsAjaxView.attach = function() { } }; +/** + * @namespace + */ Drupal.views = {}; +/** + * @type {Object.} + */ Drupal.views.instances = {}; /** * Javascript object for a certain view. + * @constructor + * @param {Object} settings */ Drupal.views.ajaxView = function(settings) { var selector = '.view-dom-id-' + settings.view_dom_id; + /** + * @type {jQueryObject} + */ this.$view = $(selector); // Retrieve the path to use for views' ajax. @@ -50,6 +62,15 @@ Drupal.views.ajaxView = function(settings) { } } + /** + * @type {Object} + * @prop {String} url + * @prop {Object} submit + * @prop {Boolean} setClick + * @prop {String} event + * @prop {String} selector + * @prop {Object} progress + */ this.element_settings = { url: ajax_path + queryString, submit: settings, @@ -59,10 +80,16 @@ Drupal.views.ajaxView = function(settings) { progress: { type: 'throbber' } }; + /** + * @type {Object} + */ this.settings = settings; - // Add the ajax to exposed forms. + /** + * @type {jQueryObject} + */ this.$exposed_form = $('form#views-exposed-form-'+ settings.view_name.replace(/_/g, '-') + '-' + settings.view_display_id.replace(/_/g, '-')); + // Add the ajax to exposed forms. this.$exposed_form.once('exposed-form', jQuery.proxy(this.attachExposedFormAjax, this)); // Add the ajax to pagers. @@ -80,9 +107,15 @@ Drupal.views.ajaxView = function(settings) { // @endcode var self_settings = this.element_settings; self_settings.event = 'RefreshView'; + /** + * @type {Drupal.ajax} + */ this.refreshViewAjax = new Drupal.ajax(this.selector, this.$view, self_settings); }; +/** + * @method + */ Drupal.views.ajaxView.prototype.attachExposedFormAjax = function() { var button = $('input[type=submit], input[type=image]', this.$exposed_form); button = button[0]; @@ -90,6 +123,9 @@ Drupal.views.ajaxView.prototype.attachExposedFormAjax = function() { this.exposedFormAjax = new Drupal.ajax($(button).attr('id'), button, this.element_settings); }; +/** + * @method + */ Drupal.views.ajaxView.prototype.filterNestedViews= function() { // If there is at least one parent with a view class, this view // is nested (e.g., an attachment). Bail. @@ -129,6 +165,9 @@ Drupal.views.ajaxView.prototype.attachPagerLinkAjax = function(id, link) { this.pagerAjax = new Drupal.ajax(false, $link, this.element_settings); }; +/** + * @method + */ Drupal.AjaxCommands.prototype.viewsScrollTop = function (ajax, response) { // Scroll to the top of the view. This will allow users // to browse newly loaded content after e.g. clicking a pager diff --git a/core/modules/views/js/base.js b/core/modules/views/js/base.js index e7aa903..01e8466 100644 --- a/core/modules/views/js/base.js +++ b/core/modules/views/js/base.js @@ -6,10 +6,14 @@ "use strict"; + /** + * @namespace + */ Drupal.Views = {}; /** * Helper function to parse a querystring. + * @param {String} query */ Drupal.Views.parseQueryString = function (query) { var args = {}; @@ -31,6 +35,9 @@ /** * Helper function to return a view's arguments based on a path. + * + * @param {String} href + * @param {String} viewPath */ Drupal.Views.parseViewArgs = function (href, viewPath) { var returnObj = {}; @@ -46,6 +53,7 @@ /** * Strip off the protocol plus domain from an href. + * @param {String} href */ Drupal.Views.pathPortion = function (href) { // Remove e.g. http://example.com if present. @@ -59,6 +67,7 @@ /** * Return the Drupal path portion of an href. + * @param {String} href */ Drupal.Views.getPath = function (href) { href = Drupal.Views.pathPortion(href); diff --git a/core/modules/views/js/views-contextual.js b/core/modules/views/js/views-contextual.js index e90283d..40be51a 100644 --- a/core/modules/views/js/views-contextual.js +++ b/core/modules/views/js/views-contextual.js @@ -6,6 +6,9 @@ "use strict"; +/** + * @type {Behavior} + */ Drupal.behaviors.viewsContextualLinks = { attach: function (context) { var id = $('body').attr('data-views-page-contextual-id'); diff --git a/core/modules/views/tests/modules/views_test_data/views_cache.test.js b/core/modules/views/tests/modules/views_test_data/views_cache.test.js index 8dd17c1..e407d6d 100644 --- a/core/modules/views/tests/modules/views_test_data/views_cache.test.js +++ b/core/modules/views/tests/modules/views_test_data/views_cache.test.js @@ -1,4 +1,5 @@ /** + * @ignore * @file * Just a placeholder file for the test. * @see ViewsCacheTest::testHeaderStorage diff --git a/core/modules/views_ui/js/ajax.js b/core/modules/views_ui/js/ajax.js index f926330..5813b9a 100644 --- a/core/modules/views_ui/js/ajax.js +++ b/core/modules/views_ui/js/ajax.js @@ -6,22 +6,34 @@ "use strict"; + /** + * @method + */ Drupal.AjaxCommands.prototype.viewsHighlight = function (ajax, response, status) { $('.hilited').removeClass('hilited'); $(response.selector).addClass('hilited'); }; + /** + * @method + */ Drupal.AjaxCommands.prototype.viewsShowButtons = function (ajax, response, status) { $('div.views-edit-view div.form-actions').removeClass('js-hide'); $('div.views-edit-view div.view-changed.messages').removeClass('js-hide'); }; + /** + * @method + */ Drupal.AjaxCommands.prototype.viewsTriggerPreview = function (ajax, response, status) { if ($('input#edit-displays-live-preview').is(':checked')) { $('#preview-submit').trigger('click'); } }; + /** + * @method + */ Drupal.AjaxCommands.prototype.viewsReplaceTitle = function (ajax, response, status) { var doc = document; // For the element, make a best-effort attempt to replace the page @@ -39,6 +51,7 @@ /** * Get rid of irritating tabledrag messages + * @return {Array} */ Drupal.theme.tableDragChangedWarning = function () { return []; @@ -46,6 +59,7 @@ /** * Trigger preview when the "live preview" checkbox is checked. + * @type {Behavior} */ Drupal.behaviors.livePreview = { attach: function (context) { @@ -59,6 +73,7 @@ /** * Sync preview display. + * @type {Behavior} */ Drupal.behaviors.syncPreviewDisplay = { attach: function (context) { @@ -72,6 +87,9 @@ } }; + /** + * @type {Behavior} + */ Drupal.behaviors.viewsAjax = { collapseReplaced: false, attach: function (context, settings) { diff --git a/core/modules/views_ui/js/dialog.views.js b/core/modules/views_ui/js/dialog.views.js index 818d2d5..33d72e7 100644 --- a/core/modules/views_ui/js/dialog.views.js +++ b/core/modules/views_ui/js/dialog.views.js @@ -1,3 +1,6 @@ +/** + * @file + */ (function ($, Drupal, drupalSettings) { "use strict"; @@ -25,6 +28,9 @@ } } + /** + * @type {Behavior} + */ Drupal.behaviors.viewsModalContent = { attach: function (context) { $('body').once('viewsDialog').on('dialogContentResize.viewsDialog', '.ui-dialog-content', handleDialogResize); diff --git a/core/modules/views_ui/js/views-admin.js b/core/modules/views_ui/js/views-admin.js index bb54d50..7333ff6 100644 --- a/core/modules/views_ui/js/views-admin.js +++ b/core/modules/views_ui/js/views-admin.js @@ -6,10 +6,14 @@ "use strict"; +/** + * @namespace + */ Drupal.viewsUi = {}; /** * Improve the user experience of the views edit interface. + * @type {Behavior} */ Drupal.behaviors.viewsUiEditView = { attach: function () { @@ -24,6 +28,7 @@ Drupal.behaviors.viewsUiEditView = { /** * In the add view wizard, use the view name to prepopulate form fields such as * page title and menu link. + * @type {Behavior} */ Drupal.behaviors.viewsUiAddView = { attach: function (context) { @@ -81,16 +86,17 @@ Drupal.behaviors.viewsUiAddView = { * * Prepopulates a form field based on the view name. * - * @param $target + * @constructor + * @param {jQueryObject} $target * A jQuery object representing the form field to prepopulate. - * @param exclude - * Optional. A regular expression representing characters to exclude from the + * @param {RegExp} [exclude] + * A regular expression representing characters to exclude from the * target field. - * @param replace - * Optional. A string to use as the replacement value for disallowed + * @param {String} [replace] + * A string to use as the replacement value for disallowed * characters. - * @param suffix - * Optional. A suffix to append at the end of the target field content. + * @param {String} [suffix] + * A suffix to append at the end of the target field content. */ Drupal.viewsUi.FormFieldFiller = function ($target, exclude, replace, suffix) { this.source = $('#edit-label'); @@ -105,14 +111,20 @@ Drupal.viewsUi.FormFieldFiller = function ($target, exclude, replace, suffix) { // one bound version of an object method, whereas we need one version per // object instance. var self = this; + /** + * @returns {*} + */ this.populate = function () {return self._populate.call(self);}; + /** + * @returns {*} + */ this.unbind = function () {return self._unbind.call(self);}; this.bind(); // Object constructor; no return value. }; -$.extend(Drupal.viewsUi.FormFieldFiller.prototype, { +$.extend(Drupal.viewsUi.FormFieldFiller.prototype, /** @lends Drupal.viewsUi.FormFieldFiller# */ { /** * Bind the form-filling behavior. */ @@ -159,7 +171,9 @@ $.extend(Drupal.viewsUi.FormFieldFiller.prototype, { this.bind(); }}); - +/** + * @type {Behavior} + */ Drupal.behaviors.addItemForm = { attach: function (context) { var $context = $(context); @@ -175,6 +189,10 @@ Drupal.behaviors.addItemForm = { } }; +/** + * @param {jQueryObject} $form + * @constructor + */ Drupal.viewsUi.AddItemForm = function ($form) { this.$form = $form; this.$form.find('.views-filterable-options :checkbox').on('click', $.proxy(this.handleCheck, this)); @@ -184,6 +202,9 @@ Drupal.viewsUi.AddItemForm = function ($form) { this.checkedItems = []; }; +/** + * @param {Event} event + */ Drupal.viewsUi.AddItemForm.prototype.handleCheck = function (event) { var $target = $(event.target); var label = $.trim($target.next().text()); @@ -221,9 +242,10 @@ Drupal.viewsUi.AddItemForm.prototype.refreshCheckedItems = function () { }; /** - * The input field items that add displays must be rendered as <input> elements. - * The following behavior detaches the <input> elements from the DOM, wraps them + * The input field items that add displays must be rendered as `<input>` elements. + * The following behavior detaches the `<input>` elements from the DOM, wraps them * in an unordered list, then appends them to the list of tabs. + * @type {Behavior} */ Drupal.behaviors.viewsUiRenderAddViewButton = { attach: function (context) { @@ -281,6 +303,9 @@ Drupal.behaviors.viewsUiRenderAddViewButton.toggleMenu = function ($trigger) { $trigger.next().slideToggle('fast'); }; +/** + * @type {Behavior} + */ Drupal.behaviors.viewsUiSearchOptions = { attach: function (context) { var $context = $(context); @@ -302,6 +327,9 @@ Drupal.behaviors.viewsUiSearchOptions = { * The OptionsSearch object filters the available options on a form according * to the user's search term. Typing in "taxonomy" will show only those options * containing "taxonomy" in their label. + * + * @constructor + * @param {jQueryObject} $form */ Drupal.viewsUi.OptionsSearch = function ($form) { this.$form = $form; @@ -321,11 +349,11 @@ Drupal.viewsUi.OptionsSearch = function ($form) { }); }; -$.extend(Drupal.viewsUi.OptionsSearch.prototype, { +$.extend(Drupal.viewsUi.OptionsSearch.prototype, /** @lends Drupal.viewsUi.OptionsSearch */ { /** * Assemble a list of all the filterable options on the form. * - * @param $allOptions + * @param {jQueryObject} $allOptions * A $ object representing the rows of filterable options to be * shown and hidden depending on the user's search terms. */ @@ -351,6 +379,7 @@ $.extend(Drupal.viewsUi.OptionsSearch.prototype, { /** * Keyup handler for the search box that hides or shows the relevant options. + * @param {Event} event */ handleKeyup: function (event) { var found, i, j, option, search, words, wordsLength; @@ -387,6 +416,9 @@ $.extend(Drupal.viewsUi.OptionsSearch.prototype, { } }); +/** + * @type {Behavior} + */ Drupal.behaviors.viewsUiPreview = { attach: function (context) { // Only act on the edit view form. @@ -412,7 +444,9 @@ Drupal.behaviors.viewsUiPreview = { } } }; - +/** + * @type {Behavior} + */ Drupal.behaviors.viewsUiRearrangeFilter = { attach: function (context) { // Only act on the rearrange filter form. @@ -430,19 +464,41 @@ Drupal.behaviors.viewsUiRearrangeFilter = { /** * Improve the UI of the rearrange filters dialog box. + * + * @constructor + * @param {jQueryObject} $table + * @param {jQueryObject} $operator */ Drupal.viewsUi.RearrangeFilterHandler = function ($table, $operator) { - // Keep a reference to the <table> being altered and to the div containing - // the filter groups operator dropdown (if it exists). + /** + * Keep a reference to the table being altered and to the div containing + * the filter groups operator dropdown (if it exists). + * @type {jQueryObject} + */ this.table = $table; + /** + * @type {jQueryObject} + */ this.operator = $operator; + /** + * @type {Boolean} + */ this.hasGroupOperator = this.operator.length > 0; - // Keep a reference to all draggable rows within the table. + /** + * Keep a reference to all draggable rows within the table. + * @type {jQueryObject} + */ this.draggableRows = $table.find('.draggable'); - // Keep a reference to the buttons for adding and removing filter groups. + /** + * Keep a reference to the buttons for adding and removing filter groups. + * @type {jQueryObject} + */ this.addGroupButton = $('input#views-add-group'); + /** + * @type {jQueryObject} + */ this.removeGroupButtons = $table.find('input.views-remove-group'); // Add links that duplicate the functionality of the (hidden) add and remove @@ -482,7 +538,7 @@ Drupal.viewsUi.RearrangeFilterHandler = function ($table, $operator) { .on('click.views-rearrange-filter-handler', $.proxy(this, 'redrawOperatorLabels')); }; -$.extend(Drupal.viewsUi.RearrangeFilterHandler.prototype, { +$.extend(Drupal.viewsUi.RearrangeFilterHandler.prototype, /** @lends Drupal.viewsUi.RearrangeFilterHandler# */ { /** * Insert links that allow filter groups to be added and removed. */ @@ -531,7 +587,7 @@ $.extend(Drupal.viewsUi.RearrangeFilterHandler.prototype, { /** * Dynamically click a button for removing a filter group. * - * @param event + * @param {Event} event * Event being triggered, with event.data.buttonId set to the ID of the * form button that should be clicked. */ @@ -615,6 +671,9 @@ $.extend(Drupal.viewsUi.RearrangeFilterHandler.prototype, { operators.val($target.val()); }, + /** + * @method + */ modifyTableDrag: function () { var tableDrag = Drupal.tableDrag['views-rearrange-filters']; var filterHandler = this; @@ -624,6 +683,7 @@ $.extend(Drupal.viewsUi.RearrangeFilterHandler.prototype, { * * When a row is dragged to another place in the table, several things need * to occur. + * * - The row needs to be moved so that it's within one of the filter groups. * - The operator cells that span multiple rows need their rowspan attributes * updated to reflect the number of rows in each group. @@ -760,6 +820,7 @@ $.extend(Drupal.viewsUi.RearrangeFilterHandler.prototype, { /** * Add a select all checkbox, which checks each checkbox at once. + * @type {Behavior} */ Drupal.behaviors.viewsFilterConfigSelectAll = { attach: function (context) { @@ -787,6 +848,7 @@ Drupal.behaviors.viewsFilterConfigSelectAll = { /** * Remove icon class from elements that are themed as buttons or dropbuttons. + * @type {Behavior} */ Drupal.behaviors.viewsRemoveIconClass = { attach: function (context) { @@ -798,6 +860,7 @@ Drupal.behaviors.viewsRemoveIconClass = { /** * Change "Expose filter" buttons into checkboxes. + * @type {Behavior} */ Drupal.behaviors.viewsUiCheckboxify = { attach: function (context, settings) { @@ -813,6 +876,7 @@ Drupal.behaviors.viewsUiCheckboxify = { /** * Change the default widget to select the default group according to the * selected widget for the exposed group. + * @type {Behavior} */ Drupal.behaviors.viewsUiChangeDefaultWidget = { attach: function () { @@ -839,12 +903,22 @@ Drupal.behaviors.viewsUiChangeDefaultWidget = { /** * Attaches an expose filter button to a checkbox that triggers its click event. * - * @param button + * @constructor + * @param {HTMLElement} button * The DOM object representing the button to be checkboxified. */ Drupal.viewsUi.Checkboxifier = function (button) { + /** + * @type {jQueryObject} + */ this.$button = $(button); + /** + * @type {jQueryObject} + */ this.$parent = this.$button.parent('div.views-expose, div.views-grouped'); + /** + * @type {jQueryObject} + */ this.$input = this.$parent.find('input:checkbox, input:radio'); // Hide the button and its description. this.$button.hide(); @@ -856,6 +930,7 @@ Drupal.viewsUi.Checkboxifier = function (button) { /** * When the checkbox is checked or unchecked, simulate a button press. + * @param {Event} e */ Drupal.viewsUi.Checkboxifier.prototype.clickHandler = function (e) { this.$button @@ -865,6 +940,7 @@ Drupal.viewsUi.Checkboxifier.prototype.clickHandler = function (e) { /** * Change the Apply button text based upon the override select state. + * @type {Behavior} */ Drupal.behaviors.viewsUiOverrideSelect = { attach: function (context) { @@ -899,7 +975,9 @@ Drupal.behaviors.viewsUiOverrideSelect = { } }; - +/** + * @type {Behavior} + */ Drupal.behaviors.viewsUiHandlerRemoveLink = { attach: function (context) { var $context = $(context); diff --git a/core/modules/views_ui/js/views_ui.listing.js b/core/modules/views_ui/js/views_ui.listing.js index 1b6f554..79f6abb 100644 --- a/core/modules/views_ui/js/views_ui.listing.js +++ b/core/modules/views_ui/js/views_ui.listing.js @@ -1,3 +1,6 @@ +/** + * @file + */ (function ($, Drupal) { "use strict"; @@ -8,6 +11,7 @@ * Text search input: input.views-filter-text * Target table: input.views-filter-text[data-table] * Source text: .views-table-filter-text-source + * @type {Behavior} */ Drupal.behaviors.viewTableFilterByText = { attach: function (context, settings) { diff --git a/core/themes/seven/js/mobile.install.js b/core/themes/seven/js/mobile.install.js index 2326c24..2ecad33 100644 --- a/core/themes/seven/js/mobile.install.js +++ b/core/themes/seven/js/mobile.install.js @@ -1,3 +1,7 @@ +/** + * @file + * Vanilla JS file altering install pages for mobile use. + */ (function () { "use strict";