wiki:CodeDocumentation

Version 1 (modified by Piotrek Koszuliński, 6 years ago) (diff)

Copied from dev-v4.

JSDuck documentation guide

Starting from CKEditor 4 we use JSDuck documentation generator, previously it was JSDoc.

JSDuck's comments format differs from JSDoc's and both generators have different features lists. Thus, entire documentation has been reformatted in new, consistent way.

JSDuck vs JSDoc - important differences

  • JSDuck has Markdown support. HTML entities may still be used, but try to avoid them in favor of Markdown. Note that HTML in code samples (indented blocks) and `pre-formatted` will be encoded.
  • JSDuck does not accept these tags: @namespace, @name, @constant, @augments, @field, @type (deprecated), @default and more (I listed only those which we were using).
  • JSDuck accepts new tags: @cfg, @member, @chainable, @inherits, @method, @mixins, @readonly, @singleton and more.
  • Many of shared tags have different format in JSDuck (e.g. @example creates live examples, standard code samples are just indented). So be careful.
  • JSDuck does not parse code searching for classes and properties. Thus, it will only find those API elements which have at least their preceding /** */ doc comments.
  • JSDuck recognizes names of API elements (methods, classes, events, config vars, properties, etc), method definitions (with arguments list) and properties (their type and default value too if possible). Thus, these information does not have to be specified in some cases.
  • Classes' definitions may be opened multiple times - it's useful when class's methods and properties are defined in more than one file or place in the code.
  • There's no list of files in JSDuck, so old @license and @fileOverview tags are kept for other purposes (and thanks to custom tags they work in JSDuck like @ignore).
  • There are no namespaces in JSDuck, so the packages tree is auto-generated based on the classes tree and @member tags.
  • All properties, events, etc. defined under the class definition will be assigned to this class, so there's no need to specify @member.

Docs formats

File header

/**
 * @license Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
 * For licensing, see LICENSE.html or http://ckeditor.com/license
 */

/**
 * @fileOverview Defines the {@link CKEDITOR.editor} class, which represents an
 * editor instance.
 */

Both comments will be ignored and they are not required.

Note that since @fileOverview comments are ignored, they weren't reformatted, so they may contain old JSDoc format.

Class

/**
 * Represents an editor instance. This constructor should be rarely
 * used, in favor of the {@link CKEDITOR} editor creation functions.
 *
 *		var editor = new CKEDITOR.editor();
 *		editor.setSomething( name, {
 *			value: 1
 *		} );
 *
 * @since 3.0
 * @private
 * @class CKEDITOR.editor
 * @extends CKEDITOR.parent
 * @mixins CKEDITOR.event
 * @mixins CKEDITOR.whatever
 * @constructor Creates an editor class instance.
 * @param {Object} [instanceConfig] Configuration values for this specific instance.
 * @param {Number} [mode=CKEDITOR.SOURCE_MODE] The element creation mode to be used by this editor.
 * will be created.
 *
 * Possible values are:
 *
 * * `CKEDITOR.SOURCE_MODE` - desc 1,
 * * `CKEDITOR.WYSIWYG_MODE` - desc 2 long long long
 *      long long long long long,
 * * `CKEDITOR.ANOTHER_MODE` - desc 3.
 *
 * @param {CKEDITOR.dom.element} [element] The DOM element upon which this editor
 * will be created.
 * @see CKEDITOR.editable
 * @see CKEDITOR.cofing#someVar
 */
