Developer

Create useful relevant JavaScript documentation with JSDoc


This blog post is also available as a TechRepublic PDF download.

Whatever the reason, not documenting an application is never a good thing, even if it is usually something of a chore. This is especially true when given the task of documenting client-side JavaScript, which is usually considered something of an ugly stepchild when compared to server-side technologies. Interestingly though, the answer to the problem with JavaScript documentation comes from one of those very same server-side technologies — Java.

There is a really neat tool for Java developers that aids in the generation of documentation called Javadoc. There is also a version for JavaScript called JSDoc, which is used to develop HTML documentation that not only fulfills the need for code documentation but also helps prevent problems such as multiple functions or objects that essentially do the same thing and the general lack of knowledge of what is in the library. This tutorial walks you through how to install and use JSDoc for documenting JavaScript.

Installing JSDoc

Unfortunately, the installation of JSDoc isn't as exactly straightforward as it could be. The reason for this is that it is written in Perl, so unless you've already installed Perl there's an additional step or two. Because I recently reinstalled Windows XP Pro on my laptop, I had run through the additional steps myself. The first thing I had to do was download and install ActivePerl, which was available as a msi file. Figure A shows part of the installation process.

Figure A

Installing ActivePerl
Once ActivePerl is installed successfully, the next step is to download and decompress JSDoc. At this point, it is possible to run JSDoc from a DOS Window, but if you do, it probably won't work. This failure is due to a missing Perl Package, as shown in Figure B. Fortunately, typing ppm in the very same Window brings up the Perl Package Manager, shown in Figure C.

Figure B

DOS Window

Figure C

Perl Package Manager
Using the Perl Package Manager, the missing HTML-Template package can be installed, as Figure D illustrates.

Figure D

Installing a Perl Package

Trying it out

Once all of the required components have been installed, it is time to kick the tires, so to speak. For this, I'm using the JavaScript shown in Listing A.

Listing A — Sample JavaScript

