Formatting Guide

This guide explains some of our formatting requirements. Please refer to existing source code if you are unsure as to how to format your code. Clean code is happy code!

Whitespace

Use a single blank line to separate related (but separate logic). Think of it as paragraphs of code.


capri.parseArgs = function(args, defaults, delimiter) {
   if (!args)
      args = {};
   else if (typeof args === 'string')
      args = capri.parseString(args, delimiter || ';');

   if (typeof defaults === 'string')
      defaults = capri.parseString(defaults, delimiter || ';');
   else if (!defaults)
      defaults = {};

   for (var key in defaults)
      if (args[ key ] === undefined || args[ key ] === null)
         args[ key ] = defaults[ key ];

   return args;
};

Please use tab characters to indent code blocks appropriately (not spaces!).

Remember, whitespace and comments are free! They will be removed from minified distribution.

Commenting

Single-line comments should provide meaningful insight that cannot otherwise be deduced from reading the code. It is safe to assume that developers understand how the programming language works.

The Good

// Do callbacks exist?
if (typeof action === 'object') {
   // Prepare arguments for use.
   if (capri.typeOf(params) === 'function')
      params = params();
...
}
		
The Bad

// If action is an object then...
if (typeof action === 'object') {
   // If params is specified as function...
   if (capri.typeOf(params) === 'function')
      params = params();
...
}
		

We don't mind long comments provided that they are relevant!


// Long comments should wrap at around column 70ish to span multiple lines
// (unless there is only one word to wrap).

// This comment is one word over column 70 so doesn't need to be wrapped around.

Classes and namespaces can be split into logical sections using the following:


/* Namespaces:
-------------------------------------------------------------------*/

/* Utility Functions:
-------------------------------------------------------------------*/

Curly Brackets

We only use curly brackets when they are either absolutely necesssary, or lead to cleaner code that is easier to read. Curly brackets are not necessary for simple if or for statements.


if (typeof action === 'object')
   alert("It's an object!");

if (typeof action === 'object') {
   alert("It's an object!");
   accepted = true;
}

String Literals

There are two kinds of string literal; single quote and double quote. Where possible we prefer to use single quote literals, but it really doesn't matter. We use double quote literals for JSON encoded data.


// General string usage:
alert('Greetings!');

// Avoid nasty escape sequence on single quotes:
$('#output').html("You'll love our range of products!");
// Avoid nasty escape sequence on double quotes:
$('#output').html('<div class="alert">Thank you for your purchase!</div>');

// Some JSON encoded data
var jsonData = {
   "title"     : "IT",
   "author"    : "Stephen King",
   "publisher" : "Viking"
};

Identifiers

Type of identifier Example
Variables, fields and functions someIdentifier or prefix_someIdentifier
Constants and enumeration values SOME_IDENTIFIER or PREFIX_SOME_IDENTIFIER
Classes SomeIdentifier or Prefix_SomeIdentifier
Interfaces ISomeIdentifier or Prefix_ISomeIdentifier

Doclets

A doclet is a multi-line comment that preceeds with one extra star /** ... */. Doclets should contain a detailed explanation of the associated method, field, class, etc. These can be used to generate API documentation (like ours!).

We use a custom documentation generator called CapriDoc which is written in JavaScript and executed from the command-line using nodejs. There are several notable differences between jsdoc and CapriDoc:

  • CapriDoc has a shorter vocabulary of tags to avoid confusion.
  • CapriDoc is able to recognise the Capri way of defining classes and namespaces. This means that @namespace, @class and @lends tags do not need to be specified.

Unfortunately tab characters cannot be used inside doclets because they do not format properly in web browsers. Instead 3 spaces should be used in place of each tab.

View CapriDoc tag guide here.


/**
 * Append query string to URI
 *
 * @example
 * uri = capri.appendQueryString('http://example.com', 'a=b');
 * // http://example.com?a=b
 * uri = capri.appendQueryString('http://example.com?a=b', { "c": "d" });
 * // http://example.com?a=b&c=d
 *
 * @param {string} uri URI
 * @param {string|object} query Query arguments
 *
 * @returns {string} URI with additional query string
 *
 * @throws {capri.Error} Thrown when parameter is invalid
 */
capri.appendQueryString = function(uri, query) {
   if (typeof uri !== 'string')
      throw new capri.Error("Expected string for 'uri'", 'invalid_param');

   if (!!query) {
      if (typeof query !== 'string')
         query = capri.buildParamString(query);
      if (query)
         uri += (uri.indexOf('?') === -1 ? '?' : '&') + query;
   }
   return uri;
};