Dojo Style Guide

This document follows the basic outline of the Java Programming Conventions Guide.

Widget authors are expected to adhere to this style guide and also to the Dojo Accessibility Design Requirements guidelines.

General

Any violation to this guide is allowed if it enhances readability.

Guidelines in this document are informed by discussions carried out among the Dojo core developers. The most weight has been given to considerations that impact external developer interaction with Dojo code and APIs. Rules such as whitespace placement are of a much lower order importance for Dojo developers, but should be followed in the main in order to improve developer coordination.

Quick Reference

Table of core API naming constructs:

Construct Convention Comment
module lowercase never multiple words
class CamelCase  
public method mixedCase both class and instance method. lower_case() is acceptable only if the particular function is mimicking another API.
public var mixedCase  
constant CamelCase or UPPER_CASE  

Table of constructs that are not visible in the API, and therefore carry less weight of enforcement.

Construct Convention
private method _mixedCase
private var _mixedCase
method args _mixedCase, mixedCase
local vars _mixedCase, mixedCase

Naming Conventions

  1. When constructing string IDs or ID prefixes in the code, do not use "dojo", "dijit" or "dojox" in the names. Because we now allow multiple versions of dojo in a page, it is important you use _scopeName instead (dojo._scopeName, dijit._scopeName, dojox._scopeName).

  2. Names representing modules SHOULD be in all lower case.

  3. Names representing types (classes) MUST be nouns and written using CamelCase capitalization: Account, EventHandler

  4. Constants SHOULD be placed within a single object created as a holder for constants, emulating an Enum; the enum SHOULD be named appropriately, and members SHOULD be named using either CamelCase or UPPER_CASE capitalization:

    var NodeTypes = {
        Element: 1,
        DOCUMENT: 2
    };
    
  5. Abbreviations and acronyms SHOULD NOT be UPPERCASE when used as a name:

    getInnerHTML(), getXML(), XmlDocument

  6. Names representing methods SHOULD be verbs or verb phrases: obj.getSomeValue()

  7. Public class variables MUST be written using mixedCase capitalization.

  8. CSS variable names SHOULD follow the same conventions as public class variables.

  9. Private class variables MAY be written using _mixedCase (with preceding underscore):

    var MyClass = function(){
        var _buffer;
        this.doSomething = function(){}
    }
    
  10. Variables that are intended to be private, but are not closure bound, SHOULD be prepended with a \_ (underscore) char:

    this._somePrivateVariable = statement;
    

    note: the above variables also follows the convention for a private variable

  11. Generic variables SHOULD have the same name as their type: setTopic(topic) // where topic is of type Topic

  12. All names SHOULD be written in English.

  13. Variables with a large scope SHOULD have globally unambiguous names; ambiguity MAY be distinguished by module membership. Variables with small or private scope MAY have terse names.

  14. The name of the return object is implicit, and SHOULD be avoided in a method name:

    getHandler(); // NOT getEventHandler()``
    
  15. Public names SHOULD be as clear as necessary and SHOULD avoid unclear shortenings and contractions:

    MouseEventHandler // not MseEvtHdlr
    
  16. Note that, again, any context that can be determined by module membership SHOULD be used when determining if a variable name is clear. For example, a class that represents a mouse event handler:

    dojo.event.mouse.Handler; // NOT dojo.events.mouse.MouseEventhandler
    
  17. Classes/constructors MAY be named based on their inheritance pattern, with the base class to the right of the name:

    UiEventHandler
    MouseEventHandler
    
  18. The base class CAN be dropped from a name if it is obviously implicit in the name:

    MouseEventHandler; // as opposed to MouseUIEventHandler
    
  19. Functions that act as both getters and setters depending on the number of arguments are named after nouns. The 'get' and 'set' are implied. For example:

    dojo.attr(node, "tabIndex"); // getter
    dojo.attr(node, "tabIndex", -1); // setter
    

Specific Naming Conventions

  1. The terms get/set SHOULD NOT be used where a field is accessed, unless the variable being accessed is lexically private.

  2. The is prefix SHOULD be used for boolean variables and methods. Alternatives include has can and should

  3. The term compute CAN be used in methods where something is computed.

  4. The term find CAN be used in methods where something is looked up.

  5. The terms initialize or init CAN be used where an object or a concept is established.

  6. UI Control variables SHOULD be suffixed by the control type. Examples:

    leftComboBox, topScrollPane

  7. Plural form MUST be used to name collections.

  8. A num prefix or count postfix SHOULD be used for variables representing a number of objects.

  9. Iterator variables SHOULD be called i, j, k, etc.

  10. Complement names MUST be used for complement entities. Examples: get/set, add/remove, create/destroy, start/stop, insert/delete, begin/end, etc.

  11. Abbreviations in names SHOULD be avoided.

  12. Negated boolean variable names MUST be avoided: isNotError and isNotFound are unacceptable.

  13. Methods returning an object MAY be named after what they return, and methods returning void after what they do.

