===============================
    Coding Style Guidelines
===============================

This section concerns written code format in Tangelo, with the goal of clear,
readable, and consistent code.  The build process uses ``jshint`` and ``jscs``
to catch possible code and style errors.  This document describes some of the
coding practices employed to help make Tangelo more reliable.

Code Style Rules
----------------

Indentation
~~~~~~~~~~~

Indentation is used to provide visual cues about the syntactic scope
containing particular line of code. Good indentation practice
dramaticaly improves code readability.

**Four-space indentation.** Each additional indentation level shall be
exactly four spaces.

**Indentation policy.** The following structures shall require
incrementing the indentation level:

*Statements belonging to any block.*

*Chained function calls:*

::

    obj.call1()
        .call2()
        .call3();

*Properties in a literal object:*

::

    obj = {
        prop1: 10,
        prop2: 3
    };

**Curly bracket placement.** The left curly bracket that introduces a
new indentation level shall appear at the end of the line that uses it;
the right curly bracket that delimits the indented statements shall
appear on the line following the last indented statement, at the
decremented indentation:

::

    [some statement...] {
                        ^
        .
        .
        .
    }
    ^

Naming
~~~~~~

Use ``camelCase`` for visualization, property, method, and local variable names.

Curly brackets
~~~~~~~~~~~~~~

JavaScript uses curly brackets to delimit blocks. Blocks are required by
the language when functions are defined. They are also required for
executing more than one statement within control flow constructs such as
``if`` and ``while``. While the option exists *not* to use curly
brackets for a single statement in such cases, that practice can lead to
errors (when, e.g., a new feature requires the single statement to be
replaced by several statements).

**Always use blocks in control flow statements.** Every use of control
flow operators (``if``, ``while``, ``do``) shall use curly brackets for
its associated statement block, even if only a single statement appears
therein.

Space placement
~~~~~~~~~~~~~~~

Parentheses are required in several places in JavaScript. Proper space
placement can help make such constructs more readable.

**Keyword-condition separation.** A single space shall appear in the
following situations.

*Between a control-flow operator and its parenthesized condition:*

::

    if (condition...) {
      ^

*Between a parenthesized condition and its following curly bracket:*

::

    if (condition...) {
                     ^

*Between a function argument list and its following curly bracket:*

::

    function foobar(x, y, z) {
                            ^

*Between the* ``function`` *keyword and the argument list, in anonymous
functions:*

::

    f = function (a, b) {
                ^

*After every comma.*

*On either side of a binary operator:*

::

    x = 3 + 4;
         ^ ^

**Extraneous spaces.** The last character in any given line shall not be
a space.

**Blank lines.** Blank lines should be used to set apart sequences of
statements that logically belong together.

Chained if/else-if/else statements
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

A common programming pattern is to test a sequence of conditions,
selecting a single action to take when one of them is satisfied. In
JavaScript, this is accomplished with an ``if`` block followed by a
number of ``else if`` blocks, followed by an ``else`` block.
``try catch`` blocks have a similar syntax.

**Single line** ``else if``, ``else``, **and** ``catch``. The ``else if``,
``else``, and ``catch`` keyword phrases shall appear on a single line,
with a right curly bracket on their left and a left curly bracket on
their right:

::

    if (condition) {
        action();
    } else if {
        other_action();
    } else {
        default_action();
    }

``new Array`` and ``new Object``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The ``new`` keyword is problematic in JavaScript. If it is omitted by
mistake, the code will run without error, but will not do the right
thing. Furthermore, built in constructors like ``Array`` and ``Object``
can be reimplemented by other code.

**Use** ``[]`` **and** ``{}``. All construction of arrays and objects shall
use the literal ``[]`` and ``{}`` syntax. The sequence of statements
``x = [];``, then ``x.length = N;`` shall replace ``new Array(N)``.

Code structure
--------------

This section concerns the structure of functions and modules, how
constructs at a larger scale than individual statements and expressions
should be handled.

JSLint directives
~~~~~~~~~~~~~~~~~

JSLint reads two special comments appearing at the top of files it is
working on. The first appears in the following form:

::

    /*jslint browser: true */

and specifies options to JSLint. Because Tangelo is a web project,
every JavaScript file should have the comment that appears above as the
first line. The other recognized directive in the global name list:

::

    /*globals d3, $, FileReader */

This directive prevents JSLint from complaining that the listed names
are global variables, or undefined. It is meant for valid names, such as
standard library objects or linked libraries used in the file.

Lexical scopes
~~~~~~~~~~~~~~

JavaScript has only two scope levels: *global* and *function*. In
particular, blocks following, e.g., ``for`` and ``if`` statements *do
not introduce an inner scope*. Despite this fact, JavaScript allows for
variables to be declared within such blocks, causing seasoned C and C++
programmers to assume something false about the lifetime of such
variables.

**Single** ``var`` **declaration.** Every function shall contain a single
``var`` declaration as its first statement, which shall list every local
variable used by that function, listed one per line.

::

    function foobar(){
        var width,
            height,
            i;
        .
        .
        .
    }

This declaration statement shall **not** include any initializers (this
promotes clearer coding, as the "initializers" can be moved below the
declaration, and each one can retain its own comment to explain the
initialization).

**Global variables.** Global variables shall **not** be used, unless as
a namespace-like container for variables and names that would otherwise
have to be global. When such namespace-like containers are used in a
JavaScript file, they shall appear in the JSLint global name specifier.

Strict Mode
~~~~~~~~~~~

JavaScript has a "strict mode" that disallows certain actions
technically allowed by the language. These are such things as using
variables before they are defined, etc. It can be enabled by including
``"use strict";`` as the first statement in any function:

::

    function foobaz() {
        "use strict";

        .
        .
        .
    }

**Strict mode functions.** All functions shall be written to use strict
mode.

A note on ``try...catch`` blocks
--------------------------------

JSLint complains if the exception name bound to a ``catch`` block is the
same as the exception name bound to a previous ``catch`` block. This is
due to an ambiguity in the ECMAScript standard regarding the semantics
of ``try...catch`` blocks. Because using a unique exception name in each
``catch`` block just to avoid errors from JSLint seems to introduce just
as much confusion as it avoids, the current practice is **not** to use
unique exception names for each ``catch`` block.

**Use** ``e`` **for exception name.** ``catch`` blocks may all use the name
``e`` for the bound exception, to aid in scanning over similar messages
in the JSLint output. **This rule is subject to change in the future.**

A note on *"eval is evil"*
--------------------------

JSLint claims that ``eval`` is evil. However, it is actually
*dangerous*, and not evil. Accordingly, ``eval`` should be kept away
from most JavaScript code. However, to take one example, one of 
Tangelo's main dependencies, Vega, makes use of compiler technology that generates
JavaScript code. ``eval``\ ing this code is reasonable and necessary in
this instance.

**eval is misunderstood.** If a JavaScript file needs to make use of
``eval``, it shall insert an ``evil: true`` directive into the JSLint
options list. All other JavaScript files shall **not** make use of
``eval``.