CKEDITOR.editor = function( ) {
	// ...

This is the example of class definition. It contains so many tags to show their correct order.

The minimal class doc:

/**
 * Represents an editor instance. This constructor should be rarely
 * used, in favor of the {@link CKEDITOR} editor creation functions.
 *
 * @class
 */
CKEDITOR.editor = function( ) {
	// ...

And when you want to reopen class declaration in other file:

/** @class CKEDITOR.editor */

Details

Tags order may look strange, but you can remember it thanks to this description:

Since 3.0 there's a private class CKEDITOR.editor which extends CKEDITOR.parent and mixins CKEDITOR.event and CKEDITOR.whatever.

It has a private constructor (switched order - I'll explain this later in the tags list) which accepts following params: ...

See also: ...

Important tags details:

  • Private classes by default won't be visible in the packages tree.
  • Good example of difference between "mixins" and "extends" is that CKEDITOR.event is mixed in various other classes and CKEDITOR.dom.* structure is based on extending parent classes.
  • Constructor is in fact separate documentation "instance", because it will be listed with methods. Thus, it may have its own @private, but it has to be placed below it, because everything before will be the part of class description. However two @private tags in one comment won't be accepted by JSLinter, so the doc then should be split into two comments.

Another conclusion is that constructor may be declared completely independently from class, what's useful when CKEDITOR.tools.createClass has been used.

And the last conclusion is that in the first example @see tags will the part of constructor's definition, not class. Thus they may be also placed after mixins.

Property and Config variable

/**
 * A unique identifier of this editor instance.
 *
 * **Note:** It will be originated from the ID or name
 * attribute of the {@link #element}, otherwise a name pattern of
 * `'editor{n}'` will be used.
 *
 * @private
 * @readonly
 * @static
 * @property {String/Boolean} [complicatedName=default value]
 * @member CKEDITOR.editor
 * @see CKEDITOR.whatever
 */
obj[ 'complicated' + 'Name' ] = this.name || genEditorName();

The minimal property doc:

/**
 * Property desc (even this may be omitted, but it's better to always describe property).
 */
this.propertyName = 'value';

Which will be, by the JSDuck, recognized as @property {String} [propertyName='value'] and will be assigned to the class defined earlier in the file.

Partial:

/**
 * Property desc.
 *
 * @property {String} [=config.something (value taken from configuration)]
 */
this.propertyName = this.config.something;

Basic:

/**
 * Property desc.
 *
 * @property propertyName
 */
this.propertyName = this.config.something;

Details

  • JSDuck's type definitions are awesome - read more about them.
  • Property name, type and default value may be automatically recognized.
  • Default value doesn't have to be a JS code, so in the "Partial" example JSDuck will print: "Defaults to: config.something (value taken...)".
  • If property isn't defined below a class definition or it belongs to a different class, then @member has to be used. Specifying namespace in @property isn't possible.

Config variables

To define config var instead of property:

  • Use @cfg instead of @property. Format is the same.
  • @private, @readonly, @static may not work (haven't been tested).

Method and Event

/**
 * The the {@link CKEDITOR.dom.element} representing and element. If the
 * element is a native DOM element, it will be transformed into a valid
 * CKEDITOR.dom.element object.
 *
 *		var element = new CKEDITOR.dom.element( 'span' );
 *		alert( element == CKEDITOR.dom.element.get( element ) ); // true
 *
 *		var element = document.getElementById( 'myElement' );
 *		alert( CKEDITOR.dom.element.get( element ).getName() ); // (e.g.) 'p'
 *
 * @private
 * @static
 * @method complicatedName
 * @member CKEDITOR.editor
 * @param {String/Object} element Element's id or name or native DOM element.
 * @param {Function} fn Callback.
 * @param {String} fn.firstArg Callback's first argument.
 * @param {Number} fn.secondArg Callback's second argument.
 * @param {String} [name='default value']
 * @returns {CKEDITOR.dom.element} The transformed element.
 */
this[ 'complicated' + 'Name' ] = (function() {
	return function() {
	};
}());

Typical:

/**
 * Method desc.
 *
 * @param {String/Object} element Element's id or name or native DOM element.
 * @param {String} [name='default value']
 * @returns {CKEDITOR.dom.element} The transformed element.
 */
this.methodName = function() {
	// ...
};

Details

  • @method tag has to be used when it's not clear that this is a method (e.g. closure returning function was used or reference to function defined elsewhere) or method's name isn't obvious.
  • Callback's arguments may be defined. Also - if method returns object, its properties may be defined too - read more.
  • Both @return and @returns are accepted, but use the latter one.

Events

To define event instead of method:

  • Use @event instead of @method - usually you'll have to provide the name.
  • @returns isn't accepted and @private and @static may not work (haven't been tested).

Various rules

  • Always leave one blank line between textual comment and the first tag.
  • Separate all block (paragraphs, code samples, etc) with one blank line.
  • Code samples indent with at least two tabs after '*'.
  • Wrapped lines of multiline lists indent with five (default 1 + additional 4) spaces.
  • Always place dot '.' at the end of the sentence. Sentence starts with upper-case letter.
  • Always use single quotes for JS strings, but double quotes for cites, irony, etc. in textual comments.
  • Cross-references format for links is: CKEDITOR.name.space#property. If there are more than one event/prop/cfg/method with the same name, then prepend cfg-, property-, method- or event- to the name. Namespace may be omitted if equals to @member or current class. See "Cross-references" section in JSDuck's guide.
  • In default values use real format: CKEDITOR.name.space.property.
  • When describing value returned/alerted in the code sample wrap only strings in ''. All other types (boolean, number, objects, etc.) should be left unwrapped.
  • There's no Integer type in JS and constructors' names should be used as types names - so Boolean, not boolean.
  • In textual comments wrap tokens, names from code, JS values, etc. with `` - they will be better visible. Remember to wrap strings with '' - so: This method may return: `'text text'`.
© 2003 – 2019 CKSource – Frederico Knabben. All rights reserved. | Terms of use | Privacy policy