Guidelines and Recommendations
==============================

Web Module Recommendations
--------------------------

Identifiers (``id`` attribute) should be avoided
''''''''''''''''''''''''''''''''''''''''''''''''

In generic applications and modules, ``@id`` limits the reusabily of
components and tends to make code more brittle.

Just about all the time, they can be replaced with nothing, with
classes or with keeping a reference to a DOM node or a jQuery element
around.

.. note::

    If it is *absolutely necessary* to have an ``@id`` (because a
    third-party library requires one and can't take a DOM element), it
    should be generated with `_.uniqueId
    <http://underscorejs.org/#uniqueId>`_ or some other similar
    method.

Avoid predictable/common CSS class names
''''''''''''''''''''''''''''''''''''''''

Class names such as "content" or "navigation" might match the desired
meaning/semantics, but it is likely an other developer will have the
same need, creating a naming conflict and unintended behavior. Generic
class names should be prefixed with e.g. the name of the component
they belong to (creating "informal" namespaces, much as in C or
Objective-C)

Global selectors should be avoided
''''''''''''''''''''''''''''''''''

Because a component may be used several times in a single page (an
example in OpenERP is dashboards), queries should be restricted to a
given component's scope. Unfiltered selections such as ``$(selector)``
or ``document.querySelectorAll(selector)`` will generally lead to
unintended or incorrect behavior.

OpenERP Web's :js:class:`~openerp.web.Widget` has an attribute
providing its DOM root :js:attr:`Widget.$el <openerp.web.Widget.$el>`,
and a shortcut to select nodes directly :js:attr:`Widget.$
<openerp.web.Widget.$>`.

More generally, never assume your components own or controls anything
beyond its own personal DOM.

Understand deferreds
''''''''''''''''''''

Deferreds, promises, futures, …

Known under many names, these objects are essential to and (in OpenERP
Web) widely used for making :doc:`asynchronous javascript operations
<async>` palatable and understandable.

OpenERP Web guidelines
----------------------

* HTML templating/rendering should use :doc:`qweb` unless absolutely
  trivial.

* All interactive components (components displaying information to the
  screen or intercepting DOM events) must inherit from
  :class:`~openerp.web.Widget` and correctly implement and use its API
  and lifecycle.

* All css classes must be prefixed with *oe_* .

* Asynchronous functions (functions which call :ref:`session.rpc
  <rpc_rpc>` directly or indirectly at the very least) *must* return
  deferreds, so that callers of overriders can correctly synchronize
  with them.

New Javascript guidelines
-------------------------

From v11, we introduce a new coding standard for Odoo Javascript code.  Here it
is:

* add "use strict"; on top of every odoo JS module

* name all entities exported by a JS module. So, instead of 

  .. code-block:: javascript

      return Widget.extend({
        ...
      });

you should use:

  .. code-block:: javascript

      var MyWidget = Widget.extend({
        ...
      });

      return MyWidget

* there should be one space between function and the left parenthesis:

  .. code-block:: javascript

    function (a, b) {}

* JS files should have a (soft) limit of 80 chars width, and a hard limit of 100

* document every functions and every files, with the style JSDoc.

* for function overriding other functions, consider adding the tag @override in
  the JS Doc.  Also, you can mention which method is overridden:

  .. code-block:: javascript

    /**
     * When a save operation has been confirmed from the model, this method is
     * called.
     *
     * @override method from field manager mixin
     * @param {string} id
     * @returns {Deferred}
     */
    _confirmSave: function (id) {

* there should be an empty line between the main function comments and the tags,
  or parameter descriptions

* avoid introspection: don't build dynamically a method name and call it.  It is
  more fragile and more difficult to refactor

* methods should be private if possible

* never read an attribute of an attribute on somethig that you have a reference.
  So, this is not good:

  .. code-block:: javascript

    this.myObject.propA.propB

* never use a reference to the parent widget

* avoid using the 'include' functionality: extending a class is fine and does
  not cause issue, including a class is much more fragile, and may not work.

* For the widgets, here is how the various attributes/functions should be
  ordered:

  1. all static attributes, such as template, events, custom_events, ...

  2. all methods from the lifecycle of a widget, in this order: init, willStart,
     start, destroy

  3. If there are public methods, a section titled "Public", with an empty line
    before and after

  4. all public methods, camelcased, in alphabetic order

  5. If there are private methods, a section titled "Private", with an empty line
    before and after

  6. all private methods, camelcased and prefixed with _, in alphabetic order

  7. If there are event handlers, a section titled "Handlers", with an empty line
    before and after

  8. all handlers, camelcased and prefixed with _on, in alphabetic order

  9. If there are static methods, they should be in a section titled "Static".
     All static methods are considered public, camelcased with no _.

* write unit tests

* for the event handlers defined by the key 'event' or 'custom_events', don't
  inline the function.  Always add a string name, and add the definition in the
  handler section

* one space after if and for

* never call private methods on another object

* object definition on more than one line: each element should have a trailing
  comma.

* strings: double quotes for all textual strings (such as "Hello"), and single
  quotes for all other strings, such as a css selector '.o_form_view'

* always use this._super.apply(this, arguments);

* keys in an object: ordered by alphabetic order