Search code examples
javascriptyuidocumentation-generation

Documentation of classes and modules in YUIDocs


I'm having a bit of trouble writing my documentation for a set of grouped modules. I think it's partly a misconception over what @class, @module and @namespace represent. (Or maybe it's a result of Yahoo trying to shoehorn a 'classical' language vocabulary into JS.)

I've got a roughed out sample below showing how most of my code is written and my attempt at documenting it in YUIDoc-style. The first two parts (Foo and BazManager) are pretty straightforward. To me:

  • Foo is a @class;
  • Baz is a @class;
  • BazManager is a @module (or maybe a @class that contains only @static members);
  • Qux is also a @module but contains only methods.

My problems are:

  1. If BazManager is a @module, Foo shows up under BazManager;
  2. If BazManager is a @class, the methods inside Baz get sucked into it if you don't add @for to everything;
  3. If BazManager is a @class, then documenting Baz's visibility becomes really tricky;
  4. I really don't know how I'm supposed to document Qux. It seems to me to be a module, but since it has no @classes, it gobbles everything around it, including BazManager. So it must be a @class.

Can anyone suggest how I should be doing this? I don't really care if I get the terms right as long as everything in the documentation gets generated correctly.

Here's my sample code:

// File: Widgets.js

/**
MyNamespace namespace
@namespace MyNamespace
*/
var MyNamespace = window.MyNamespace || {};

//--------------------PART 1: Foo-------------------//

/**
This is a description of Foo.
@class Foo
*/
MyNamespace.Foo = function () {
    this.toString = function () {
        return "I am a foo";
    };

    /**
    This is Foo's private method description.
    @method privateMethod
    @private
    */
    var privateMethod = function () {};

    /**
    This is Foo's public method description.
    @method publicMethod
    */
    this.publicMethod = function () {};
};


//--------------------PART 2: Baz-------------------//
/**
This is a description of BazManager.
@module BazManager
@namespace MyNamespace
*/
MyNamespace.BazManager = (function () {
    var self = {};

    /**
    This is a description of Baz.
    @class Baz
    */
    var Baz = function (type) {
        /**
        toString description
        @method toString
        @returns {String}
        */
        this.toString = function () {
            return "I am a baz and I'm " + type;
        };
    };

    /**
    This is BazManager's privateBaz description.
    @method privateBaz
    @private
    */
    var privateBaz = new Baz("private");

    /**
    This is BazManager's publicBaz description.
    @method publicBaz
    */
    self.publicBaz = new Baz("public");

    return self;
} ());


//--------------------PART 3: Qux-------------------//

MyNamespace.Qux = (function () {
    var self = {};
    /**
    execute description
    @method execute
    @private
    */
    var execute = function () {
        console.log("Qux is done");
    };

    /**
    start description
    @method start
    */
    self.start = function () {
        setTimeout(execute, 1000);
    };

    return self;
} ());

Solution

  • In YUIDoc @class is used for both classical classes and for objects which contain a bunch of methods. Classes that are meant to be instantiated are also marked with @constructor. That's mostly because of the way that those classes are then shown in the templates. It's a lot easier to track down a class than many lone functions.

    The YUI team and many in the community (myself included) seem to be moving away from @namespace. It's hard to get right. Instead we're writing class names with dots in them, ie: @class Plugin.NodeMenuNav.

    Modules are meant in the YUI sense and can be mostly understood as "scripts" that contain one or more classes.

    So a typical module will look like this:

    /**
    A series of utilities to do stuff
    
    @module Stuff
    **/
    
    /**
    A class that does foo very well
    
    @class Foo
    @constructor
    @param {Object} [config] Configuration object
    @param {Boolean} [config.jumpHigh] Whether foo should jump really high
    **/
    function Foo(config) {
      config = config || {};
      var high = config.jumpHigh;
    }
    /**
    @method jump
    @chainable
    **/
    Foo.prototype.jump = function () {
        // jump
        return this;
    };
    
    /**
    A series of utilities to make Foo do more stuff
    
    @class FooUtils
    **/
    var FooUtils = {
        /**
        @method doSomeStuff
        @static
        **/
        doSomeStuff: function () {
    
        }
    };
    

    Finally, @for is meant for modules that extend other modules. For instance, you could have a module Bar that adds methods to the prototype of Foo:

    /**
    Adds extra functionality to Foo
    
    @module Bar
    **/
    
    /**
    Run really fast
    
    @method run
    @for Foo
    **/
    Foo.prototype.run = function () {};bv