Files

  1. Class or object-per-file guidelines are not yet determined

  2. Tabs (set to 4 spaces) SHOULD be used for indentation.

  3. If your editor supports "file tags", please append the appropriate tag at the end of the file to enable others to effortlessly obey the correct indentation guidelines for that file:

    // vim:ts=4:noet:tw=0:

  4. The incompleteness of a split line MUST be made obvious

    var someExpression = Expression1
        + Expression2
        + Expression3
    ;
    
    var o = someObject.get(
        Expression1,
        Expression2,
        Expression3
    );
    

    Note the indentation for expression continuation is indented relative to the variable name, while indentation for parameters is relative to the method being called.

    Note also the position of the parenthesis in the method call; positioning SHOULD be similar to the use of block notation.

Variables

  1. Variables SHOULD be initialized where they are declared and they SHOULD be declared in the smallest scope possible. A null initialization is acceptable.

  2. Variables MUST never have a dual meaning.

  3. Related variables of the same type CAN be declared in a common statement; unrelated variables SHOULD NOT be declared in the same statement.

  4. Variables SHOULD be kept alive for as short a time as possible.

  5. Loops / iterative declarations

    1. Only loop control statements MUST be included in the for loop construction.
    2. Loop variables SHOULD be initialized immediately before the loop; loop variables in a for statement MAY be initialized in the for loop construction.
    3. The use of do...while loops is acceptable (unlike in Java).
    4. The use of break and continue is not discouraged (unlike in Java).
  6. Conditionals

    1. Complex conditional expressions SHOULD be avoided; use temporary boolean variables instead.
    2. The nominal case SHOULD be put in the if part and the exception in the else part of an if statement.
    3. Executable statements in conditionals MUST be avoided.
  7. Miscellaneous

    1. The use of magic numbers in the code SHOULD be avoided; they SHOULD be declared using named constants instead.
    2. Floating point constants SHOULD ALWAYS be written with decimal point and at least one decimal.
    3. Floating point constants SHOULD ALWAYS be written with a digit before the decimal point.

Layout

  1. Block statements.

    1. Block layout SHOULD BE as illustrated below:

      while(!isDone){
          doSomething();
          isDone = moreToDo();
      }
      
    2. if statements SHOULD have the following form:

      if(someCondition){
          statements;
      }else if(someOtherContion){
          statements;
      }else{
          statements;
      }
      
    3. for statements SHOULD have the following form:

      for(init; condition; update){
          statements;
      }
      
    4. while statements SHOULD have the following form:

      while(!isDone){
          doSomething();
          isDone = moreToDo();
      }
      
    5. do...while statements SHOULD have the following form:

      do{
          statements;
      }while(condition);
      
    6. switch statements SHOULD have the following form:

      switch(condition){
          case "ABC":
              statement;
              // fallthrough
          case "DEF":
              statements;
              break;
          default:
              statements;
              // no break keyword on the last case - it's redundant.
      }
      
    7. try...catch...finally statements SHOULD have the following form:

      try{
          statements;
      }catch(e){
          statements;
      }finally{
          statements;
      }
      
    8. A single statement if-else, while or for MUST NOT be written without brackets, but CAN be written on the same line:

      if(condition){ statement; }
      else{ statement; }
      
      while(condition){ statement; }
      
      for(init; condition; update){ statement; }
      
  2. Whitespace

    1. Conventional operators MAY be surrounded by a space (including ternary operators).

    2. The following reserved words SHOULD NOT be followed by a space:

      • break
      • catch
      • continue
      • do
      • else
      • finally
      • for
      • function if anonymous. eg: var foo = function(){};
      • if
      • return
      • switch
      • this
      • try
      • void
      • while
      • with
    3. The following reserved words SHOULD be followed by a space:

      • case
      • default
      • delete
      • function if named. eg: function foo(){})
      • in
      • instanceof
      • new
      • throw
      • typeof
      • var
    4. Commas SHOULD be followed by a space.

    5. Colons MAY be surrounded by a space.

    6. Semi-colons in for statements SHOULD be followed by a space.

    7. Semi-colons SHOULD NOT be preceded by a space.

    8. Function calls and method calls SHOULD NOT be followed by a space.

      doSomething(someParameter); // not doSomething (someParameter);
      
    9. Logical units within a block SHOULD be separated by one blank line.

    10. Statements MAY be aligned wherever this enhances readability.

  3. Line length

    There's no line length limit in dojo although 120 characters (treating tabs as 4 spaces) is a guideline. In particular code examples embedded into the API documentation may benefit from longer lines, since they start out already indented by 4 or 5 tabs.

  4. Comments

    1. Tricky code SHOULD not be commented, but rewritten.
    2. All comments SHOULD be written in English.
    3. Comments SHOULD be indented relative to their position in the code, preceding or to the right of the code in question.
    4. The declaration of collection variables SHOULD be followed by a comment stating the common type of the elements in the collection.
    5. Comments SHOULD be included to explain BLOCKS of code, to explain the point of the following block.
    6. Comments SHOULD NOT be included for every single line of code.

API Documentation

Markup Guidelines

Dojo's API documentation is written inline in the code, similar to JavaDoc. See the Dojo Inline Documentation for information on dojo's proprietary format.

CSS

The CSS styling basically inherits all the rules from JavaScript, that means "key: value" looks like in JS, etc. Therefore a CSS file might look like this:

.className1 {
     color: red;
}

.className1,
#someId {
     color: blue;
}

Mainly the rules are:

  • each selector is on a new line
  • the opening curly brace is preceded by a space
  • the key value pairs have a space after the colon
  • every block is followed by an empty new line