<!— <![CDATA[
/**
 * @fileoverview This file contains the information necessary to add client-side
 * keyboard restriction functionality to a web page.
 */
/**
 * Accept 'Y' or 'N' and return issue an error message.
 * @requires keybEdit
 */
var keybYN = new keybEdit('yn','Valid values are 'Y' or 'N'.');
/**
 * Accept numeric input and return issue an error message.
 * @requires keybEdit
 */
var keybNumeric = new keybEdit('01234567890','Numeric input only.');
/**
 * Accept numeric input and return issue an error message.
 * @requires keybEdit
 */
var keybAlpha = new keybEdit('abcdefghijklmnopqurstuvwxyz','Alpha input only.');
/**
 * Accept alphabetic input and return issue an error message.
 * @requires keybEdit
 */
var keybAlphaNumeric = new keybEdit('abcdefghijklmnopqurstuvwxyz01234567890/ -,.=!@#$%^&*()_+'":;','Alpha-numeric input only.');
/**
 * Accept alphabetic or numeric input and return issue an error message.
 * @requires keybEdit
 */
var keybDecimal = new keybEdit('01234567890.','Decimal input only.');
/**
 * Accept decimal input and return issue an error message.
 * @requires keybEdit
 */
var keybDate =  new keybEdit('01234567890/','Date input only');;
/**
 * Accept date input and return issue an error message.
 * @requires keybEdit
 */
var keybYNNM = new keybEdit('yn','');
/**
 * Accept numeric input.
 * @requires keybEdit
 */
var keybNumericNM = new keybEdit('01234567890','');
/**
 * Accept alphabetic input.
 * @requires keybEdit
 */
var keybAlphaNM = new keybEdit('abcdefghijklmnopqurstuvwxyz','');
/**
 * Accept alphabetic or numeric input.
 * @requires keybEdit
 */
var keybAlphaNumericNM = new keybEdit('abcdefghijklmnopqurstuvwxyz01234567890/ -,.=!@#$%^&*()_+'":;','');
/**
 * Accept decimal input.
 * @requires keybEdit
 */
var keybDecimalNM = new keybEdit('01234567890.','');
/**
 * Accept date input.
 * @requires keybEdit
 */
var keybDateNM =  new keybEdit('01234567890/','');;

/**
 * keybEdit
 * @class The purpose of this function is to be a constructor for the keybEdit
 * object. keybEdit objects are used by the function editKeyBoard to
 * determine which keystrokes are valid for form objects. In addition, if an
 * error occurs, they provide the error message.
 * @constructor
 * @param {string} strValid Valid input characters
 * @param {string} strMsg Error message
 */
function keybEdit(strValid, strMsg) {
      //    Variables
      var reWork = new RegExp('[a-z]','gi');       //    Regular expression

      //    Properties
      if(reWork.test(strValid))
             this.valid = strValid.toLowerCase() + strValid.toUpperCase();
      else
             this.valid = strValid;

      if((strMsg == null) || (typeof(strMsg) == 'undefined'))
             this.message = '';
      else
             this.message = strMsg;

      /**
       * @ignore
       */
      this.getValid = keybEditGetValid;
      /**
       * @ignore
       */
      this.getMessage = keybEditGetMessage;

      /**
       * Return a boolean indicating whether or not a key stroke is valid.
       * @method getValid
       * @return string-boolean Indicates whether or not a key is valid.
       */
      function keybEditGetValid() {
             return this.valid.toString();
      }

      /**
       * Return an error message associated with a key stroke.
       * @method getMessage
       * @return string Error message.
       */
      function keybEditGetMessage() {
             return this.message;
      }
}

/**
 * The purpose of this function is to edit edit keyboard input to determine if
 * the keystrokes are valid.
 * @requires keybEdit
 * @param {Object} evt
 * @param {Object} objKeyb
 */
function editKeyBoard(evt, objKeyb) {
      var strWork = objKeyb.getValid();
      var strMsg = '';                                   // Error message
      var blnValidChar = false;                    // Valid character flag
      var intCode = evt.charCode == undefined ? evt.keyCode : evt.charCode;

      // Part 1: Validate input
      if(!blnValidChar)
             switch(true) {
                   case(intCode == 8):
                   case(intCode == 9):
                   case(intCode == 10):
                   case(intCode == 13):
                          blnValidChar = true;

                          break;
                   default:
                          for(i=0;i < strWork.length;i++)
                                if(intCode == strWork.charCodeAt(i)) {
                                      blnValidChar = true;

                                      break;
                                }

                          break;
             }

      // Part 2: Build error message
      if(!blnValidChar) {
             if(objKeyb.getMessage().toString().length != 0)
                   alert('Error: ' + objKeyb.getMessage());

             evt.stopPropagation = true;

             try {
                   evt.preventDefault();
             }
             catch(e) {
                   window.event.returnValue = false;            // Clear invalid character
             }
      }
}
// ]]> —>
Using the above JavaScript as input requires once again going into the DOS command prompt, as shown in Figure E. This image also shows the command necessary to generate the documentation. Figure F shows some of the documentation itself.

Figure E

Generating documentation

Figure F

Generated documentation

Options and hints

The example just scratches the surface of the capabilities of JSDoc, as you can probably figure out from my lame example. To fully appreciate just what JSDoc is capable of, you might want to look at Table A, which shows the tags that can be used within JavaScript documentation.

Table A

Tag

Description

@addon

Marks a function as an extension of a function whose definition is not within the source file.

@argument

Describes an argument with the argument type being in curly braces.

@author

Names the author of the function/class.

@base

Defines the provided class name as the class being inherited from.

@class

Used to provide a description of a class, which will not be used in the constructor's documentation.

@constructor

Describes the constructor for a class.

@deprecated

Signifies that the function/class has been deprecated.

@exception

Describes an error that the function/class may throw.

@exec

 

@extends

Signifies the class that the current class is derived from.

@fileoverview

Signifies that the documentation block is to be used to describe the current file. This tag should be placed before any other tags.

@final

Indicates that the function/class

@ignore

Causes JSDoc to ignore the subsequent code.

@link

Similar to the @link tag, used to link to a number of other pages.

@member

Defines the subsequent function as a member of the provided class name.

@param

Describes a parameter with the parameter type being in curly braces.

@private

Signifies that the function/class is private and should not be included in the generated documentation.

@requires

Signifies that another function/class is required.

@return

Describes the return value for a function.

@returns

Describes the return value for a function.

@see

Links to another function/class.

@throws

Describes an error that the function/class may throw.

@type

Specifies the return type of a function/member.

@version

The function's/classes' version number.

In addition to the information shown, executing JSDoc.pl with the -h or -help option will display a list of options available when generating documentation. Figure G shows the result of the help option.

Figure G

The -help option

No more excuses

While the documentation generated by JSDoc might not conform to your local standards, it does provide a starting point. Say, for instance, that the local standard is UML, then you might want to try to generate XMI using the -format option. It seems that with JSDoc the list of excuses for not documenting is growing short.

Editor's Picks