API documentation and comment standard
JavaScript code should be documented with documentation headers that are very similar to the PHP documentation headers, with modifications due to using the JSDoc3 parser as the first step in parsing the code and documentation. We generally follow the PHP standards as much as possible, with the following changes:
- All JavaScript items (methods, object constructors and properties, functions, variables, etc.) need to have documentation headers, or they will not be recognized by the parser (unlike the API module, which picks up all PHP items whether or not they have documentation headers). Only behaviors are documented specifically, see the behavior documentation example.
- Not all of the @tags we use for PHP are supported. See below for the tags available and their order of declaration.
- To indicate the data type for a
@paramor@returntag, put the data type in{}brackets:@param {TheType} paramNameor@return {TheType}. For non-object data, usenumber,string,bool,null,undefined,object,function,Array. For particular objects, use the constructor name; this could be a built-in JavaScript class (Date,RegExp), a DOM element (HTMLElement,HTMLInputElement), a Drupal-specific class (Drupal.Ajax), etc. - Additional tag: like
@throws, which documents exceptions being thrown by a PHP or JavaScript function, use@firesto document events that are triggered by a JavaScript function. In addition, if the event is a custom event (as opposed to a standard event like a key press), add a documentation block immediately before the first line of code within a function that triggers the event, with an@eventtag, to document the event itself (see sample below for details). Only include one@eventblock for each custom event, but use@firesin each function that triggers the custom event. - Additional tag: when documenting an object that is not being used as a namespace or class, use
@prop {type} nametags to document its properties (these work like@paramfor function parameters). - Some additional notation is required in many cases to help JSDoc figure out what type of item is being documented.
- Use
@nameto tell JSDoc the name of what is being documented, if it is not the same as the name in the code (usually because it is a function name likeDropButtonrather than including the class name likeDrupal.DropButton). - Use
@constructorto indicate that a function is intended to be a class constructor. - Use
@namespaceto indicate that an object is intended as a namespace. - You do not need to use
@functionin most cases - JSDoc will assume anything declared as a function is a regular function or method, unless one of the tags above overrides this determination.
- Use
Tag order
Tags available should be declared in the following order:
@global
@typedef
@var
@name
@namespace
@constructor
@callback
@event
@function
@augments
@lends
@type
@prop
@param
@return
@throws
@fires
@listens
@ingroup
@deprecated
@see
@todo
@ignore
Here's a sample:
Documenting a JavaScript file
/**
* @file
* Provides some feature
*
* The extra line between the end of the @file docblock
* and the file-closure is important.
*/
(function ($) {
"use strict";
})();
Documenting behaviors
/**
* Attaches the table drag behavior to tables.
*
* @type {Drupal~behavior}
*
* @prop {Drupal~behaviorAttach} attach
* Specific description of this attach function goes here.
* @prop {Drupal~behaviorDetach} detach
* Specific description of this detach function goes here.
*/
Drupal.behaviors.tableDrag = {
attach: function (context, settings) {
// ...
},
detach: function (context, settings, trigger) {
// …
}
};
Documenting usual constructs
/**
* Holds JavaScript settings and other information for Drupal.
*
* @namespace
*/
var Drupal = {
// ...
/**
* Holds behaviors for Drupal.
*
* @namespace
*/
'behaviors': {},
// ...
};
/**
* Returns the value of foo for the current widget.
*
* Description of this ordinary function in the Drupal namespace goes here.
*
* @return
* The value of foo in the current widget.
*/
Drupal.getCurrentFoo = function () {
// ...
};
/**
* Constructs a table drag object.
*
* Provides the ability to drag to manipulate a table and its fields.
*
* @constructor
*
* @param {HTMLTableElement} table
* DOM object for the table to be made draggable.
* @param {object} tableSettings
* Settings for the table.
*/
Drupal.tableDrag = function (table, tableSettings) {
// ...
}
/**
* Hides the columns containing weight and parent form elements.
*
* @fires event:columnschange
*
* @see Drupal.tableDrag.showColumns
*/
Drupal.tableDrag.prototype.hideColumns = function() {
// ...
/**
* Indicates that columns have changed in a table.
*
* @param {string} type
* Type of change: 'show' or 'hide'.
*
* @event columnschange
*/
$('table.tableDrag-processed').trigger('columnschange', 'hide');
// ...
};
/**
* Shows the columns containing weight and parent form elements.
*
* @fires columnschange
*
* @see Drupal.tableDrag.hideColumns
*/
Drupal.tableDrag.prototype.showColumns = function() {
// This event is documented in Drupal.tableDrag.hideColumns
$('table.tabledrag-processed').trigger('columnschange', 'hide');
};