[DOC] use a flat (i.e. no source/ directory) structure.
authorOpenerp Online <online@openerp.com>
Mon, 5 Mar 2012 12:40:16 +0000 (13:40 +0100)
committerOpenerp Online <online@openerp.com>
Mon, 5 Mar 2012 12:40:16 +0000 (13:40 +0100)
bzr revid: online@openerp.com-20120305124016-d25rncl3q2qcem31

42 files changed:
doc/Makefile
doc/_templates/sidebarintro.html
doc/addon-structure.txt [new file with mode: 0644]
doc/addons.rst [new file with mode: 0644]
doc/conf.py
doc/development.rst [new file with mode: 0644]
doc/getting-started.rst [new file with mode: 0644]
doc/guides/client-action.rst [new file with mode: 0644]
doc/guides/sidebar-protocol.rst [new file with mode: 0644]
doc/index.rst
doc/make.bat
doc/old-version.rst [new file with mode: 0644]
doc/production.rst [new file with mode: 0644]
doc/project.rst [new file with mode: 0644]
doc/source/Makefile [deleted file]
doc/source/_static/openerp.png [deleted file]
doc/source/_templates/sidebarintro.html [deleted file]
doc/source/_templates/sidebarlogo.html [deleted file]
doc/source/_themes/LICENSE [deleted file]
doc/source/_themes/README [deleted file]
doc/source/_themes/flask/layout.html [deleted file]
doc/source/_themes/flask/relations.html [deleted file]
doc/source/_themes/flask/static/flasky.css_t [deleted file]
doc/source/_themes/flask/static/small_flask.css [deleted file]
doc/source/_themes/flask/theme.conf [deleted file]
doc/source/_themes/flask_small/layout.html [deleted file]
doc/source/_themes/flask_small/static/flasky.css_t [deleted file]
doc/source/_themes/flask_small/theme.conf [deleted file]
doc/source/_themes/flask_theme_support.py [deleted file]
doc/source/addon-structure.txt [deleted file]
doc/source/addons.rst [deleted file]
doc/source/conf.py [deleted file]
doc/source/development.rst [deleted file]
doc/source/getting-started.rst [deleted file]
doc/source/guides/client-action.rst [deleted file]
doc/source/guides/sidebar-protocol.rst [deleted file]
doc/source/index.rst [deleted file]
doc/source/old-version.rst [deleted file]
doc/source/production.rst [deleted file]
doc/source/project.rst [deleted file]
doc/source/widgets.rst [deleted file]
doc/widgets.rst [new file with mode: 0644]

index 8afc4d9..c1eff18 100644 (file)
@@ -2,7 +2,7 @@
 #
 
 # You can set these variables from the command line.
-SPHINXOPTS    =
+SPHINXOPTS    = -q
 SPHINXBUILD   = sphinx-build
 PAPER         =
 BUILDDIR      = _build
index 4d4dcc8..d61f341 100644 (file)
@@ -5,7 +5,7 @@
 <h3>Other Docs</h3>
 <ul>
   <li><a href="http://doc.openerp.com/v6.1/developers">OpenERP Developers Documentation</a></li>
-  <li><a href="http://doc.openerp.com/v6.1/developers/web">OpenERP Web Developers Documentation</a></li>
+  <li><a href="http://doc.openerp.com/v6.1/developers/server">OpenERP Server Developers Documentation</a></li>
   <li><a href="http://doc.openerp.com/v6.1/users">OpenERP Users Documentation</a></li>
 </ul>
 
diff --git a/doc/addon-structure.txt b/doc/addon-structure.txt
new file mode 100644 (file)
index 0000000..3815174
--- /dev/null
@@ -0,0 +1,12 @@
+<addon name>
+  +-- __openerp__.py
+  +-- controllers/
+  +-- static/
+       +-- lib/
+       +-- src/
+            +-- css/
+            +-- img/
+            +-- js/
+            +-- xml/
+       +-- test/
+  +-- test/
diff --git a/doc/addons.rst b/doc/addons.rst
new file mode 100644 (file)
index 0000000..da1f1f2
--- /dev/null
@@ -0,0 +1,558 @@
+Developing OpenERP Web Addons
+=============================
+
+An OpenERP Web addon is simply a Python package with an openerp
+descriptor (a ``__openerp__.py`` file) which follows a few structural
+and namespacing rules.
+
+Structure
+---------
+
+.. literalinclude:: addon-structure.txt
+
+``__openerp__.py``
+  The addon's descriptor, contains the following information:
+
+  ``name: str``
+    The addon name, in plain, readable english
+  ``version: str``
+    The addon version, following `Semantic Versioning`_ rules
+  ``depends: [str]``
+    A list of addons this addon needs to work correctly. ``base`` is
+    an implied dependency if the list is empty.
+  ``css: [str]``
+    An ordered list of CSS files this addon provides and needs. The
+    file paths are relative to the addon's root. Because the Web
+    Client *may* perform concatenations and other various
+    optimizations on CSS files, the order is important.
+  ``js: [str]``
+    An ordered list of Javascript files this addon provides and needs
+    (including dependencies files). As with CSS files, the order is
+    important as the Web Client *may* perform contatenations and
+    minimizations of files.
+  ``active: bool``
+    Whether this addon should be enabled by default any time it is
+    found, or whether it will be enabled through other means (on a
+    by-need or by-installation basis for instance).
+
+``controllers/``
+  All of the Python controllers and JSON-RPC endpoints.
+
+``static/``
+  The static files directory, may be served via a separate web server.
+
+``static/lib/``
+  Third-party libraries used by the addon.
+
+``static/src/{css,js,img,xml}``
+  Location for (respectively) the addon's static CSS files, its JS
+  files, its various image resources as well as the template files
+
+``static/test``
+  Javascript tests files
+
+``test/``
+  The directories in which all tests for the addon are located.
+
+Some of these are guidelines (and not enforced by code), but it's
+suggested that these be followed. Code which does not fit into these
+categories can go wherever deemed suitable.
+
+Namespacing
+-----------
+
+Python
+++++++
+
+Because addons are also Python packages, they're inherently namespaced
+and nothing special needs to be done on that front.
+
+JavaScript
+++++++++++
+
+The JavaScript side of an addon has to live in the namespace
+``openerp.$addon_name``. For instance, everything created by the addon
+``base`` lives in ``openerp.base``.
+
+The root namespace of the addon is a function which takes a single
+parameter ``openerp``, which is an OpenERP client instance. Objects
+(as well as functions, registry instances, etc...) should be added on
+the correct namespace on that object.
+
+The root function will be called by the OpenERP Web client when
+initializing the addon.
+
+.. code-block:: javascript
+
+    // root namespace of the openerp.example addon
+    /** @namespace */
+    openerp.example = function (openerp) {
+        // basic initialization code (e.g. templates loading)
+        openerp.example.SomeClass = openerp.base.Class.extend(
+            /** @lends openerp.example.SomeClass# */{
+            /**
+             * Description for SomeClass's constructor here
+             *
+             * @constructs
+             */
+            init: function () {
+                // SomeClass initialization code
+            }
+            // rest of SomeClass
+        });
+
+        // access an object in an other addon namespace to replace it
+        openerp.base.SearchView = openerp.base.SearchView.extend({
+            init: function () {
+                this._super.apply(this, arguments);
+                console.log('Search view initialized');
+            }
+        });
+    }
+
+Creating new standard roles
+---------------------------
+
+Widget
+++++++
+
+This is the base class for all visual components. It provides a number of
+services for the management of a DOM subtree:
+
+* Rendering with QWeb
+
+* Parenting-child relations
+
+* Life-cycle management (including facilitating children destruction when a
+  parent object is removed)
+
+* DOM insertion, via jQuery-powered insertion methods. Insertion targets can
+  be anything the corresponding jQuery method accepts (generally selectors,
+  DOM nodes and jQuery objects):
+
+  :js:func:`~openerp.base.Widget.appendTo`
+    Renders the widget and inserts it as the last child of the target, uses
+    `.appendTo()`_
+
+  :js:func:`~openerp.base.Widget.prependTo`
+    Renders the widget and inserts it as the first child of the target, uses
+    `.prependTo()`_
+
+  :js:func:`~openerp.base.Widget.insertAfter`
+    Renders the widget and inserts it as the preceding sibling of the target,
+    uses `.insertAfter()`_
+
+  :js:func:`~openerp.base.Widget.insertBefore`
+    Renders the widget and inserts it as the following sibling of the target,
+    uses `.insertBefore()`_
+
+:js:class:`~openerp.base.Widget` inherits from
+:js:class:`~openerp.base.SessionAware`, so subclasses can easily access the
+RPC layers.
+
+Subclassing Widget
+~~~~~~~~~~~~~~~~~~
+
+:js:class:`~openerp.base.Widget` is subclassed in the standard manner (via the
+:js:func:`~openerp.base.Class.extend` method), and provides a number of
+abstract properties and concrete methods (which you may or may not want to
+override). Creating a subclass looks like this:
+
+.. code-block:: javascript
+
+    var MyWidget = openerp.base.Widget.extend({
+        // QWeb template to use when rendering the object
+        template: "MyQWebTemplate",
+
+        init: function(parent) {
+            this._super(parent);
+            // insert code to execute before rendering, for object
+            // initialization
+        },
+        start: function() {
+            this._super();
+            // post-rendering initialization code, at this point
+            // ``this.$element`` has been initialized
+            this.$element.find(".my_button").click(/* an example of event binding * /);
+
+            // if ``start`` is asynchronous, return a promise object so callers
+            // know when the object is done initializing
+            return this.rpc(/* … */)
+        }
+    });
+
+The new class can then be used in the following manner:
+
+.. code-block:: javascript
+
+    // Create the instance
+    var my_widget = new MyWidget(this);
+    // Render and insert into DOM
+    my_widget.appendTo(".some-div");
+
+After these two lines have executed (and any promise returned by ``appendTo``
+has been resolved if needed), the widget is ready to be used.
+
+.. note:: the insertion methods will start the widget themselves, and will
+          return the result of :js:func:`~openerp.base.Widget.start()`.
+
+          If for some reason you do not want to call these methods, you will
+          have to first call :js:func:`~openerp.base.Widget.render()` on the
+          widget, then insert it into your DOM and start it.
+
+If the widget is not needed anymore (because it's transient), simply terminate
+it:
+
+.. code-block:: javascript
+
+    my_widget.stop();
+
+will unbind all DOM events, remove the widget's content from the DOM and
+destroy all widget data.
+
+Views
++++++
+
+Views are the standard high-level component in OpenERP. A view type corresponds
+to a way to display a set of data (coming from an OpenERP model).
+
+In OpenERP Web, views are standard objects registered against a dedicated
+object registry, so the :js:class:`~openerp.base.ViewManager` knows where to
+find and how to call them.
+
+Although not mandatory, it is recommended that views inherit from
+:js:class:`openerp.base.View`, which provides a view useful services to its
+children.
+
+Registering a view
+~~~~~~~~~~~~~~~~~~
+
+This is the first task to perform when creating a view, and the simplest by
+far: simply call ``openerp.base.views.add(name, object_path)`` to register
+the object of path ``object_path`` as the view for the view name ``name``.
+
+The view name is the name you gave to your new view in the OpenERP server.
+
+From that point onwards, OpenERP Web will be able to find your object and
+instantiate it.
+
+Standard view behaviors
+~~~~~~~~~~~~~~~~~~~~~~~
+
+In the normal OpenERP Web flow, views have to implement a number of methods so
+view managers can correctly communicate with them:
+
+``start()``
+    This method will always be called after creating the view (via its
+    constructor), but not necessarily immediately.
+
+    It is called with no arguments and should handle the heavy setup work,
+    including remote call (to load the view's setup data from the server via
+    e.g. ``fields_view_get``, for instance).
+
+    ``start`` should return a `promise object`_ which *must* be resolved when
+    the view's setup is completed. This promise is used by view managers to
+    know when they can start interacting with the view.
+
+``do_hide()``
+    Called by the view manager when it wants to replace this view by an other
+    one, but wants to keep this view around to re-activate it later.
+
+    Should put the view in some sort of hibernation mode, and *must* hide its
+    DOM elements.
+
+``do_show()``
+    Called when the view manager wants to re-display the view after having
+    hidden it. The view should refresh its data display upon receiving this
+    notification
+
+``do_search(domain: Array, context: Object, group_by: Array)``
+    If the view is searchable, this method is called to notify it of a search
+    against it.
+
+    It should use the provided query data to perform a search and refresh its
+    internal content (and display).
+
+    All views are searchable by default, but they can be made non-searchable
+    by setting the property ``searchable`` to ``false``.
+
+    This can be done either on the view class itself (at the same level as
+    defining e.g. the ``start`` method) or at the instance level (in the
+    class's ``init``), though you should generally set it on the class.
+
+Frequent development tasks
+--------------------------
+
+There are a number of tasks which OpenERP Web developers do or will need to
+perform quite regularly. To make these easier, we have written a few guides
+to help you get started:
+
+.. toctree::
+    :maxdepth: 1
+
+    guides/client-action
+    guides/sidebar-protocol
+
+Translations
+------------
+
+OpenERP Web should provide most of the tools needed to correctly translate your
+addons via the tool of your choice (OpenERP itself uses `Launchpad's own
+translation tool`_.
+
+Making strings translatable
++++++++++++++++++++++++++++
+
+QWeb
+~~~~
+
+QWeb automatically marks all text nodes (any text which is not in an XML
+attribute and not part of an XML tag) as translatable, and handles the
+replacement for you. There is nothing special to do to mark template text as
+translatable
+
+JavaScript
+~~~~~~~~~~
+
+OpenERP Web provides two functions to translate human-readable strings in
+javascript code. These functions should be "imported" in your module by
+aliasing them to their bare name:
+
+.. code-block:: javascript
+
+    var _t = openerp.web._t,
+       _tl = openerp.web._tl;
+
+importing those functions under any other name is not guaranteed to work.
+
+.. note:: only import them if necessary, and only the necessary one(s), no need
+          to clutter your module's namespace for nothing
+
+.. js:function:: openerp.web._t(s)
+
+    Base translation function, eager, works much like :manpage:`gettext(3)`
+
+    :type s: String
+    :rtype: String
+
+.. js:function:: openerp.web._lt(s)
+
+    Lazy equivalent to :js:func:`~openerp.web._t`, this function will postpone
+    fetching the translation to its argument until the last possible moment.
+
+    To use in contexts evaluated before the translation database can be
+    fetched, usually your module's toplevel and the attributes of classes
+    defined in it (class attributes, not instance attributes set in the
+    constructor).
+
+    :type s: String
+    :rtype: LazyString
+
+Text formatting & translations
+""""""""""""""""""""""""""""""
+
+A difficulty when translating is integrating data (from the code) into the
+translated string. In OpenERP Web addons, this should be done by wrapping the
+text to translate in an :manpage:`sprintf(3)` call. For OpenERP Web,
+:manpage:`sprintf(3)` is provided by `underscore.string
+<http://epeli.github.com/underscore.string/>`_.
+
+As much as possible, you should use the "named argument" form of sprintf:
+
+.. code-block:: javascript
+
+    var translated_string = _.str.sprintf(
+        _t("[%(first_record)d to %(last_record)d] of %(records_count)d"), {
+            first_record: first + 1,
+            last_record: last,
+            records_count: total
+        }));
+
+named arguments make the string to translate much clearer for translators, and
+allows them to "move" sections around based on the requirements of their
+language (not all language order text like english).
+
+Named arguments are specified using the following pattern: ``%($name)$type``
+where
+
+``$name``
+  the name of the argument, this is the key in the object/dictionary provided
+  as second parameter to ``sprintf``
+``$type``
+  a type/format specifier, `see the list for all possible types
+  <http://www.diveintojavascript.com/projects/javascript-sprintf>`_.
+
+.. note:: positional arguments are acceptable if the translated string has
+          *a single* argument and its content is easy to guess from the text
+          around it. Named arguments should still be preferred.
+
+.. warning:: you should *never* use string concatenation as it robs the
+             translator of context and make result in a completely incorrect
+             translation
+
+Extracting strings
+~~~~~~~~~~~~~~~~~~
+
+.. program:: gen_translations.sh
+
+Once strings have been marked for translation, they need to be extracted into
+:abbr:`POT (Portable Object Template)` files, from which most translation tools
+can build a database.
+
+This can be done via the provided :program:`gen_translations.sh`.
+
+It can be called either as :option:`gen_translations.sh -a` or by providing
+two parameters, a path to the addons and the complete path in which to put the
+extracted POT file.
+
+.. option:: -a
+
+    Extracts translations from all standard OpenERP Web addons (addons bundled
+    with OpenERP Web itself) and puts the extracted templates into the right
+    directory for `Rosetta`_ to handle them
+
+Utility behaviors
+-----------------
+
+JavaScript
+++++++++++
+
+* All javascript objects inheriting from
+  :js:class:`openerp.base.BasicConroller` will have all methods
+  starting with ``on_`` or ``do_`` bound to their ``this``. This means
+  they don't have to be manually bound (via ``_.bind`` or ``$.proxy``)
+  in order to be useable as bound event handlers (event handlers
+  keeping their object as ``this`` rather than taking whatever
+  ``this`` object they were called with).
+
+  Beware that this is only valid for methods starting with ``do_`` and
+  ``on_``, any other method will have to be bound manually.
+
+.. _addons-testing:
+
+Testing
+-------
+
+Python
+++++++
+
+OpenERP Web uses unittest2_ for its testing needs. We selected
+unittest2 rather than unittest_ for the following reasons:
+
+* autodiscovery_ (similar to nose, via the ``unit2``
+  CLI utility) and `pluggable test discovery`_.
+
+* `new and improved assertions`_ (with improvements in type-specific
+  inequality reportings) including `pluggable custom types equality
+  assertions`_
+
+* neveral new APIs, most notably `assertRaises context manager`_,
+  `cleanup function registration`_, `test skipping`_ and `class- and
+  module-level setup and teardown`_
+
+* finally, unittest2 is a backport of Python 3's unittest. We might as
+  well get used to it.
+
+To run tests on addons (from the root directory of OpenERP Web) is as
+simple as typing ``PYTHONPATH=. unit2 discover -s addons`` [#]_. To
+test an addon which does not live in the ``addons`` directory, simply
+replace ``addons`` by the directory in which your own addon lives.
+
+.. note:: unittest2 is entirely compatible with nose_ (or the
+     other way around). If you want to use nose as your test
+     runner (due to its addons for instance) you can simply install it
+     and run ``nosetests addons`` instead of the ``unit2`` command,
+     the result should be exactly the same.
+
+Python
+++++++
+
+.. autoclass:: web.common.session.OpenERPSession
+    :members:
+
+.. autoclass:: web.common.openerplib.main.Model
+    :members:
+
+* Addons lifecycle (loading, execution, events, ...)
+
+  * Python-side
+  * JS-side
+
+* Handling static files
+* Overridding a Python controller (object?)
+* Overridding a Javascript controller (object?)
+* Extending templates
+  .. how do you handle deploying static files via e.g. a separate lighttpd?
+* Python public APIs
+* QWeb templates description?
+* OpenERP Web modules (from OpenERP modules)
+
+.. [#] the ``-s`` parameter tells ``unit2`` to start trying to
+       find tests in the provided directory (here we're testing
+       addons). However a side-effect of that is to set the
+       ``PYTHONPATH`` there as well, so it will fail to find (and
+       import) ``openerpweb``.
+
+       The ``-t`` parameter lets us set the ``PYTHONPATH``
+       independently, but it doesn't accept multiple values and here
+       we really want to have both ``.`` and ``addons`` on the
+       ``PYTHONPATH``.
+
+       The solution is to set the ``PYTHONPATH`` to ``.`` on start,
+       and the ``start-directory`` to ``addons``. This results in a
+       correct ``PYTHONPATH`` within ``unit2``.
+
+.. _unittest:
+    http://docs.python.org/library/unittest.html
+
+.. _unittest2:
+    http://www.voidspace.org.uk/python/articles/unittest2.shtml
+
+.. _autodiscovery:
+    http://www.voidspace.org.uk/python/articles/unittest2.shtml#test-discovery
+
+.. _pluggable test discovery:
+    http://www.voidspace.org.uk/python/articles/unittest2.shtml#load-tests
+
+.. _new and improved assertions:
+    http://www.voidspace.org.uk/python/articles/unittest2.shtml#new-assert-methods
+
+.. _pluggable custom types equality assertions:
+    http://www.voidspace.org.uk/python/articles/unittest2.shtml#add-new-type-specific-functions
+
+.. _assertRaises context manager:
+    http://www.voidspace.org.uk/python/articles/unittest2.shtml#assertraises
+
+.. _cleanup function registration:
+    http://www.voidspace.org.uk/python/articles/unittest2.shtml#cleanup-functions-with-addcleanup
+
+.. _test skipping:
+    http://www.voidspace.org.uk/python/articles/unittest2.shtml#test-skipping
+
+.. _class- and module-level setup and teardown:
+    http://www.voidspace.org.uk/python/articles/unittest2.shtml#class-and-module-level-fixtures
+
+.. _Semantic Versioning:
+    http://semver.org/
+
+.. _nose:
+    http://somethingaboutorange.com/mrl/projects/nose/1.0.0/
+
+.. _promise object:
+    http://api.jquery.com/deferred.promise/
+
+.. _.appendTo():
+    http://api.jquery.com/appendTo/
+
+.. _.prependTo():
+    http://api.jquery.com/prependTo/
+
+.. _.insertAfter():
+    http://api.jquery.com/insertAfter/
+
+.. _.insertBefore():
+    http://api.jquery.com/insertBefore/
+
+.. _Rosetta:
+.. _Launchpad's own translation tool:
+    https://help.launchpad.net/Translations
index 9e08b5f..d745299 100644 (file)
@@ -16,9 +16,9 @@ import sys, os
 # If extensions (or modules to document with autodoc) are in another directory,
 # add these directories to sys.path here. If the directory is relative to the
 # documentation root, use os.path.abspath to make it absolute, like shown here.
-#sys.path.insert(0, os.path.abspath('.'))
 sys.path.append(os.path.abspath('_themes'))
-sys.path.append(os.path.abspath('..'))
+sys.path.insert(0, os.path.abspath('../addons'))
+sys.path.insert(0, os.path.abspath('..'))
 
 # -- General configuration -----------------------------------------------------
 
@@ -42,7 +42,7 @@ source_suffix = '.rst'
 master_doc = 'index'
 
 # General information about the project.
-project = u'OpenERP Server Developers Documentation'
+project = u'OpenERP Web Developers Documentation'
 copyright = u'2012, OpenERP s.a.'
 
 # The version info for the project you're documenting, acts as replacement for
@@ -170,7 +170,7 @@ html_sidebars = {
 #html_file_suffix = None
 
 # Output file base name for HTML help builder.
-htmlhelp_basename = 'openerp-server-doc'
+htmlhelp_basename = 'openerp-web-doc'
 
 
 # -- Options for LaTeX output --------------------------------------------------
@@ -189,7 +189,7 @@ latex_elements = {
 # Grouping the document tree into LaTeX files. List of tuples
 # (source start file, target name, title, author, documentclass [howto/manual]).
 latex_documents = [
-  ('index', 'openerp-server-doc.tex', u'OpenERP Server Developers Documentation',
+  ('index', 'openerp-web-doc.tex', u'OpenERP Web Developers Documentation',
    u'OpenERP s.a.', 'manual'),
 ]
 
@@ -219,7 +219,7 @@ latex_documents = [
 # One entry per manual page. List of tuples
 # (source start file, name, description, authors, manual section).
 man_pages = [
-    ('index', 'openerp-server-doc', u'OpenERP Server Developers Documentation',
+    ('index', 'openerp-web-doc', u'OpenERP Web Developers Documentation',
      [u'OpenERP s.a.'], 1)
 ]
 
@@ -233,8 +233,8 @@ man_pages = [
 # (source start file, target name, title, author,
 #  dir menu entry, description, category)
 texinfo_documents = [
-  ('index', 'OpenERPServerDocumentation', u'OpenERP Server Developers Documentation',
-   u'OpenERP s.a.', 'OpenERPServerDocumentation', 'Developers documentation for the openobject-server project.',
+  ('index', 'OpenERPWebDocumentation', u'OpenERP Web Developers Documentation',
+   u'OpenERP s.a.', 'OpenERPWebDocumentation', 'Developers documentation for the openerp-web project.',
    'Miscellaneous'),
 ]
 
@@ -250,5 +250,7 @@ texinfo_documents = [
 
 # Example configuration for intersphinx: refer to the Python standard library.
 intersphinx_mapping = {
-    'http://docs.python.org/': None,
-    }
+    'python': ('http://docs.python.org/', None),
+    'openerpserver': ('http://doc.openerp.com/v6.1/developers/server', None),
+    'openerpdev': ('http://doc.openerp.com/v6.1/developers', None),
+}
diff --git a/doc/development.rst b/doc/development.rst
new file mode 100644 (file)
index 0000000..7431a3e
--- /dev/null
@@ -0,0 +1,424 @@
+OpenERP Web Core and standard addons
+====================================
+
+* General organization and core ideas (design philosophies)
+* Internal documentation, autodoc, Python and JS domains
+* QWeb code documentation/description
+* Documentation of the OpenERP APIs and choices taken based on that?
+* Style guide and coding conventions (PEP8? More)
+* Test frameworks in JS?
+
+Standard Views
+--------------
+
+Search View
++++++++++++
+
+The OpenERP search view really is a sub-view, used in support of views
+acting on collections of records (list view or graph view, for
+instance).
+
+Its main goal is to collect information from its widgets (themselves
+collecting information from the users) and make those available to the
+rest of the client.
+
+The search view's root is :js:class:`~openerp.base.SearchView`. This
+object should never need to be created or managed directly, its
+lifecycle should be driven by the
+:js:class:`~openerp.base.ViewManager`.
+
+.. TODO: insert SearchView constructor here
+
+The search view defines a number of internal and external protocols to
+communicate with the objects around and within it. Most of these
+protocols are informal, and types available for inheritance are more
+mixins than mandatory.
+
+Events
+""""""
+
+``on_loaded``
+
+  .. TODO: method openerp.base.SearchView.on_loaded
+
+  Fires when the search view receives its view data (the result of
+  ``fields_view_get``). Hooking up before the event allows for
+  altering view data before it can be used.
+
+  By the time ``on_loaded`` is done, the search view is guaranteed to
+  be fully set up and ready to use.
+
+``on_search``
+
+  .. TODO: method openerp.base.SearchView.on_search
+
+  Event triggered after a user asked for a search. The search view
+  fires this event after collecting all input data (contexts, domains
+  and group_by contexts). Note that the search view does *not* merge
+  those (or otherwise evaluate them), they are returned as provided by
+  the various inputs within the view.
+
+``on_clear``
+
+  .. TODO: method openerp.base.SearchView.on_clear
+
+  Triggered after a user asked for a form clearing.
+
+Input management
+""""""""""""""""
+
+An important concept in the search view is that of input. It is both
+an informal protocol and an abstract type that can be inherited from.
+
+Inputs are widgets which can contain user data (a char widget for
+instance, or a selection box). They are capable of action and of
+reaction:
+
+.. _views-search-registration:
+
+``registration``
+
+  This is an input action. Inputs have to register themselves to the
+  main view (which they receive as a constructor argument). This is
+  performed by pushing themselves on the
+  :js:attr:`openerp.base.SearchView.inputs` array.
+
+``get_context``
+
+  An input reaction. When it needs to collect contexts, the view calls
+  ``get_context()`` on all its inputs.
+
+  Inputs can react in the following manners:
+
+  * Return a context (an object), this is the "normal" response if the
+    input holds a value.
+
+  * Return a value that evaluates as false (generally ``null``). This
+    value indicates the input does not contain any value and will not
+    affect the results of the search.
+
+  * Raise :js:class:`openerp.base.search.Invalid` to indicate that it
+    holds a value but this value can not be used in the search
+    (because it is incorrectly formatted or nonsensical). Raising
+    :js:class:`~openerp.base.search.Invalid` is guaranteed to cancel
+    the search process.
+
+    :js:class:`~openerp.base.search.Invalid` takes three mandatory
+    arguments: an identifier (a name for instance), the invalid value,
+    and a validation message indicating the issue.
+
+``get_domain``
+
+  The second input reaction, the possible behaviors of inputs are the
+  same as for ``get_context``.
+
+The :js:class:`openerp.base.search.Input` type implements registration
+on its own, but its implementations of ``get_context`` and
+``get_domain`` simply raise errors and *must* be overridden.
+
+One last action is for filters, as an activation order has to be kept
+on them for some controls (to establish the correct grouping sequence,
+for instance).
+
+To that end, filters can call
+:js:func:`openerp.base.Search.do_toggle_filter`, providing themselves
+as first argument.
+
+Filters calling :js:func:`~openerp.base.Search.do_toggle_filter` also
+need to implement a method called
+:js:func:`~openerp.base.search.Filter.is_enabled`, which the search
+view will use to know the current status of the filter.
+
+The search view automatically triggers a search after calls to
+:js:func:`~openerp.base.Search.do_toggle_filter`.
+
+Life cycle
+""""""""""
+
+The search view has a pretty simple and linear life cycle, in three main steps:
+
+:js:class:`~openerp.base.SearchView.init`
+
+  Nothing interesting happens here
+
+:js:func:`~openerp.base.SearchView.start`
+
+  Called by the main view's creator, this is the main initialization
+  step for the list view.
+
+  It begins with a remote call to fetch the view's descriptors
+  (``fields_view_get``).
+
+  Once the remote call is complete, the ``on_loaded`` even happens,
+  holding three main operations:
+
+  :js:func:`~openerp.base.SearchView.make_widgets`
+
+    Builds and returns the top-level widgets of the search
+    view. Because it returns an array of widget lines (a 2-dimensional
+    matrix of widgets) it should be called recursively by container
+    widgets (:js:class:`openerp.base.search.Group` for instance).
+
+  :js:func:`~openerp.base.search.Widget.render`
+
+    Called by the search view on all top-level widgets. Container
+    widgets should recursively call this method on their own children
+    widgets.
+
+    Widgets are provided with a mapping of ``{name: value}`` holding
+    default values for the search view. They can freely pick their
+    initial values from there, but must pass the mapping to their
+    children widgets if they have any.
+
+  :js:func:`~openerp.base.search.Widget.start`
+
+    The last operation of the search view startup is to initialize all
+    its widgets in order. This is again done recursively (the search
+    view starts its children, which have to start their own children).
+
+:js:func:`~openerp.base.SearchView.stop`
+
+  Used before discarding a search view, allows the search view to
+  disable its events and pass the message to its own widgets,
+  gracefully shutting down the whole view.
+
+Widgets
+"""""""
+
+In a search view, the widget is simply a unit of display.
+
+All widgets must be able to react to three events, which will be
+called in this order:
+
+:js:func:`~openerp.base.search.Widget.render`
+
+  Called with a map of default values. The widget must return a
+  ``String``, which is its HTML representation. That string can be
+  empty (if the widget should not be represented).
+
+  Widgets are responsible for asking their children for rendering, and
+  for passing along the default values.
+
+:js:func:`~openerp.base.search.Widget.start`
+
+  Called without arguments. At this point, the widget has been fully
+  rendered and can set its events up, if any.
+
+  The widget is responsible for starting its children, if it has any.
+
+:js:func:`~openerp.base.search.Widget.stop`
+
+  Gives the widget the opportunity to unbind its events, remove itself
+  from the DOM and perform any other cleanup task it may have.
+
+  Even if the widget does not do anything itself, it is responsible
+  for shutting down its children.
+
+An abstract type is available and can be inherited from, to simplify
+the implementation of those tasks:
+
+.. TODO: insert Widget here
+
+.. remember to document all methods
+
+Inputs
+""""""
+
+The search namespace (``openerp.base.search``) provides two more
+abstract types, used to implement input widgets:
+
+* :js:class:`openerp.base.search.Input` is the most basic input type,
+  it only implements :ref:`input registration
+  <views-search-registration>`.
+
+  If inherited from, descendant classes should not call its
+  implementations of :js:func:`~openerp.base.search.Input.get_context`
+  and :js:func:`~openerp.base.search.Input.get_domain`.
+
+* :js:class:`openerp.base.search.Field` is used to implement more
+  "field" widgets (which allow the user to input potentially complex
+  values).
+
+  It provides various services for its subclasses:
+
+  * Sets up the field attributes, using attributes from the field and
+    the view node.
+
+  * It fills the widget with :js:class:`~openerp.base.search.Filter`
+    if the field has any child filter.
+
+  * It automatically generates an identifier based on the field type
+    and the field name, using
+    :js:func:`~openerp.base.search.Widget.make_id`.
+
+  * It sets up a basic (overridable)
+    :js:attr:`~openerp.base.search.Field.template` attribute, combined
+    with the previous tasks, this makes subclasses of
+    :js:class:`~openerp.base.search.Field` render themselves "for
+    free".
+
+  * It provides basic implementations of ``get_context`` and
+    ``get_domain``, both hinging on the subclasses implementing
+    ``get_value()`` (which should return a correct, converted
+    Javascript value):
+
+    :js:func:`~openerp.base.search.Field.get_context`
+
+        Checks if the field has a non-``null`` and non-empty
+        (``String``) value, and that the field has a ``context`` attr.
+
+        If both conditions are fullfilled, returns the context.
+
+    :js:func:`~openerp.base.search.Field.get_domain`
+
+        Only requires that the field has a non-``null`` and non-empty
+        value.
+
+        If the field has a ``filter_domain``, returns it
+        immediately. Otherwise, builds a context using the field's
+        name, the field :js:attr:`~openerp.base.search.Field.operator`
+        and the field value, and returns it.
+
+.. TODO: insert Input, Field, Filter, and just about every Field subclass
+
+List View
++++++++++
+
+OpenERP Web's list views don't actually exist as such in OpenERP itself: a
+list view is an OpenERP tree view in the ``view_mode`` form.
+
+The overall purpose of a list view is to display collections of objects in two
+main forms: per-object, where each object is a row in and of itself, and
+grouped, where multiple objects are represented with a single row providing
+an aggregated view of all grouped objects.
+
+These two forms can be mixed within a single list view, if needed.
+
+The root of a list view is :js:class:`openerp.base.ListView`, which may need
+to be overridden (partially or fully) to control list behavior in non-view
+cases (when using a list view as sub-component of a form widget for instance).
+
+Creation and Initialization
+"""""""""""""""""""""""""""
+
+As with most OpenERP Web views, the list view's
+:js:func:`~openerp.base.ListView.init` takes quite a number of arguments.
+
+While most of them are the standard view constructor arguments
+(``view_manager``, ``session``, ``element_id``, ``dataset`` and an
+optional ``view_id``), the list view adds a number of options for basic
+customization (without having to override methods or templates):
+
+``selectable`` (default: ``true``)
+    Indicates that the list view should allow records to be selected
+    individually. Displays selection check boxes to the left of all record rows,
+    and allows for the triggering of the
+    :ref:`selection event <listview-events-selection>`.
+``deletable`` (default: ``true``)
+    Indicates that the list view should allow records to be removed
+    individually. Displays a deletion button to the right of all record rows,
+    and allows for the triggering of the
+    :ref:`deletion event <listview-events-deletion>`.
+``header`` (default: ``true``)
+    Indicates that list columns should bear a header sporting their name (for
+    non-action columns).
+``addable`` (default: ``"New"``)
+    Indicates that a record addition/creation button should be displayed in
+    the list's header, along with its label. Also allows for the triggering of
+    the :ref:`record addition event <listview-events-addition>`.
+``sortable`` (default: ``true``)
+    Indicates that the list view can be sorted per-column (by clicking on its
+    column headers).
+
+    .. TODO: event?
+``reorderable`` (default: ``true``)
+    Indicates that the list view records can be reordered (and re-sequenced)
+    by drag and drop.
+
+    .. TODO: event?
+
+Events
+""""""
+.. _listview-events-addition:
+
+Addition
+''''''''
+The addition event is used to add a record to an existing list view. The
+default behavior is to switch to the form view, on a new record.
+
+Addition behavior can be overridden by replacing the
+:js:func:`~openerp.base.ListView.do_add_record` method.
+
+.. _listview-events-selection:
+
+Selection
+'''''''''
+The selection event is triggered when a given record is selected in the list
+view.
+
+It can be overridden by replacing the
+:js:func:`~openerp.base.ListView.do_select` method.
+
+The default behavior is simply to hide or display the list-wise deletion button
+depending on whether there are selected records or not.
+
+.. _listview-events-deletion:
+
+Deletion
+''''''''
+The deletion event is triggered when the user tries to remove 1..n records from
+the list view, either individually or globally (via the header button).
+
+Deletion can be overridden by replacing the
+:js:func:`~openerp.base.ListView.do_delete` method. By default, this method
+calls :js:func:`~openerp.base.DataSet.unlink` in order to remove the records
+entirely.
+
+.. note::
+
+  the list-wise deletion button (next to the record addition button)
+  simply proxies to :js:func:`~openerp.base.ListView.do_delete` after
+  obtaining all selected record ids, but it is possible to override it
+  alone by replacing
+  :js:func:`~openerp.base.ListView.do_delete_selected`.
+
+Internal API Doc
+----------------
+
+Python
+++++++
+
+These classes should be moved to other sections of the doc as needed,
+probably.
+
+.. automodule:: web.common.http
+    :members:
+    :undoc-members:
+
+    See also: :class:`~web.common.session.OpenERPSession`,
+    :class:`~web.common.openerplib.main.OpenERPModel`
+
+.. automodule:: web.controllers.main
+    :members:
+    :undoc-members:
+
+Testing
+-------
+
+Python
+++++++
+
+Testing for the OpenERP Web core is similar to :ref:`testing addons
+<addons-testing>`: the tests live in ``openerpweb.tests``, unittest2_
+is the testing framework and tests can be run via either unittest2
+(``unit2 discover``) or via nose_ (``nosetests``).
+
+Tests for the OpenERP Web core can also be run using ``setup.py
+test``.
+
+
+.. _unittest2:
+    http://www.voidspace.org.uk/python/articles/unittest2.shtml
+
+.. _nose:
+    http://somethingaboutorange.com/mrl/projects/nose/1.0.0/
diff --git a/doc/getting-started.rst b/doc/getting-started.rst
new file mode 100644 (file)
index 0000000..cd7f7ee
--- /dev/null
@@ -0,0 +1,10 @@
+Getting Started with OpenERP Web
+================================
+
+Installing
+----------
+
+.. per-distro packaging
+
+Launching
+---------
diff --git a/doc/guides/client-action.rst b/doc/guides/client-action.rst
new file mode 100644 (file)
index 0000000..2e11773
--- /dev/null
@@ -0,0 +1,92 @@
+Creating a new client action
+============================
+
+Client actions are the client-side of OpenERP's "Server Actions": instead of
+allowing for semi-arbitrary code to be executed in the server, they allow
+for execution of client-customized code.
+
+On the server side, a client action is an action of type ``ir.actions.client``,
+which has (at most) two properties: a mandatory ``tag``, which is an arbitrary
+string by which the client will identify the action, and an optional ``params``
+which is simply a map of keys and values sent to the client as-is (this way,
+client actions can be made generic and reused in multiple contexts).
+
+General Structure
+-----------------
+
+In the OpenERP Web code, a client action only requires two pieces of
+information:
+
+* Mapping the action's ``tag`` to an OpenERP Web object
+
+* The OpenERP Web object itself, which must inherit from
+  :js:class:`openerp.web.Widget`
+
+Our example will be the actual code for the widgets client action (a client
+action displaying a ``res.widget`` object, used in the homepage dashboard of
+the web client):
+
+.. code-block:: javascript
+
+    // Registers the object 'openerp.web_dashboard.Widget' to the client
+    // action tag 'board.home.widgets'
+    openerp.web.client_actions.add(
+        'board.home.widgets', 'openerp.web_dashboard.Widget');
+    // This object inherits from View, but only Widget is required
+    openerp.web_dashboard.Widget = openerp.web.View.extend({
+        template: 'HomeWidget'
+    });
+
+At this point, the generic ``Widget`` lifecycle takes over, the template is
+rendered, inserted in the client DOM, bound on the object's ``$element``
+property and the object is started.
+
+If the client action takes parameters, these parameters are passed in as a
+second positional parameter to the constructor:
+
+.. code-block:: javascript
+
+    init: function (parent, params) {
+        // execute the Widget's init
+        this._super(parent);
+        // board.home.widgets only takes a single param, the identifier of the
+        // res.widget object it should display. Store it for later
+        this.widget_id = params.widget_id;
+    }
+
+More complex initialization (DOM manipulations, RPC requests, ...) should be
+performed in the ``start()`` method.
+
+.. note::
+    As required by ``Widget``'s contract, if ``start`` executes any
+    asynchronous code it should return a ``$.Deferred`` so callers know when
+    it's ready for interaction.
+
+    Although generally speaking client actions are not really interacted with.
+
+.. code-block:: javascript
+
+    start: function () {
+        return $.when(
+            this._super(),
+            // Simply read the res.widget object this action should display
+            new openerp.web.DataSet(this, 'res.widget').read_ids(
+                [this.widget_id], ['title'], this.on_widget_loaded));
+    }
+
+The client action can then behave exactly as it wishes to within its root
+(``this.$element``). In this case, it performs further renderings once its
+widget's content is retrieved:
+
+.. code-block:: javascript
+
+    on_widget_loaded: function (widgets) {
+        var widget = widgets[0];
+        var url = _.sprintf(
+            '/web_dashboard/widgets/content?session_id=%s&widget_id=%d',
+            this.session.session_id, widget.id);
+        this.$element.html(QWeb.render('HomeWidget.content', {
+            widget: widget,
+            url: url
+        }));
+    }
diff --git a/doc/guides/sidebar-protocol.rst b/doc/guides/sidebar-protocol.rst
new file mode 100644 (file)
index 0000000..83626c3
--- /dev/null
@@ -0,0 +1,78 @@
+Adding a sidebar to a view
+==========================
+
+Initialization
+--------------
+
+Each view has the responsibility to create its sidebar (or not) if and only if
+the ``sidebar`` flag is set in its options.
+
+In that case, it should use the ``sidebar_id`` value (from its options) to
+initialize the sidebar at the right position in the DOM:
+
+.. code-block:: javascript
+
+    if (this.options.sidebar && this.options.sidebar_id) {
+        this.sidebar = new openerp.web.Sidebar(this, this.options.sidebar_id);
+        this.sidebar.start();
+    }
+
+Because the sidebar is an old-style widget, it must be started after being
+initialized.
+
+Sidebar communication protocol
+------------------------------
+
+In order to behave correctly, a sidebar needs informations from its parent
+view.
+
+This information is extracted via a very basic protocol consisting of a
+property and two methods:
+
+.. js:attribute:: dataset
+
+    the view's dataset, used to fetch the currently active model and provide it
+    to remote action handlers as part of the basic context
+
+.. js:function:: get_selected_ids()
+
+    Used to query the parent view for the set of currently available record
+    identifiers. Used to setup the basic context's ``active_id`` and
+    ``active_ids`` keys.
+
+    .. warning::
+
+        :js:func:`get_selected_ids` must return at least one id
+
+    :returns: an array of at least one id
+    :rtype: Array<Number>
+
+.. js:function:: sidebar_context()
+
+    Queries the view for additional context data to provide to the sidebar.
+
+    :js:class:`~openerp.base.View` provides a default NOOP implementation,
+    which simply resolves to an empty object.
+
+    :returns: a promise yielding an object on success, this object is mergeed
+              into the sidebar's own context
+    :rtype: $.Deferred<Object>
+
+Programmatic folding and unfolding
+----------------------------------
+
+The sidebar object starts folded. It provides three methods to handle its
+folding status:
+
+.. js:function:: do_toggle
+
+    Toggles the status of the sidebar
+
+.. js:function:: do_fold
+
+    Forces the sidebar closed if it's currently open
+
+.. js:function:: do_unfold
+
+    Forces the sidebar open if it's currently closed
+
index 5d5b4f8..efa4d1c 100644 (file)
@@ -1,6 +1,27 @@
-:orphan:
+.. OpenERP Web documentation master file, created by
+   sphinx-quickstart on Fri Mar 18 16:31:55 2011.
+   You can adapt this file completely to your liking, but it should at least
+   contain the root `toctree` directive.
 
-OpenERP Server Developers Documentation
+Welcome to OpenERP Web's documentation!
 =======================================
 
-.. include:: index.rst.inc
+Contents:
+
+.. toctree::
+   :maxdepth: 2
+
+   getting-started
+   production
+   widgets
+   addons
+   development
+   project
+   old-version
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
index 2440f7c..3e72cad 100644 (file)
@@ -5,8 +5,8 @@ REM Command file for Sphinx documentation
 if "%SPHINXBUILD%" == "" (
        set SPHINXBUILD=sphinx-build
 )
-set BUILDDIR=build
-set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source
+set BUILDDIR=_build
+set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
 if NOT "%PAPER%" == "" (
        set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
 )
diff --git a/doc/old-version.rst b/doc/old-version.rst
new file mode 100644 (file)
index 0000000..d745806
--- /dev/null
@@ -0,0 +1,11 @@
+Main differences with the 6.0 client
+====================================
+
+.. No more populate.sh, use virtualenvs
+
+.. Logic is mainly in Javascript (had to make a choice between JS and
+.. Python logic)
+
+.. Templating language changes
+
+.. How to port addons and modules?
diff --git a/doc/production.rst b/doc/production.rst
new file mode 100644 (file)
index 0000000..2524471
--- /dev/null
@@ -0,0 +1,47 @@
+Deploying OpenERP Web
+=====================
+
+.. After release one, add upgrade instructions if any
+
+.. How about running the web client on alternative Python
+.. implementations e.g. pypy or Jython? Since the only lib with C
+.. accelerators we're using right now is SimpleJSON and it has a pure
+.. Python base component, we should be able to test and deploy on
+.. non-cpython no?
+
+In-depth configuration
+----------------------
+
+SSL, basic proxy (link to relevant section), links to sections and
+example files for various servers and proxies, WSGI
+integration/explanation (if any), ...
+
+Deployment Options
+------------------
+
+Serving via WSGI
+~~~~~~~~~~~~~~~~
+
+Apache mod_wsgi
++++++++++++++++
+
+NGinx mod_wsgi
+++++++++++++++
+
+uWSGI
++++++
+
+Gunicorn
+++++++++
+
+FastCGI, SCGI, or AJP
++++++++++++++++++++++
+
+Behind a proxy
+~~~~~~~~~~~~~~
+
+Apache mod_proxy
+++++++++++++++++
+
+NGinx HttpProxy
++++++++++++++++
diff --git a/doc/project.rst b/doc/project.rst
new file mode 100644 (file)
index 0000000..aa465aa
--- /dev/null
@@ -0,0 +1,451 @@
+The OpenERP Web open-source project
+===================================
+
+Getting involved
+----------------
+
+Translations
+++++++++++++
+
+Bug reporting
++++++++++++++
+
+Source code repository
+++++++++++++++++++++++
+
+Merge proposals
++++++++++++++++
+
+Coding issues and coding conventions
+++++++++++++++++++++++++++++++++++++
+
+Javascript coding
+~~~~~~~~~~~~~~~~~
+
+These are a number of guidelines for javascript code. More than coding
+conventions, these are warnings against potentially harmful or sub-par
+constructs.
+
+Ideally, you should be able to configure your editor or IDE to warn you against
+these kinds of issues.
+
+Use ``var`` for *all* declarations
+**********************************
+
+In javascript (as opposed to Python), assigning to a variable which does not
+already exist and is not explicitly declared (via ``var``) will implicitly
+create a global variable. This is bad for a number of reasons:
+
+* It leaks information outside function scopes
+* It keeps memory of previous run, with potentially buggy behaviors
+* It may conflict with other functions with the same issue
+* It makes code harder to statically check (via e.g. IDE inspectors)
+
+.. note::
+    It is perfectly possible to use ``var`` in ``for`` loops:
+
+    .. code-block:: javascript
+
+        for (var i = 0; i < some_array.length; ++i) {
+            // code here
+        }
+
+    this is not an issue
+
+All local *and global* variables should be declared via ``var``.
+
+.. note:: generally speaking, you should not need globals in OpenERP Web: you
+          can just declare a variable local to your top-level function. This
+          way, if your widget/addon is instantiated several times on the same
+          page (because it's used in embedded mode) each instance will have its
+          own internal but global-to-its-objects data.
+
+Do not leave trailing commas in object literals
+***********************************************
+
+While it is legal to leave trailing commas in Python dictionaries, e.g.
+
+.. code-block:: python
+
+    foo = {
+        'a': 1,
+        'b': 2,
+    }
+
+and it's valid in ECMAScript 5 and most browsers support it in Javascript, you
+should *never* use trailing commas in Javascript object literals:
+
+* Internet Explorer does *not* support trailing commas (at least until and
+  including Internet Explorer 8), and trailing comma will cause hard-to-debug
+  errors in it
+
+* JSON does not accept trailing comma (it is a syntax error), and using them
+  in object literals puts you at risks of using them in literal JSON strings
+  as well (though there are few reasons to write JSON by hand)
+
+*Never* use ``for … in`` to iterate on arrays
+*********************************************
+
+:ref:`Iterating over an object with for…in is a bit tricky already
+<for-in-iteration>`, it is far more complex than in Python (where it Just
+Works™) due to the interaction of various Javascript features, but to iterate
+on arrays it becomes downright deadly and errorneous: ``for…in`` really
+iterates over an *object*'s *properties*.
+
+With an array, this has the following consequences:
+
+* It does not necessarily iterate in numerical order, nor does it iterate in
+  any kind of set order. The order is implementation-dependent and may vary
+  from one run to the next depending on a number of reasons and implementation
+  details.
+* If properties are added to an array, to ``Array.prototype`` or to
+  ``Object.prototype`` (the latter two should not happen in well-behaved
+  javascript code, but you never know...) those properties *will* be iterated
+  over by ``for…in``. While ``Object.hasOwnProperty`` will guard against
+  iterating prototype properties, they will not guard against properties set
+  on the array instance itself (as memoizers for instance).
+
+  Note that this includes setting negative keys on arrays.
+
+For this reason, ``for…in`` should **never** be used on array objects. Instead,
+you should use either a normal ``for`` or (even better, unless you have
+profiled the code and found a hotspot) one of Underscore's array iteration
+methods (`_.each`_, `_.map`_, `_.filter`_, etc...).
+
+Underscore is guaranteed to be bundled and available in OpenERP Web scopes.
+
+.. _for-in-iteration:
+
+Use ``hasOwnProperty`` when iterating on an object with ``for … in``
+********************************************************************
+
+``for…in`` is Javascript's built-in facility for iterating over and object's
+properties.
+
+`It is also fairly tricky to use`_: it iterates over *all* non-builtin
+properties of your objects [#]_, which includes methods of an object's class.
+
+As a result, when iterating over an object with ``for…in`` the first line of
+the body *should* generally be a call to `Object.hasOwnProperty`_. This call
+will check whether the property was set directly on the object or comes from
+the object's class:
+
+.. code-block:: javascript
+
+    for(var key in ob) {
+        if (!ob.hasOwnProperty(key)) {
+            // comes from ob's class
+            continue;
+        }
+        // do stuff with key
+    }
+
+Since properties can be added directly to e.g. ``Object.prototype`` (even
+though it's usually considered bad style), you should not assume you ever know
+which properties ``for…in`` is going to iterate over.
+
+An alternative is to use Underscore's iteration methods, which generally work
+over objects as well as arrays:
+
+Instead of
+
+.. code-block:: javascript
+
+    for (var key in ob) {
+        if (!ob.hasOwnProperty(key)) { continue; }
+        var value = ob[key];
+        // Do stuff with key and value
+    }
+
+you could write:
+
+.. code-block:: javascript
+
+    _.each(ob, function (value, key) {
+        // do stuff with key and value
+    });
+
+and not worry about the details of the iteration: underscore should do the
+right thing for you on its own [#]_.
+
+Writing documentation
++++++++++++++++++++++
+
+The OpenERP Web project documentation uses Sphinx_ for the literate
+documentation (this document for instance), the development guides
+(for Python and Javascript alike) and the Python API documentation
+(via autodoc_).
+
+For the Javascript API, documentation should be written using the
+`JsDoc Toolkit`_.
+
+Guides and main documentation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The meat and most important part of all documentation. Should be
+written in plain English, using reStructuredText_ and taking advantage
+of `Sphinx's extensions`_, especially `cross-references`_.
+
+Python API Documentation
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+All public objects in Python code should have a docstring written in
+RST, using Sphinx's `Python domain`_ [#]_:
+
+* Functions and methods documentation should be in their own
+  docstring, using Sphinx's `info fields`_
+
+  For parameters types, built-in and stdlib types should be using the
+  combined syntax:
+
+  .. code-block:: restructuredtext
+
+      :param dict foo: what the purpose of foo is
+
+  unless a more extensive explanation needs to be given (e.g. the
+  specification that the input should be a list of 3-tuple needs to
+  use ``:type:`` even though all types involved are built-ins). Any
+  other type should be specified in full using the ``:type:`` field
+
+  .. code-block:: restructuredtext
+
+      :param foo: what the purpose of foo is
+      :type foo: some.addon.Class
+
+  Mentions of other methods (including within the same class), modules
+  or types in descriptions (of anything, including parameters) should
+  be cross-referenced.
+
+* Classes should likewise be documented using their own docstring, and
+  should include the documentation of their construction (``__init__``
+  and ``__new__``), using the `info fields`_  as well.
+
+* Attributes (class and instance) should be documented in their
+  class's docstring via the ``.. attribute::`` directive, following
+  the class's own documentation.
+
+* The relation between modules and module-level attributes is similar:
+  modules should be documented in their own docstring, public module
+  attributes should be documented in the module's docstring using the
+  ``.. data::`` directive.
+
+Javascript API documentation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Javascript API documentation uses JsDoc_, a javascript documentation
+toolkit with a syntax similar to (and inspired by) JavaDoc's.
+
+Due to limitations of JsDoc, the coding patterns in OpenERP Web and
+the Sphinx integration, there are a few peculiarities to be aware of
+when writing javascript API documentation:
+
+* Namespaces and classes *must* be explicitly marked up even if they
+  are not documented, or JsDoc will not understand what they are and
+  will not generate documentation for their content.
+
+  As a result, the bare minimum for a namespace is:
+
+  .. code-block:: javascript
+
+      /** @namespace */
+      foo.bar.baz = {};
+
+  while for a class it is:
+
+  .. code-block:: javascript
+
+      /** @class */
+      foo.bar.baz.Qux = [...]
+
+* Because the OpenERP Web project uses `John Resig's Class
+  implementation`_ instead of direct prototypal inheritance [#]_,
+  JsDoc fails to infer class scopes (and constructors or super
+  classes, for that matter) and has to be told explicitly.
+
+  See :ref:`js-class-doc` for the complete rundown.
+
+* Much like the JavaDoc, JsDoc does not include a full markup
+  language. Instead, comments are simply marked up in HTML.
+
+  This has a number of inconvenients:
+
+  * Complex documentation comments become nigh-unreadable to read in
+    text editors (as opposed to IDEs, which may handle rendering
+    documentation comments on the fly)
+
+  * Though cross-references are supported by JsDoc (via ``@link`` and
+    ``@see``), they only work within the JsDoc
+
+  * More general impossibility to integrate correctly with Sphinx, and
+    e.g. reference JavaScript objects from a tutorial, or have all the
+    documentation live at the same place.
+
+  As a result, JsDoc comments should be marked up using RST, not
+  HTML. They may use Sphinx's cross-references as well.
+
+.. _js-class-doc:
+
+Documenting a Class
+*******************
+
+The first task when documenting a class using JsDoc is to *mark* that
+class, so JsDoc knows it can be used to instantiate objects (and, more
+importantly as far as it's concerned, should be documented with
+methods and attributes and stuff).
+
+This is generally done through the ``@class`` tag, but this tag has a
+significant limitation: it "believes" the constructor and the class
+are one and the same [#]_. This will work for constructor-less
+classes, but because OpenERP Web uses Resig's class the constructor is
+not the class itself but its ``init()`` method.
+
+Because this pattern is common in modern javascript code bases, JsDoc
+supports it: it is possible to mark an arbitrary instance method as
+the *class specification* by using the ``@constructs`` tag.
+
+.. warning:: ``@constructs`` is a class specification in and of
+    itself, it *completely replaces* the class documentation.
+
+    Using both a class documentation (even without ``@class`` itself)
+    and a constructor documentation is an *error* in JsDoc and will
+    result in incorrect behavior and broken documentation.
+
+The second issue is that Resig's class uses an object literal to
+specify instance methods, and because JsDoc does not know anything
+about Resig's class, it does not know about the role of the object
+literal.
+
+As with constructors, though, JsDoc provides a pluggable way to tell
+it about methods: the ``@lends`` tag. It specifies that the object
+literal "lends" its properties to the class being built.
+
+``@lends`` must be specified right before the opening brace of the
+object literal (between the opening paren of the ``#extend`` call and
+the brace), and takes the full qualified name of the class being
+created as a parameter, followed by the character ``#`` or by
+``.prototype``. This latter part tells JsDoc these are instance
+methods, not class (static) methods..
+
+Finally, specifying a class's superclass is done through the
+``@extends`` tag, which takes a fully qualified class name as a
+parameter.
+
+Here are a class without a constructor, and a class with one, so that
+everything is clear (these are straight from the OpenERP Web source,
+with the descriptions and irrelevant atttributes stripped):
+
+.. code-block:: javascript
+
+    /**
+     * <Insert description here, not below>
+     *
+     * @class
+     * @extends openerp.base.search.Field
+     */
+    openerp.base.search.CharField = openerp.base.search.Field.extend(
+        /** @lends openerp.base.search.CharField# */ {
+            // methods here
+    });
+
+.. code-block:: javascript
+
+    openerp.base.search.Widget = openerp.base.Controller.extend(
+        /** @lends openerp.base.search.Widget# */{
+        /**
+         * <Insert description here, not below>
+         *
+         * @constructs
+         * @extends openerp.base.Controller
+         *
+         * @param view the ancestor view of this widget
+         */
+        init: function (view) {
+            // construction of the instance
+        },
+        // bunch of other methods
+    });
+
+OpenERP Web over time
+---------------------
+
+Release process
++++++++++++++++
+
+OpenSUSE packaging: http://blog.lowkster.com/2011/04/packaging-python-packages-in-opensuse.html
+
+Roadmap
++++++++
+
+Release notes
++++++++++++++
+
+.. [#] More precisely, it iterates over all *enumerable* properties. It just
+       happens that built-in properties (such as ``String.indexOf`` or
+       ``Object.toString``) are set to non-enumerable.
+
+       The enumerability of a property can be checked using
+       `Object.propertyIsEnumeable`_.
+
+       Before ECMAScript 5, it was not possible for user-defined properties
+       to be non-enumerable in a portable manner. ECMAScript 5 introduced
+       `Object.defineProperty`_ which lets user code create non-enumerable
+       properties (and more, read-only properties for instance, or implicit
+       getters and setters). However, support for these is not fully complete
+       at this point, and they are not being used in OpenERP Web code anyway.
+
+.. [#] While using underscore is generally the preferred method (simpler,
+       more reliable and easier to write than a *correct* ``for…in``
+       iteration), it is also probably slower (due to the overhead of
+       calling a bunch of functions).
+
+       As a result, if you profile some code and find out that an underscore
+       method adds unacceptable overhead in a tight loop, you may want to
+       replace it with a ``for…in`` (or a regular ``for`` statement for
+       arrays).
+
+.. [#] Because Python is the default domain, the ``py:`` markup prefix
+       is optional and should be left out.
+
+.. [#] Resig's Class still uses prototypes under the hood, it doesn't
+       reimplement its own object system although it does add several
+       helpers such as the ``_super()`` instance method.
+
+.. [#] Which is the case in normal Javascript semantics. Likewise, the
+       ``.prototype`` / ``#`` pattern we will see later on is due to
+       JsDoc defaulting to the only behavior it can rely on: "normal"
+       Javascript prototype-based type creation.
+
+.. _reStructuredText:
+    http://docutils.sourceforge.net/rst.html
+.. _Sphinx:
+    http://sphinx.pocoo.org/index.html
+.. _Sphinx's extensions:
+    http://sphinx.pocoo.org/markup/index.html
+.. _Python domain:
+    http://sphinx.pocoo.org/domains.html#the-python-domain
+.. _info fields:
+    http://sphinx.pocoo.org/domains.html#info-field-lists
+.. _autodoc:
+    http://sphinx.pocoo.org/ext/autodoc.html
+        ?highlight=autodoc#sphinx.ext.autodoc
+.. _cross-references:
+    http://sphinx.pocoo.org/markup/inline.html#xref-syntax
+.. _JsDoc:
+.. _JsDoc Toolkit:
+    http://code.google.com/p/jsdoc-toolkit/
+.. _John Resig's Class implementation:
+    http://ejohn.org/blog/simple-javascript-inheritance/
+.. _\_.each:
+    http://documentcloud.github.com/underscore/#each
+.. _\_.map:
+    http://documentcloud.github.com/underscore/#map
+.. _\_.filter:
+    http://documentcloud.github.com/underscore/#select
+.. _It is also fairly tricky to use:
+    https://developer.mozilla.org/en/JavaScript/Reference/Statements/for...in#Description
+.. _Object.propertyIsEnumeable:
+    https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/propertyIsEnumerable
+.. _Object.defineProperty:
+    https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/defineProperty
+.. _Object.hasOwnProperty:
+    https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/hasOwnProperty
diff --git a/doc/source/Makefile b/doc/source/Makefile
deleted file mode 100644 (file)
index c1eff18..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-# Makefile for Sphinx documentation
-#
-
-# You can set these variables from the command line.
-SPHINXOPTS    = -q
-SPHINXBUILD   = sphinx-build
-PAPER         =
-BUILDDIR      = _build
-
-# Internal variables.
-PAPEROPT_a4     = -D latex_paper_size=a4
-PAPEROPT_letter = -D latex_paper_size=letter
-ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
-# the i18n builder cannot share the environment and doctrees with the others
-I18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
-
-.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
-
-help:
-       @echo "Please use \`make <target>' where <target> is one of"
-       @echo "  html       to make standalone HTML files"
-       @echo "  dirhtml    to make HTML files named index.html in directories"
-       @echo "  singlehtml to make a single large HTML file"
-       @echo "  pickle     to make pickle files"
-       @echo "  json       to make JSON files"
-       @echo "  htmlhelp   to make HTML files and a HTML help project"
-       @echo "  qthelp     to make HTML files and a qthelp project"
-       @echo "  devhelp    to make HTML files and a Devhelp project"
-       @echo "  epub       to make an epub"
-       @echo "  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
-       @echo "  latexpdf   to make LaTeX files and run them through pdflatex"
-       @echo "  text       to make text files"
-       @echo "  man        to make manual pages"
-       @echo "  texinfo    to make Texinfo files"
-       @echo "  info       to make Texinfo files and run them through makeinfo"
-       @echo "  gettext    to make PO message catalogs"
-       @echo "  changes    to make an overview of all changed/added/deprecated items"
-       @echo "  linkcheck  to check all external links for integrity"
-       @echo "  doctest    to run all doctests embedded in the documentation (if enabled)"
-
-clean:
-       -rm -rf $(BUILDDIR)/*
-
-html:
-       $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
-       @echo
-       @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
-
-dirhtml:
-       $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
-       sed -i '/-99999/d' _build/dirhtml/_static/flasky.css
-       @echo
-       @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
-
-singlehtml:
-       $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
-       @echo
-       @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
-
-pickle:
-       $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
-       @echo
-       @echo "Build finished; now you can process the pickle files."
-
-json:
-       $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
-       @echo
-       @echo "Build finished; now you can process the JSON files."
-
-htmlhelp:
-       $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
-       @echo
-       @echo "Build finished; now you can run HTML Help Workshop with the" \
-             ".hhp project file in $(BUILDDIR)/htmlhelp."
-
-qthelp:
-       $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
-       @echo
-       @echo "Build finished; now you can run "qcollectiongenerator" with the" \
-             ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
-       @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/OpenERPTechnicalDocumentation.qhcp"
-       @echo "To view the help file:"
-       @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/OpenERPTechnicalDocumentation.qhc"
-
-devhelp:
-       $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
-       @echo
-       @echo "Build finished."
-       @echo "To view the help file:"
-       @echo "# mkdir -p $$HOME/.local/share/devhelp/OpenERPTechnicalDocumentation"
-       @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/OpenERPTechnicalDocumentation"
-       @echo "# devhelp"
-
-epub:
-       $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
-       @echo
-       @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
-
-latex:
-       $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
-       @echo
-       @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
-       @echo "Run \`make' in that directory to run these through (pdf)latex" \
-             "(use \`make latexpdf' here to do that automatically)."
-
-latexpdf:
-       $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
-       @echo "Running LaTeX files through pdflatex..."
-       $(MAKE) -C $(BUILDDIR)/latex all-pdf
-       @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
-
-text:
-       $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
-       @echo
-       @echo "Build finished. The text files are in $(BUILDDIR)/text."
-
-man:
-       $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
-       @echo
-       @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
-
-texinfo:
-       $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
-       @echo
-       @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
-       @echo "Run \`make' in that directory to run these through makeinfo" \
-             "(use \`make info' here to do that automatically)."
-
-info:
-       $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
-       @echo "Running Texinfo files through makeinfo..."
-       make -C $(BUILDDIR)/texinfo info
-       @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
-
-gettext:
-       $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
-       @echo
-       @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
-
-changes:
-       $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
-       @echo
-       @echo "The overview file is in $(BUILDDIR)/changes."
-
-linkcheck:
-       $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
-       @echo
-       @echo "Link check complete; look for any errors in the above output " \
-             "or in $(BUILDDIR)/linkcheck/output.txt."
-
-doctest:
-       $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
-       @echo "Testing of doctests in the sources finished, look at the " \
-             "results in $(BUILDDIR)/doctest/output.txt."
diff --git a/doc/source/_static/openerp.png b/doc/source/_static/openerp.png
deleted file mode 100644 (file)
index d6dbd9d..0000000
Binary files a/doc/source/_static/openerp.png and /dev/null differ
diff --git a/doc/source/_templates/sidebarintro.html b/doc/source/_templates/sidebarintro.html
deleted file mode 100644 (file)
index d61f341..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-<p class="logo"><a href="http://doc.openerp.com/">
-  <img class="logo" src="{{ pathto('_static/openerp.png', 1) }}" alt="Logo"/>
-</a></p>
-
-<h3>Other Docs</h3>
-<ul>
-  <li><a href="http://doc.openerp.com/v6.1/developers">OpenERP Developers Documentation</a></li>
-  <li><a href="http://doc.openerp.com/v6.1/developers/server">OpenERP Server Developers Documentation</a></li>
-  <li><a href="http://doc.openerp.com/v6.1/users">OpenERP Users Documentation</a></li>
-</ul>
-
-<h3>Useful Links</h3>
-<ul>
-  <li><a href="http://www.openerp.com/">The OpenERP website</a></li>
-  <li><a href="http://python.org/">The Python programming language</a></li>
-</ul>
diff --git a/doc/source/_templates/sidebarlogo.html b/doc/source/_templates/sidebarlogo.html
deleted file mode 100644 (file)
index de6e3e5..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-<p class="logo"><a href="{{ pathto(master_doc) }}">
-  <img class="logo" src="{{ pathto('_static/openerp.png', 1) }}" alt="Logo"/>
-</a></p>
diff --git a/doc/source/_themes/LICENSE b/doc/source/_themes/LICENSE
deleted file mode 100644 (file)
index 8daab7e..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-Copyright (c) 2010 by Armin Ronacher.
-
-Some rights reserved.
-
-Redistribution and use in source and binary forms of the theme, with or
-without modification, are permitted provided that the following conditions
-are met:
-
-* Redistributions of source code must retain the above copyright
-  notice, this list of conditions and the following disclaimer.
-
-* Redistributions in binary form must reproduce the above
-  copyright notice, this list of conditions and the following
-  disclaimer in the documentation and/or other materials provided
-  with the distribution.
-
-* The names of the contributors may not be used to endorse or
-  promote products derived from this software without specific
-  prior written permission.
-
-We kindly ask you to only use these themes in an unmodified manner just
-for Flask and Flask-related products, not for unrelated projects.  If you
-like the visual style and want to use it for your own projects, please
-consider making some larger changes to the themes (such as changing
-font faces, sizes, colors or margins).
-
-THIS THEME IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS THEME, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
diff --git a/doc/source/_themes/README b/doc/source/_themes/README
deleted file mode 100644 (file)
index b3292bd..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-Flask Sphinx Styles
-===================
-
-This repository contains sphinx styles for Flask and Flask related
-projects.  To use this style in your Sphinx documentation, follow
-this guide:
-
-1. put this folder as _themes into your docs folder.  Alternatively
-   you can also use git submodules to check out the contents there.
-2. add this to your conf.py:
-
-   sys.path.append(os.path.abspath('_themes'))
-   html_theme_path = ['_themes']
-   html_theme = 'flask'
-
-The following themes exist:
-
-- 'flask' - the standard flask documentation theme for large
-  projects
-- 'flask_small' - small one-page theme.  Intended to be used by
-  very small addon libraries for flask.
-
-The following options exist for the flask_small theme:
-
-   [options]
-   index_logo = ''              filename of a picture in _static
-                                to be used as replacement for the
-                                h1 in the index.rst file.
-   index_logo_height = 120px    height of the index logo
-   github_fork = ''             repository name on github for the
-                                "fork me" badge
diff --git a/doc/source/_themes/flask/layout.html b/doc/source/_themes/flask/layout.html
deleted file mode 100644 (file)
index ad08ecc..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-{%- extends "basic/layout.html" %}
-{%- block extrahead %}
-  {{ super() }}
-  {% if theme_touch_icon %}
-  <link rel="apple-touch-icon" href="{{ pathto('_static/' ~ theme_touch_icon, 1) }}" />
-  {% endif %}
-  <link media="only screen and (max-device-width: 480px)" href="{{
-    pathto('_static/small_flask.css', 1) }}" type= "text/css" rel="stylesheet" />
-{% endblock %}
-{%- block relbar2 %}{% endblock %}
-{% block header %}
-  {{ super() }}
-  {% if pagename == 'index' %}
-  <div class=indexwrapper>
-  {% endif %}
-{% endblock %}
-{%- block footer %}
-  <div class="footer">
-    &copy; Copyright {{ copyright }}
-    Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> and a modified <a href="https://github.com/mitsuhiko/flask-sphinx-themes">Flask theme</a>.
-  </div>
-  {% if pagename == 'index' %}
-  </div>
-  {% endif %}
-{%- endblock %}
diff --git a/doc/source/_themes/flask/relations.html b/doc/source/_themes/flask/relations.html
deleted file mode 100644 (file)
index 3bbcde8..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-<h3>Related Topics</h3>
-<ul>
-  <li><a href="{{ pathto(master_doc) }}">Documentation overview</a><ul>
-  {%- for parent in parents %}
-  <li><a href="{{ parent.link|e }}">{{ parent.title }}</a><ul>
-  {%- endfor %}
-    {%- if prev %}
-      <li>Previous: <a href="{{ prev.link|e }}" title="{{ _('previous chapter')
-        }}">{{ prev.title }}</a></li>
-    {%- endif %}
-    {%- if next %}
-      <li>Next: <a href="{{ next.link|e }}" title="{{ _('next chapter')
-        }}">{{ next.title }}</a></li>
-    {%- endif %}
-  {%- for parent in parents %}
-  </ul></li>
-  {%- endfor %}
-  </ul></li>
-</ul>
diff --git a/doc/source/_themes/flask/static/flasky.css_t b/doc/source/_themes/flask/static/flasky.css_t
deleted file mode 100644 (file)
index 0280e15..0000000
+++ /dev/null
@@ -1,395 +0,0 @@
-/*
- * flasky.css_t
- * ~~~~~~~~~~~~
- *
- * :copyright: Copyright 2010 by Armin Ronacher.
- * :license: Flask Design License, see LICENSE for details.
- */
-
-{% set page_width = '80em' %}
-{% set sidebar_width = '16em' %}
-@import url("basic.css");
-/* -- page layout ----------------------------------------------------------- */
-body {
-    font-family: 'Georgia', serif;
-    font-size: 15px;
-    background-color: white;
-    color: #000;
-    margin: 0;
-    padding: 0;
-}
-
-div.document {
-    width: {{ page_width }};
-    margin: 30px auto 0 auto;
-}
-
-div.documentwrapper {
-    float: left;
-    width: 100%;
-}
-
-div.bodywrapper {
-    margin: 0 0 0 {{ sidebar_width }};
-}
-
-div.sphinxsidebar {
-    width: {{ sidebar_width }};
-}
-
-hr {
-    border: 1px solid #B1B4B6;
-}
-div.body {
-    background-color: #ffffff;
-    color: #3E4349;
-    padding: 0 0px 0 0px;
-}
-
-img.floatingflask {
-    padding: 0 0 10px 10px;
-    float: right;
-}
-div.footer {
-    width: {{ page_width }};
-    margin: 20px auto 30px auto;
-    font-size: 12px;
-    color: #888;
-    text-align: right;
-}
-
-div.footer a {
-    color: #888;
-}
-
-div.related {
-    display: none;
-}
-div.sphinxsidebar a {
-    color: #444;
-    text-decoration: none;
-    border-bottom: 1px dotted #999;
-}
-
-div.sphinxsidebar a:hover {
-    border-bottom: 1px solid #999;
-}
-div.sphinxsidebar {
-    font-size: 12px;
-    line-height: 1.5;
-}
-
-div.sphinxsidebarwrapper {
-    padding: 0px 10px;
-}
-
-div.sphinxsidebarwrapper p.logo {
-    padding: 0 0 20px 0;
-    margin: 0;
-    text-align: center;
-}
-div.sphinxsidebar h3,
-div.sphinxsidebar h4 {
-    font-family: 'Garamond', 'Georgia', serif;
-    color: #444;
-    font-size: 22px;
-    font-weight: normal;
-    margin: 0 0 5px 0;
-    padding: 0;
-}
-
-div.sphinxsidebar h4 {
-    font-size: 18px;
-}
-div.sphinxsidebar h3 a {
-    color: #444;
-}
-
-div.sphinxsidebar p.logo a,
-div.sphinxsidebar h3 a,
-div.sphinxsidebar p.logo a:hover,
-div.sphinxsidebar h3 a:hover {
-    border: none;
-}
-div.sphinxsidebar p {
-    color: #555;
-    margin: 10px 0;
-}
-
-div.sphinxsidebar ul {
-    margin: 10px 0;
-    padding: 0;
-    color: #000;
-}
-div.sphinxsidebar input {
-    border: 1px solid #ccc;
-    font-family: 'Georgia', serif;
-    font-size: 1em;
-}
-/* -- body styles ----------------------------------------------------------- */
-a {
-    color: #004B6B;
-    text-decoration: underline;
-}
-a:hover {
-    color: #6D4100;
-    text-decoration: underline;
-}
-div.body h1,
-div.body h2,
-div.body h3,
-div.body h4,
-div.body h5,
-div.body h6 {
-    font-family: 'Garamond', 'Georgia', serif;
-    font-weight: normal;
-    margin: 30px 0px 10px 0px;
-    padding: 0;
-}
-
-{% if theme_index_logo %}
-div.indexwrapper h1 {
-    text-indent: -999999px;
-    background: url({{ theme_index_logo }}) no-repeat center center;
-    height: {{ theme_index_logo_height }};
-}
-{% endif %}
-div.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; }
-div.body h2 { font-size: 180%; }
-div.body h3 { font-size: 150%; }
-div.body h4 { font-size: 130%; }
-div.body h5 { font-size: 100%; }
-div.body h6 { font-size: 100%; }
-a.headerlink {
-    color: #ddd;
-    padding: 0 4px;
-    text-decoration: none;
-}
-a.headerlink:hover {
-    color: #444;
-    background: #eaeaea;
-}
-div.body p, div.body dd, div.body li {
-    line-height: 1.4em;
-}
-
-div.admonition {
-    background: #fafafa;
-    margin: 20px -30px;
-    padding: 10px 30px;
-    border-top: 1px solid #ccc;
-    border-bottom: 1px solid #ccc;
-}
-
-div.admonition tt.xref, div.admonition a tt {
-    border-bottom: 1px solid #fafafa;
-}
-
-dd div.admonition {
-    margin-left: -60px;
-    padding-left: 60px;
-}
-
-div.admonition p.admonition-title {
-    font-family: 'Garamond', 'Georgia', serif;
-    font-weight: normal;
-    font-size: 22px;
-    margin: 0 0 10px 0;
-    padding: 0;
-    line-height: 1;
-}
-
-div.admonition p.last {
-    margin-bottom: 0;
-}
-
-div.highlight {
-    background-color: white;
-}
-
-dt:target, .highlight {
-    background: #FAF3E8;
-}
-
-div.note {
-    background-color: #eee;
-    border: 1px solid #ccc;
-}
-div.seealso {
-    background-color: #ffc;
-    border: 1px solid #ff6;
-}
-div.topic {
-    background-color: #eee;
-}
-p.admonition-title {
-    display: inline;
-}
-p.admonition-title:after {
-    content: ":";
-}
-
-pre, tt {
-    font-family: 'Consolas', 'Menlo', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
-    font-size: 0.9em;
-}
-
-img.screenshot {
-}
-
-tt.descname, tt.descclassname {
-    font-size: 0.95em;
-}
-
-tt.descname {
-    padding-right: 0.08em;
-}
-
-img.screenshot {
-    -moz-box-shadow: 2px 2px 4px #eee;
-    -webkit-box-shadow: 2px 2px 4px #eee;
-    box-shadow: 2px 2px 4px #eee;
-}
-
-table.docutils {
-    border: 1px solid #888;
-    -moz-box-shadow: 2px 2px 4px #eee;
-    -webkit-box-shadow: 2px 2px 4px #eee;
-    box-shadow: 2px 2px 4px #eee;
-}
-
-table.docutils td, table.docutils th {
-    border: 1px solid #888;
-    padding: 0.25em 0.7em;
-}
-
-table.field-list, table.footnote {
-    border: none;
-    -moz-box-shadow: none;
-    -webkit-box-shadow: none;
-    box-shadow: none;
-}
-
-table.footnote {
-    margin: 15px 0;
-    width: 100%;
-    border: 1px solid #eee;
-    background: #fdfdfd;
-    font-size: 0.9em;
-}
-
-table.footnote + table.footnote {
-    margin-top: -15px;
-    border-top: none;
-}
-
-table.field-list th {
-    padding: 0 0.8em 0 0;
-}
-
-table.field-list td {
-    padding: 0;
-}
-
-table.footnote td.label {
-    width: 0px;
-    padding: 0.3em 0 0.3em 0.5em;
-}
-
-table.footnote td {
-    padding: 0.3em 0.5em;
-}
-
-dl {
-    margin: 0;
-    padding: 0;
-}
-
-dl dd {
-    margin-left: 30px;
-}
-
-blockquote {
-    margin: 0 0 0 30px;
-    padding: 0;
-}
-
-ul, ol {
-    margin: 10px 0 10px 30px;
-    padding: 0;
-}
-pre {
-    background: #eee;
-    padding: 7px 30px;
-    margin: 15px -30px;
-    line-height: 1.3em;
-}
-
-dl pre, blockquote pre, li pre {
-    margin-left: -60px;
-    padding-left: 60px;
-}
-
-dl dl pre {
-    margin-left: -90px;
-    padding-left: 90px;
-}
-tt {
-    background-color: #ecf0f3;
-    color: #222;
-    /* padding: 1px 2px; */
-}
-
-tt.xref, a tt {
-    background-color: #FBFBFB;
-    border-bottom: 1px solid white;
-}
-
-a.reference {
-    text-decoration: none;
-    border-bottom: 1px dotted #004B6B;
-}
-
-a.reference:hover {
-    border-bottom: 1px solid #6D4100;
-}
-
-a.footnote-reference {
-    text-decoration: none;
-    font-size: 0.7em;
-    vertical-align: top;
-    border-bottom: 1px dotted #004B6B;
-}
-
-a.footnote-reference:hover {
-    border-bottom: 1px solid #6D4100;
-}
-
-a:hover tt {
-    background: #EEE;
-}
diff --git a/doc/source/_themes/flask/static/small_flask.css b/doc/source/_themes/flask/static/small_flask.css
deleted file mode 100644 (file)
index 1c6df30..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * small_flask.css_t
- * ~~~~~~~~~~~~~~~~~
- *
- * :copyright: Copyright 2010 by Armin Ronacher.
- * :license: Flask Design License, see LICENSE for details.
- */
-
-body {
-    margin: 0;
-    padding: 20px 30px;
-}
-
-div.documentwrapper {
-    float: none;
-    background: white;
-}
-
-div.sphinxsidebar {
-    display: block;
-    float: none;
-    width: 102.5%;
-    margin: 50px -30px -20px -30px;
-    padding: 10px 20px;
-    background: #333;
-    color: white;
-}
-
-div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p,
-div.sphinxsidebar h3 a {
-    color: white;
-}
-
-div.sphinxsidebar a {
-    color: #aaa;
-}
-
-div.sphinxsidebar p.logo {
-    display: none;
-}
-
-div.document {
-    width: 100%;
-    margin: 0;
-}
-
-div.related {
-    display: block;
-    margin: 0;
-    padding: 10px 0 20px 0;
-}
-
-div.related ul,
-div.related ul li {
-    margin: 0;
-    padding: 0;
-}
-
-div.footer {
-    display: none;
-}
-
-div.bodywrapper {
-    margin: 0;
-}
-
-div.body {
-    min-height: 0;
-    padding: 0;
-}
diff --git a/doc/source/_themes/flask/theme.conf b/doc/source/_themes/flask/theme.conf
deleted file mode 100644 (file)
index 18c720f..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-[theme]
-inherit = basic
-stylesheet = flasky.css
-pygments_style = flask_theme_support.FlaskyStyle
-
-[options]
-index_logo = ''
-index_logo_height = 120px
-touch_icon = 
diff --git a/doc/source/_themes/flask_small/layout.html b/doc/source/_themes/flask_small/layout.html
deleted file mode 100644 (file)
index aa1716a..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-{% extends "basic/layout.html" %}
-{% block header %}
-  {{ super() }}
-  {% if pagename == 'index' %}
-  <div class=indexwrapper>
-  {% endif %}
-{% endblock %}
-{% block footer %}
-  {% if pagename == 'index' %}
-  </div>
-  {% endif %}
-{% endblock %}
-{# do not display relbars #}
-{% block relbar1 %}{% endblock %}
-{% block relbar2 %}
-  {% if theme_github_fork %}
-    <a href="http://github.com/{{ theme_github_fork }}"><img style="position: fixed; top: 0; right: 0; border: 0;"
-    src="http://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub" /></a>
-  {% endif %}
-{% endblock %}
-{% block sidebar1 %}{% endblock %}
-{% block sidebar2 %}{% endblock %}
diff --git a/doc/source/_themes/flask_small/static/flasky.css_t b/doc/source/_themes/flask_small/static/flasky.css_t
deleted file mode 100644 (file)
index fe2141c..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * flasky.css_t
- * ~~~~~~~~~~~~
- *
- * Sphinx stylesheet -- flasky theme based on nature theme.
- *
- * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS.
- * :license: BSD, see LICENSE for details.
- *
- */
-@import url("basic.css");
-/* -- page layout ----------------------------------------------------------- */
-body {
-    font-family: 'Georgia', serif;
-    font-size: 17px;
-    color: #000;
-    background: white;
-    margin: 0;
-    padding: 0;
-}
-
-div.documentwrapper {
-    float: left;
-    width: 100%;
-}
-
-div.bodywrapper {
-    margin: 40px auto 0 auto;
-    width: 700px;
-}
-
-hr {
-    border: 1px solid #B1B4B6;
-}
-div.body {
-    background-color: #ffffff;
-    color: #3E4349;
-    padding: 0 30px 30px 30px;
-}
-
-img.floatingflask {
-    padding: 0 0 10px 10px;
-    float: right;
-}
-div.footer {
-    text-align: right;
-    color: #888;
-    padding: 10px;
-    font-size: 14px;
-    width: 650px;
-    margin: 0 auto 40px auto;
-}
-div.footer a {
-    color: #888;
-    text-decoration: underline;
-}
-div.related {
-    line-height: 32px;
-    color: #888;
-}
-
-div.related ul {
-    padding: 0 0 0 10px;
-}
-div.related a {
-    color: #444;
-}
-/* -- body styles ----------------------------------------------------------- */
-a {
-    color: #004B6B;
-    text-decoration: underline;
-}
-a:hover {
-    color: #6D4100;
-    text-decoration: underline;
-}
-
-div.body {
-    padding-bottom: 40px; /* saved for footer */
-}
-div.body h1,
-div.body h2,
-div.body h3,
-div.body h4,
-div.body h5,
-div.body h6 {
-    font-family: 'Garamond', 'Georgia', serif;
-    font-weight: normal;
-    margin: 30px 0px 10px 0px;
-    padding: 0;
-}
-
-{% if theme_index_logo %}
-div.indexwrapper h1 {
-    text-indent: -999999px;
-    background: url({{ theme_index_logo }}) no-repeat center center;
-    height: {{ theme_index_logo_height }};
-}
-{% endif %}
-div.body h2 { font-size: 180%; }
-div.body h3 { font-size: 150%; }
-div.body h4 { font-size: 130%; }
-div.body h5 { font-size: 100%; }
-div.body h6 { font-size: 100%; }
-a.headerlink {
-    color: white;
-    padding: 0 4px;
-    text-decoration: none;
-}
-a.headerlink:hover {
-    color: #444;
-    background: #eaeaea;
-}
-div.body p, div.body dd, div.body li {
-    line-height: 1.4em;
-}
-
-div.admonition {
-    background: #fafafa;
-    margin: 20px -30px;
-    padding: 10px 30px;
-    border-top: 1px solid #ccc;
-    border-bottom: 1px solid #ccc;
-}
-
-div.admonition p.admonition-title {
-    font-family: 'Garamond', 'Georgia', serif;
-    font-weight: normal;
-    font-size: 24px;
-    margin: 0 0 10px 0;
-    padding: 0;
-    line-height: 1;
-}
-
-div.admonition p.last {
-    margin-bottom: 0;
-}
-
-div.highlight{
-    background-color: white;
-}
-
-dt:target, .highlight {
-    background: #FAF3E8;
-}
-
-div.note {
-    background-color: #eee;
-    border: 1px solid #ccc;
-}
-div.seealso {
-    background-color: #ffc;
-    border: 1px solid #ff6;
-}
-div.topic {
-    background-color: #eee;
-}
-div.warning {
-    background-color: #ffe4e4;
-    border: 1px solid #f66;
-}
-p.admonition-title {
-    display: inline;
-}
-p.admonition-title:after {
-    content: ":";
-}
-
-pre, tt {
-    font-family: 'Consolas', 'Menlo', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
-    font-size: 0.85em;
-}
-
-img.screenshot {
-}
-
-tt.descname, tt.descclassname {
-    font-size: 0.95em;
-}
-
-tt.descname {
-    padding-right: 0.08em;
-}
-
-img.screenshot {
-    -moz-box-shadow: 2px 2px 4px #eee;
-    -webkit-box-shadow: 2px 2px 4px #eee;
-    box-shadow: 2px 2px 4px #eee;
-}
-
-table.docutils {
-    border: 1px solid #888;
-    -moz-box-shadow: 2px 2px 4px #eee;
-    -webkit-box-shadow: 2px 2px 4px #eee;
-    box-shadow: 2px 2px 4px #eee;
-}
-
-table.docutils td, table.docutils th {
-    border: 1px solid #888;
-    padding: 0.25em 0.7em;
-}
-
-table.field-list, table.footnote {
-    border: none;
-    -moz-box-shadow: none;
-    -webkit-box-shadow: none;
-    box-shadow: none;
-}
-
-table.footnote {
-    margin: 15px 0;
-    width: 100%;
-    border: 1px solid #eee;
-}
-
-table.field-list th {
-    padding: 0 0.8em 0 0;
-}
-
-table.field-list td {
-    padding: 0;
-}
-
-table.footnote td {
-    padding: 0.5em;
-}
-
-dl {
-    margin: 0;
-    padding: 0;
-}
-
-dl dd {
-    margin-left: 30px;
-}
-pre {
-    padding: 0;
-    margin: 15px -30px;
-    padding: 8px;
-    line-height: 1.3em;
-    padding: 7px 30px;
-    background: #eee;
-    border-radius: 2px;
-    -moz-border-radius: 2px;
-    -webkit-border-radius: 2px;
-}
-
-dl pre {
-    margin-left: -60px;
-    padding-left: 60px;
-}
-
-tt {
-    background-color: #ecf0f3;
-    color: #222;
-    /* padding: 1px 2px; */
-}
-
-tt.xref, a tt {
-    background-color: #FBFBFB;
-}
-
-a:hover tt {
-    background: #EEE;
-}
diff --git a/doc/source/_themes/flask_small/theme.conf b/doc/source/_themes/flask_small/theme.conf
deleted file mode 100644 (file)
index 542b462..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-[theme]
-inherit = basic
-stylesheet = flasky.css
-nosidebar = true
-pygments_style = flask_theme_support.FlaskyStyle
-
-[options]
-index_logo = ''
-index_logo_height = 120px
-github_fork = ''
diff --git a/doc/source/_themes/flask_theme_support.py b/doc/source/_themes/flask_theme_support.py
deleted file mode 100644 (file)
index 33f4744..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-# flasky extensions.  flasky pygments style based on tango style
-from pygments.style import Style
-from pygments.token import Keyword, Name, Comment, String, Error, \
-     Number, Operator, Generic, Whitespace, Punctuation, Other, Literal
-
-
-class FlaskyStyle(Style):
-    background_color = "#f8f8f8"
-    default_style = ""
-
-    styles = {
-        # No corresponding class for the following:
-        #Text:                     "", # class:  ''
-        Whitespace:                "underline #f8f8f8",      # class: 'w'
-        Error:                     "#a40000 border:#ef2929", # class: 'err'
-        Other:                     "#000000",                # class 'x'
-
-        Comment:                   "italic #8f5902", # class: 'c'
-        Comment.Preproc:           "noitalic",       # class: 'cp'
-
-        Keyword:                   "bold #004461",   # class: 'k'
-        Keyword.Constant:          "bold #004461",   # class: 'kc'
-        Keyword.Declaration:       "bold #004461",   # class: 'kd'
-        Keyword.Namespace:         "bold #004461",   # class: 'kn'
-        Keyword.Pseudo:            "bold #004461",   # class: 'kp'
-        Keyword.Reserved:          "bold #004461",   # class: 'kr'
-        Keyword.Type:              "bold #004461",   # class: 'kt'
-
-        Operator:                  "#582800",   # class: 'o'
-        Operator.Word:             "bold #004461",   # class: 'ow' - like keywords
-
-        Punctuation:               "bold #000000",   # class: 'p'
-
-        # because special names such as Name.Class, Name.Function, etc.
-        # are not recognized as such later in the parsing, we choose them
-        # to look the same as ordinary variables.
-        Name:                      "#000000",        # class: 'n'
-        Name.Attribute:            "#c4a000",        # class: 'na' - to be revised
-        Name.Builtin:              "#004461",        # class: 'nb'
-        Name.Builtin.Pseudo:       "#3465a4",        # class: 'bp'
-        Name.Class:                "#000000",        # class: 'nc' - to be revised
-        Name.Constant:             "#000000",        # class: 'no' - to be revised
-        Name.Decorator:            "#888",           # class: 'nd' - to be revised
-        Name.Entity:               "#ce5c00",        # class: 'ni'
-        Name.Exception:            "bold #cc0000",   # class: 'ne'
-        Name.Function:             "#000000",        # class: 'nf'
-        Name.Property:             "#000000",        # class: 'py'
-        Name.Label:                "#f57900",        # class: 'nl'
-        Name.Namespace:            "#000000",        # class: 'nn' - to be revised
-        Name.Other:                "#000000",        # class: 'nx'
-        Name.Tag:                  "bold #004461",   # class: 'nt' - like a keyword
-        Name.Variable:             "#000000",        # class: 'nv' - to be revised
-        Name.Variable.Class:       "#000000",        # class: 'vc' - to be revised
-        Name.Variable.Global:      "#000000",        # class: 'vg' - to be revised
-        Name.Variable.Instance:    "#000000",        # class: 'vi' - to be revised
-
-        Number:                    "#990000",        # class: 'm'
-
-        Literal:                   "#000000",        # class: 'l'
-        Literal.Date:              "#000000",        # class: 'ld'
-
-        String:                    "#4e9a06",        # class: 's'
-        String.Backtick:           "#4e9a06",        # class: 'sb'
-        String.Char:               "#4e9a06",        # class: 'sc'
-        String.Doc:                "italic #8f5902", # class: 'sd' - like a comment
-        String.Double:             "#4e9a06",        # class: 's2'
-        String.Escape:             "#4e9a06",        # class: 'se'
-        String.Heredoc:            "#4e9a06",        # class: 'sh'
-        String.Interpol:           "#4e9a06",        # class: 'si'
-        String.Other:              "#4e9a06",        # class: 'sx'
-        String.Regex:              "#4e9a06",        # class: 'sr'
-        String.Single:             "#4e9a06",        # class: 's1'
-        String.Symbol:             "#4e9a06",        # class: 'ss'
-
-        Generic:                   "#000000",        # class: 'g'
-        Generic.Deleted:           "#a40000",        # class: 'gd'
-        Generic.Emph:              "italic #000000", # class: 'ge'
-        Generic.Error:             "#ef2929",        # class: 'gr'
-        Generic.Heading:           "bold #000080",   # class: 'gh'
-        Generic.Inserted:          "#00A000",        # class: 'gi'
-        Generic.Output:            "#888",           # class: 'go'
-        Generic.Prompt:            "#745334",        # class: 'gp'
-        Generic.Strong:            "bold #000000",   # class: 'gs'
-        Generic.Subheading:        "bold #800080",   # class: 'gu'
-        Generic.Traceback:         "bold #a40000",   # class: 'gt'
-    }
diff --git a/doc/source/addon-structure.txt b/doc/source/addon-structure.txt
deleted file mode 100644 (file)
index 3815174..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<addon name>
-  +-- __openerp__.py
-  +-- controllers/
-  +-- static/
-       +-- lib/
-       +-- src/
-            +-- css/
-            +-- img/
-            +-- js/
-            +-- xml/
-       +-- test/
-  +-- test/
diff --git a/doc/source/addons.rst b/doc/source/addons.rst
deleted file mode 100644 (file)
index da1f1f2..0000000
+++ /dev/null
@@ -1,558 +0,0 @@
-Developing OpenERP Web Addons
-=============================
-
-An OpenERP Web addon is simply a Python package with an openerp
-descriptor (a ``__openerp__.py`` file) which follows a few structural
-and namespacing rules.
-
-Structure
----------
-
-.. literalinclude:: addon-structure.txt
-
-``__openerp__.py``
-  The addon's descriptor, contains the following information:
-
-  ``name: str``
-    The addon name, in plain, readable english
-  ``version: str``
-    The addon version, following `Semantic Versioning`_ rules
-  ``depends: [str]``
-    A list of addons this addon needs to work correctly. ``base`` is
-    an implied dependency if the list is empty.
-  ``css: [str]``
-    An ordered list of CSS files this addon provides and needs. The
-    file paths are relative to the addon's root. Because the Web
-    Client *may* perform concatenations and other various
-    optimizations on CSS files, the order is important.
-  ``js: [str]``
-    An ordered list of Javascript files this addon provides and needs
-    (including dependencies files). As with CSS files, the order is
-    important as the Web Client *may* perform contatenations and
-    minimizations of files.
-  ``active: bool``
-    Whether this addon should be enabled by default any time it is
-    found, or whether it will be enabled through other means (on a
-    by-need or by-installation basis for instance).
-
-``controllers/``
-  All of the Python controllers and JSON-RPC endpoints.
-
-``static/``
-  The static files directory, may be served via a separate web server.
-
-``static/lib/``
-  Third-party libraries used by the addon.
-
-``static/src/{css,js,img,xml}``
-  Location for (respectively) the addon's static CSS files, its JS
-  files, its various image resources as well as the template files
-
-``static/test``
-  Javascript tests files
-
-``test/``
-  The directories in which all tests for the addon are located.
-
-Some of these are guidelines (and not enforced by code), but it's
-suggested that these be followed. Code which does not fit into these
-categories can go wherever deemed suitable.
-
-Namespacing
------------
-
-Python
-++++++
-
-Because addons are also Python packages, they're inherently namespaced
-and nothing special needs to be done on that front.
-
-JavaScript
-++++++++++
-
-The JavaScript side of an addon has to live in the namespace
-``openerp.$addon_name``. For instance, everything created by the addon
-``base`` lives in ``openerp.base``.
-
-The root namespace of the addon is a function which takes a single
-parameter ``openerp``, which is an OpenERP client instance. Objects
-(as well as functions, registry instances, etc...) should be added on
-the correct namespace on that object.
-
-The root function will be called by the OpenERP Web client when
-initializing the addon.
-
-.. code-block:: javascript
-
-    // root namespace of the openerp.example addon
-    /** @namespace */
-    openerp.example = function (openerp) {
-        // basic initialization code (e.g. templates loading)
-        openerp.example.SomeClass = openerp.base.Class.extend(
-            /** @lends openerp.example.SomeClass# */{
-            /**
-             * Description for SomeClass's constructor here
-             *
-             * @constructs
-             */
-            init: function () {
-                // SomeClass initialization code
-            }
-            // rest of SomeClass
-        });
-
-        // access an object in an other addon namespace to replace it
-        openerp.base.SearchView = openerp.base.SearchView.extend({
-            init: function () {
-                this._super.apply(this, arguments);
-                console.log('Search view initialized');
-            }
-        });
-    }
-
-Creating new standard roles
----------------------------
-
-Widget
-++++++
-
-This is the base class for all visual components. It provides a number of
-services for the management of a DOM subtree:
-
-* Rendering with QWeb
-
-* Parenting-child relations
-
-* Life-cycle management (including facilitating children destruction when a
-  parent object is removed)
-
-* DOM insertion, via jQuery-powered insertion methods. Insertion targets can
-  be anything the corresponding jQuery method accepts (generally selectors,
-  DOM nodes and jQuery objects):
-
-  :js:func:`~openerp.base.Widget.appendTo`
-    Renders the widget and inserts it as the last child of the target, uses
-    `.appendTo()`_
-
-  :js:func:`~openerp.base.Widget.prependTo`
-    Renders the widget and inserts it as the first child of the target, uses
-    `.prependTo()`_
-
-  :js:func:`~openerp.base.Widget.insertAfter`
-    Renders the widget and inserts it as the preceding sibling of the target,
-    uses `.insertAfter()`_
-
-  :js:func:`~openerp.base.Widget.insertBefore`
-    Renders the widget and inserts it as the following sibling of the target,
-    uses `.insertBefore()`_
-
-:js:class:`~openerp.base.Widget` inherits from
-:js:class:`~openerp.base.SessionAware`, so subclasses can easily access the
-RPC layers.
-
-Subclassing Widget
-~~~~~~~~~~~~~~~~~~
-
-:js:class:`~openerp.base.Widget` is subclassed in the standard manner (via the
-:js:func:`~openerp.base.Class.extend` method), and provides a number of
-abstract properties and concrete methods (which you may or may not want to
-override). Creating a subclass looks like this:
-
-.. code-block:: javascript
-
-    var MyWidget = openerp.base.Widget.extend({
-        // QWeb template to use when rendering the object
-        template: "MyQWebTemplate",
-
-        init: function(parent) {
-            this._super(parent);
-            // insert code to execute before rendering, for object
-            // initialization
-        },
-        start: function() {
-            this._super();
-            // post-rendering initialization code, at this point
-            // ``this.$element`` has been initialized
-            this.$element.find(".my_button").click(/* an example of event binding * /);
-
-            // if ``start`` is asynchronous, return a promise object so callers
-            // know when the object is done initializing
-            return this.rpc(/* … */)
-        }
-    });
-
-The new class can then be used in the following manner:
-
-.. code-block:: javascript
-
-    // Create the instance
-    var my_widget = new MyWidget(this);
-    // Render and insert into DOM
-    my_widget.appendTo(".some-div");
-
-After these two lines have executed (and any promise returned by ``appendTo``
-has been resolved if needed), the widget is ready to be used.
-
-.. note:: the insertion methods will start the widget themselves, and will
-          return the result of :js:func:`~openerp.base.Widget.start()`.
-
-          If for some reason you do not want to call these methods, you will
-          have to first call :js:func:`~openerp.base.Widget.render()` on the
-          widget, then insert it into your DOM and start it.
-
-If the widget is not needed anymore (because it's transient), simply terminate
-it:
-
-.. code-block:: javascript
-
-    my_widget.stop();
-
-will unbind all DOM events, remove the widget's content from the DOM and
-destroy all widget data.
-
-Views
-+++++
-
-Views are the standard high-level component in OpenERP. A view type corresponds
-to a way to display a set of data (coming from an OpenERP model).
-
-In OpenERP Web, views are standard objects registered against a dedicated
-object registry, so the :js:class:`~openerp.base.ViewManager` knows where to
-find and how to call them.
-
-Although not mandatory, it is recommended that views inherit from
-:js:class:`openerp.base.View`, which provides a view useful services to its
-children.
-
-Registering a view
-~~~~~~~~~~~~~~~~~~
-
-This is the first task to perform when creating a view, and the simplest by
-far: simply call ``openerp.base.views.add(name, object_path)`` to register
-the object of path ``object_path`` as the view for the view name ``name``.
-
-The view name is the name you gave to your new view in the OpenERP server.
-
-From that point onwards, OpenERP Web will be able to find your object and
-instantiate it.
-
-Standard view behaviors
-~~~~~~~~~~~~~~~~~~~~~~~
-
-In the normal OpenERP Web flow, views have to implement a number of methods so
-view managers can correctly communicate with them:
-
-``start()``
-    This method will always be called after creating the view (via its
-    constructor), but not necessarily immediately.
-
-    It is called with no arguments and should handle the heavy setup work,
-    including remote call (to load the view's setup data from the server via
-    e.g. ``fields_view_get``, for instance).
-
-    ``start`` should return a `promise object`_ which *must* be resolved when
-    the view's setup is completed. This promise is used by view managers to
-    know when they can start interacting with the view.
-
-``do_hide()``
-    Called by the view manager when it wants to replace this view by an other
-    one, but wants to keep this view around to re-activate it later.
-
-    Should put the view in some sort of hibernation mode, and *must* hide its
-    DOM elements.
-
-``do_show()``
-    Called when the view manager wants to re-display the view after having
-    hidden it. The view should refresh its data display upon receiving this
-    notification
-
-``do_search(domain: Array, context: Object, group_by: Array)``
-    If the view is searchable, this method is called to notify it of a search
-    against it.
-
-    It should use the provided query data to perform a search and refresh its
-    internal content (and display).
-
-    All views are searchable by default, but they can be made non-searchable
-    by setting the property ``searchable`` to ``false``.
-
-    This can be done either on the view class itself (at the same level as
-    defining e.g. the ``start`` method) or at the instance level (in the
-    class's ``init``), though you should generally set it on the class.
-
-Frequent development tasks
---------------------------
-
-There are a number of tasks which OpenERP Web developers do or will need to
-perform quite regularly. To make these easier, we have written a few guides
-to help you get started:
-
-.. toctree::
-    :maxdepth: 1
-
-    guides/client-action
-    guides/sidebar-protocol
-
-Translations
-------------
-
-OpenERP Web should provide most of the tools needed to correctly translate your
-addons via the tool of your choice (OpenERP itself uses `Launchpad's own
-translation tool`_.
-
-Making strings translatable
-+++++++++++++++++++++++++++
-
-QWeb
-~~~~
-
-QWeb automatically marks all text nodes (any text which is not in an XML
-attribute and not part of an XML tag) as translatable, and handles the
-replacement for you. There is nothing special to do to mark template text as
-translatable
-
-JavaScript
-~~~~~~~~~~
-
-OpenERP Web provides two functions to translate human-readable strings in
-javascript code. These functions should be "imported" in your module by
-aliasing them to their bare name:
-
-.. code-block:: javascript
-
-    var _t = openerp.web._t,
-       _tl = openerp.web._tl;
-
-importing those functions under any other name is not guaranteed to work.
-
-.. note:: only import them if necessary, and only the necessary one(s), no need
-          to clutter your module's namespace for nothing
-
-.. js:function:: openerp.web._t(s)
-
-    Base translation function, eager, works much like :manpage:`gettext(3)`
-
-    :type s: String
-    :rtype: String
-
-.. js:function:: openerp.web._lt(s)
-
-    Lazy equivalent to :js:func:`~openerp.web._t`, this function will postpone
-    fetching the translation to its argument until the last possible moment.
-
-    To use in contexts evaluated before the translation database can be
-    fetched, usually your module's toplevel and the attributes of classes
-    defined in it (class attributes, not instance attributes set in the
-    constructor).
-
-    :type s: String
-    :rtype: LazyString
-
-Text formatting & translations
-""""""""""""""""""""""""""""""
-
-A difficulty when translating is integrating data (from the code) into the
-translated string. In OpenERP Web addons, this should be done by wrapping the
-text to translate in an :manpage:`sprintf(3)` call. For OpenERP Web,
-:manpage:`sprintf(3)` is provided by `underscore.string
-<http://epeli.github.com/underscore.string/>`_.
-
-As much as possible, you should use the "named argument" form of sprintf:
-
-.. code-block:: javascript
-
-    var translated_string = _.str.sprintf(
-        _t("[%(first_record)d to %(last_record)d] of %(records_count)d"), {
-            first_record: first + 1,
-            last_record: last,
-            records_count: total
-        }));
-
-named arguments make the string to translate much clearer for translators, and
-allows them to "move" sections around based on the requirements of their
-language (not all language order text like english).
-
-Named arguments are specified using the following pattern: ``%($name)$type``
-where
-
-``$name``
-  the name of the argument, this is the key in the object/dictionary provided
-  as second parameter to ``sprintf``
-``$type``
-  a type/format specifier, `see the list for all possible types
-  <http://www.diveintojavascript.com/projects/javascript-sprintf>`_.
-
-.. note:: positional arguments are acceptable if the translated string has
-          *a single* argument and its content is easy to guess from the text
-          around it. Named arguments should still be preferred.
-
-.. warning:: you should *never* use string concatenation as it robs the
-             translator of context and make result in a completely incorrect
-             translation
-
-Extracting strings
-~~~~~~~~~~~~~~~~~~
-
-.. program:: gen_translations.sh
-
-Once strings have been marked for translation, they need to be extracted into
-:abbr:`POT (Portable Object Template)` files, from which most translation tools
-can build a database.
-
-This can be done via the provided :program:`gen_translations.sh`.
-
-It can be called either as :option:`gen_translations.sh -a` or by providing
-two parameters, a path to the addons and the complete path in which to put the
-extracted POT file.
-
-.. option:: -a
-
-    Extracts translations from all standard OpenERP Web addons (addons bundled
-    with OpenERP Web itself) and puts the extracted templates into the right
-    directory for `Rosetta`_ to handle them
-
-Utility behaviors
------------------
-
-JavaScript
-++++++++++
-
-* All javascript objects inheriting from
-  :js:class:`openerp.base.BasicConroller` will have all methods
-  starting with ``on_`` or ``do_`` bound to their ``this``. This means
-  they don't have to be manually bound (via ``_.bind`` or ``$.proxy``)
-  in order to be useable as bound event handlers (event handlers
-  keeping their object as ``this`` rather than taking whatever
-  ``this`` object they were called with).
-
-  Beware that this is only valid for methods starting with ``do_`` and
-  ``on_``, any other method will have to be bound manually.
-
-.. _addons-testing:
-
-Testing
--------
-
-Python
-++++++
-
-OpenERP Web uses unittest2_ for its testing needs. We selected
-unittest2 rather than unittest_ for the following reasons:
-
-* autodiscovery_ (similar to nose, via the ``unit2``
-  CLI utility) and `pluggable test discovery`_.
-
-* `new and improved assertions`_ (with improvements in type-specific
-  inequality reportings) including `pluggable custom types equality
-  assertions`_
-
-* neveral new APIs, most notably `assertRaises context manager`_,
-  `cleanup function registration`_, `test skipping`_ and `class- and
-  module-level setup and teardown`_
-
-* finally, unittest2 is a backport of Python 3's unittest. We might as
-  well get used to it.
-
-To run tests on addons (from the root directory of OpenERP Web) is as
-simple as typing ``PYTHONPATH=. unit2 discover -s addons`` [#]_. To
-test an addon which does not live in the ``addons`` directory, simply
-replace ``addons`` by the directory in which your own addon lives.
-
-.. note:: unittest2 is entirely compatible with nose_ (or the
-     other way around). If you want to use nose as your test
-     runner (due to its addons for instance) you can simply install it
-     and run ``nosetests addons`` instead of the ``unit2`` command,
-     the result should be exactly the same.
-
-Python
-++++++
-
-.. autoclass:: web.common.session.OpenERPSession
-    :members:
-
-.. autoclass:: web.common.openerplib.main.Model
-    :members:
-
-* Addons lifecycle (loading, execution, events, ...)
-
-  * Python-side
-  * JS-side
-
-* Handling static files
-* Overridding a Python controller (object?)
-* Overridding a Javascript controller (object?)
-* Extending templates
-  .. how do you handle deploying static files via e.g. a separate lighttpd?
-* Python public APIs
-* QWeb templates description?
-* OpenERP Web modules (from OpenERP modules)
-
-.. [#] the ``-s`` parameter tells ``unit2`` to start trying to
-       find tests in the provided directory (here we're testing
-       addons). However a side-effect of that is to set the
-       ``PYTHONPATH`` there as well, so it will fail to find (and
-       import) ``openerpweb``.
-
-       The ``-t`` parameter lets us set the ``PYTHONPATH``
-       independently, but it doesn't accept multiple values and here
-       we really want to have both ``.`` and ``addons`` on the
-       ``PYTHONPATH``.
-
-       The solution is to set the ``PYTHONPATH`` to ``.`` on start,
-       and the ``start-directory`` to ``addons``. This results in a
-       correct ``PYTHONPATH`` within ``unit2``.
-
-.. _unittest:
-    http://docs.python.org/library/unittest.html
-
-.. _unittest2:
-    http://www.voidspace.org.uk/python/articles/unittest2.shtml
-
-.. _autodiscovery:
-    http://www.voidspace.org.uk/python/articles/unittest2.shtml#test-discovery
-
-.. _pluggable test discovery:
-    http://www.voidspace.org.uk/python/articles/unittest2.shtml#load-tests
-
-.. _new and improved assertions:
-    http://www.voidspace.org.uk/python/articles/unittest2.shtml#new-assert-methods
-
-.. _pluggable custom types equality assertions:
-    http://www.voidspace.org.uk/python/articles/unittest2.shtml#add-new-type-specific-functions
-
-.. _assertRaises context manager:
-    http://www.voidspace.org.uk/python/articles/unittest2.shtml#assertraises
-
-.. _cleanup function registration:
-    http://www.voidspace.org.uk/python/articles/unittest2.shtml#cleanup-functions-with-addcleanup
-
-.. _test skipping:
-    http://www.voidspace.org.uk/python/articles/unittest2.shtml#test-skipping
-
-.. _class- and module-level setup and teardown:
-    http://www.voidspace.org.uk/python/articles/unittest2.shtml#class-and-module-level-fixtures
-
-.. _Semantic Versioning:
-    http://semver.org/
-
-.. _nose:
-    http://somethingaboutorange.com/mrl/projects/nose/1.0.0/
-
-.. _promise object:
-    http://api.jquery.com/deferred.promise/
-
-.. _.appendTo():
-    http://api.jquery.com/appendTo/
-
-.. _.prependTo():
-    http://api.jquery.com/prependTo/
-
-.. _.insertAfter():
-    http://api.jquery.com/insertAfter/
-
-.. _.insertBefore():
-    http://api.jquery.com/insertBefore/
-
-.. _Rosetta:
-.. _Launchpad's own translation tool:
-    https://help.launchpad.net/Translations
diff --git a/doc/source/conf.py b/doc/source/conf.py
deleted file mode 100644 (file)
index eb2b10d..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# OpenERP Technical Documentation configuration file, created by
-# sphinx-quickstart on Fri Feb 17 16:14:06 2012.
-#
-# This file is execfile()d with the current directory set to its containing dir.
-#
-# Note that not all possible configuration values are present in this
-# autogenerated file.
-#
-# All configuration values have a default; values that are commented out
-# serve to show the default.
-
-import sys, os
-
-# If extensions (or modules to document with autodoc) are in another directory,
-# add these directories to sys.path here. If the directory is relative to the
-# documentation root, use os.path.abspath to make it absolute, like shown here.
-sys.path.append(os.path.abspath('_themes'))
-sys.path.insert(0, os.path.abspath('../../addons'))
-sys.path.insert(0, os.path.abspath('../..'))
-
-# -- General configuration -----------------------------------------------------
-
-# If your documentation needs a minimal Sphinx version, state it here.
-#needs_sphinx = '1.0'
-
-# Add any Sphinx extension module names here, as strings. They can be extensions
-# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.viewcode']
-
-# Add any paths that contain templates here, relative to this directory.
-templates_path = ['_templates']
-
-# The suffix of source filenames.
-source_suffix = '.rst'
-
-# The encoding of source files.
-#source_encoding = 'utf-8-sig'
-
-# The master toctree document.
-master_doc = 'index'
-
-# General information about the project.
-project = u'OpenERP Server Developers Documentation'
-copyright = u'2012, OpenERP s.a.'
-
-# The version info for the project you're documenting, acts as replacement for
-# |version| and |release|, also used in various other places throughout the
-# built documents.
-#
-# The short X.Y version.
-version = '6.1'
-# The full version, including alpha/beta/rc tags.
-release = '6.1'
-
-# The language for content autogenerated by Sphinx. Refer to documentation
-# for a list of supported languages.
-#language = None
-
-# There are two options for replacing |today|: either, you set today to some
-# non-false value, then it is used:
-#today = ''
-# Else, today_fmt is used as the format for a strftime call.
-#today_fmt = '%B %d, %Y'
-
-# List of patterns, relative to source directory, that match files and
-# directories to ignore when looking for source files.
-exclude_patterns = ['_build']
-
-# The reST default role (used for this markup: `text`) to use for all documents.
-#default_role = None
-
-# If true, '()' will be appended to :func: etc. cross-reference text.
-#add_function_parentheses = True
-
-# If true, the current module name will be prepended to all description
-# unit titles (such as .. function::).
-#add_module_names = True
-
-# If true, sectionauthor and moduleauthor directives will be shown in the
-# output. They are ignored by default.
-#show_authors = False
-
-# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
-
-# A list of ignored prefixes for module index sorting.
-#modindex_common_prefix = []
-
-
-# -- Options for HTML output ---------------------------------------------------
-
-# The theme to use for HTML and HTML Help pages.  See the documentation for
-# a list of builtin themes.
-html_theme = 'flask'
-
-# Theme options are theme-specific and customize the look and feel of a theme
-# further.  For a list of options available for each theme, see the
-# documentation.
-#html_theme_options = {}
-
-# Add any paths that contain custom themes here, relative to this directory.
-html_theme_path = ['_themes']
-
-# The name for this set of Sphinx documents.  If None, it defaults to
-# "<project> v<release> documentation".
-#html_title = None
-
-# A shorter title for the navigation bar.  Default is the same as html_title.
-#html_short_title = None
-
-# The name of an image file (relative to this directory) to place at the top
-# of the sidebar.
-#html_logo = None
-
-# The name of an image file (within the static path) to use as favicon of the
-# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
-# pixels large.
-#html_favicon = None
-
-# Add any paths that contain custom static files (such as style sheets) here,
-# relative to this directory. They are copied after the builtin static files,
-# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['_static']
-
-# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
-# using the given strftime format.
-#html_last_updated_fmt = '%b %d, %Y'
-
-# If true, SmartyPants will be used to convert quotes and dashes to
-# typographically correct entities.
-#html_use_smartypants = True
-
-# Custom sidebar templates, maps document names to template names.
-html_sidebars = {
-    'index':    ['sidebarintro.html', 'sourcelink.html', 'searchbox.html'],
-    '**':       ['sidebarlogo.html', 'localtoc.html', 'relations.html',
-                 'sourcelink.html', 'searchbox.html']
-}
-
-# Additional templates that should be rendered to pages, maps page names to
-# template names.
-#html_additional_pages = {}
-
-# If false, no module index is generated.
-#html_domain_indices = True
-
-# If false, no index is generated.
-#html_use_index = True
-
-# If true, the index is split into individual pages for each letter.
-#html_split_index = False
-
-# If true, links to the reST sources are added to the pages.
-#html_show_sourcelink = True
-
-# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
-#html_show_sphinx = True
-
-# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
-#html_show_copyright = True
-
-# If true, an OpenSearch description file will be output, and all pages will
-# contain a <link> tag referring to it.  The value of this option must be the
-# base URL from which the finished HTML is served.
-#html_use_opensearch = ''
-
-# This is the file name suffix for HTML files (e.g. ".xhtml").
-#html_file_suffix = None
-
-# Output file base name for HTML help builder.
-htmlhelp_basename = 'openerp-server-doc'
-
-
-# -- Options for LaTeX output --------------------------------------------------
-
-latex_elements = {
-# The paper size ('letterpaper' or 'a4paper').
-#'papersize': 'letterpaper',
-
-# The font size ('10pt', '11pt' or '12pt').
-#'pointsize': '10pt',
-
-# Additional stuff for the LaTeX preamble.
-#'preamble': '',
-}
-
-# Grouping the document tree into LaTeX files. List of tuples
-# (source start file, target name, title, author, documentclass [howto/manual]).
-latex_documents = [
-  ('index', 'openerp-server-doc.tex', u'OpenERP Server Developers Documentation',
-   u'OpenERP s.a.', 'manual'),
-]
-
-# The name of an image file (relative to this directory) to place at the top of
-# the title page.
-#latex_logo = None
-
-# For "manual" documents, if this is true, then toplevel headings are parts,
-# not chapters.
-#latex_use_parts = False
-
-# If true, show page references after internal links.
-#latex_show_pagerefs = False
-
-# If true, show URL addresses after external links.
-#latex_show_urls = False
-
-# Documents to append as an appendix to all manuals.
-#latex_appendices = []
-
-# If false, no module index is generated.
-#latex_domain_indices = True
-
-
-# -- Options for manual page output --------------------------------------------
-
-# One entry per manual page. List of tuples
-# (source start file, name, description, authors, manual section).
-man_pages = [
-    ('index', 'openerp-server-doc', u'OpenERP Server Developers Documentation',
-     [u'OpenERP s.a.'], 1)
-]
-
-# If true, show URL addresses after external links.
-#man_show_urls = False
-
-
-# -- Options for Texinfo output ------------------------------------------------
-
-# Grouping the document tree into Texinfo files. List of tuples
-# (source start file, target name, title, author,
-#  dir menu entry, description, category)
-texinfo_documents = [
-  ('index', 'OpenERPServerDocumentation', u'OpenERP Server Developers Documentation',
-   u'OpenERP s.a.', 'OpenERPServerDocumentation', 'Developers documentation for the openobject-server project.',
-   'Miscellaneous'),
-]
-
-# Documents to append as an appendix to all manuals.
-#texinfo_appendices = []
-
-# If false, no module index is generated.
-#texinfo_domain_indices = True
-
-# How to display URL addresses: 'footnote', 'no', or 'inline'.
-#texinfo_show_urls = 'footnote'
-
-
-# Example configuration for intersphinx: refer to the Python standard library.
-intersphinx_mapping = {
-    'python': ('http://docs.python.org/', None),
-    'openerpserver': ('http://doc.openerp.com/v6.1/developers/server', None),
-    'openerpdev': ('http://doc.openerp.com/v6.1/developers', None),
-}
diff --git a/doc/source/development.rst b/doc/source/development.rst
deleted file mode 100644 (file)
index 7431a3e..0000000
+++ /dev/null
@@ -1,424 +0,0 @@
-OpenERP Web Core and standard addons
-====================================
-
-* General organization and core ideas (design philosophies)
-* Internal documentation, autodoc, Python and JS domains
-* QWeb code documentation/description
-* Documentation of the OpenERP APIs and choices taken based on that?
-* Style guide and coding conventions (PEP8? More)
-* Test frameworks in JS?
-
-Standard Views
---------------
-
-Search View
-+++++++++++
-
-The OpenERP search view really is a sub-view, used in support of views
-acting on collections of records (list view or graph view, for
-instance).
-
-Its main goal is to collect information from its widgets (themselves
-collecting information from the users) and make those available to the
-rest of the client.
-
-The search view's root is :js:class:`~openerp.base.SearchView`. This
-object should never need to be created or managed directly, its
-lifecycle should be driven by the
-:js:class:`~openerp.base.ViewManager`.
-
-.. TODO: insert SearchView constructor here
-
-The search view defines a number of internal and external protocols to
-communicate with the objects around and within it. Most of these
-protocols are informal, and types available for inheritance are more
-mixins than mandatory.
-
-Events
-""""""
-
-``on_loaded``
-
-  .. TODO: method openerp.base.SearchView.on_loaded
-
-  Fires when the search view receives its view data (the result of
-  ``fields_view_get``). Hooking up before the event allows for
-  altering view data before it can be used.
-
-  By the time ``on_loaded`` is done, the search view is guaranteed to
-  be fully set up and ready to use.
-
-``on_search``
-
-  .. TODO: method openerp.base.SearchView.on_search
-
-  Event triggered after a user asked for a search. The search view
-  fires this event after collecting all input data (contexts, domains
-  and group_by contexts). Note that the search view does *not* merge
-  those (or otherwise evaluate them), they are returned as provided by
-  the various inputs within the view.
-
-``on_clear``
-
-  .. TODO: method openerp.base.SearchView.on_clear
-
-  Triggered after a user asked for a form clearing.
-
-Input management
-""""""""""""""""
-
-An important concept in the search view is that of input. It is both
-an informal protocol and an abstract type that can be inherited from.
-
-Inputs are widgets which can contain user data (a char widget for
-instance, or a selection box). They are capable of action and of
-reaction:
-
-.. _views-search-registration:
-
-``registration``
-
-  This is an input action. Inputs have to register themselves to the
-  main view (which they receive as a constructor argument). This is
-  performed by pushing themselves on the
-  :js:attr:`openerp.base.SearchView.inputs` array.
-
-``get_context``
-
-  An input reaction. When it needs to collect contexts, the view calls
-  ``get_context()`` on all its inputs.
-
-  Inputs can react in the following manners:
-
-  * Return a context (an object), this is the "normal" response if the
-    input holds a value.
-
-  * Return a value that evaluates as false (generally ``null``). This
-    value indicates the input does not contain any value and will not
-    affect the results of the search.
-
-  * Raise :js:class:`openerp.base.search.Invalid` to indicate that it
-    holds a value but this value can not be used in the search
-    (because it is incorrectly formatted or nonsensical). Raising
-    :js:class:`~openerp.base.search.Invalid` is guaranteed to cancel
-    the search process.
-
-    :js:class:`~openerp.base.search.Invalid` takes three mandatory
-    arguments: an identifier (a name for instance), the invalid value,
-    and a validation message indicating the issue.
-
-``get_domain``
-
-  The second input reaction, the possible behaviors of inputs are the
-  same as for ``get_context``.
-
-The :js:class:`openerp.base.search.Input` type implements registration
-on its own, but its implementations of ``get_context`` and
-``get_domain`` simply raise errors and *must* be overridden.
-
-One last action is for filters, as an activation order has to be kept
-on them for some controls (to establish the correct grouping sequence,
-for instance).
-
-To that end, filters can call
-:js:func:`openerp.base.Search.do_toggle_filter`, providing themselves
-as first argument.
-
-Filters calling :js:func:`~openerp.base.Search.do_toggle_filter` also
-need to implement a method called
-:js:func:`~openerp.base.search.Filter.is_enabled`, which the search
-view will use to know the current status of the filter.
-
-The search view automatically triggers a search after calls to
-:js:func:`~openerp.base.Search.do_toggle_filter`.
-
-Life cycle
-""""""""""
-
-The search view has a pretty simple and linear life cycle, in three main steps:
-
-:js:class:`~openerp.base.SearchView.init`
-
-  Nothing interesting happens here
-
-:js:func:`~openerp.base.SearchView.start`
-
-  Called by the main view's creator, this is the main initialization
-  step for the list view.
-
-  It begins with a remote call to fetch the view's descriptors
-  (``fields_view_get``).
-
-  Once the remote call is complete, the ``on_loaded`` even happens,
-  holding three main operations:
-
-  :js:func:`~openerp.base.SearchView.make_widgets`
-
-    Builds and returns the top-level widgets of the search
-    view. Because it returns an array of widget lines (a 2-dimensional
-    matrix of widgets) it should be called recursively by container
-    widgets (:js:class:`openerp.base.search.Group` for instance).
-
-  :js:func:`~openerp.base.search.Widget.render`
-
-    Called by the search view on all top-level widgets. Container
-    widgets should recursively call this method on their own children
-    widgets.
-
-    Widgets are provided with a mapping of ``{name: value}`` holding
-    default values for the search view. They can freely pick their
-    initial values from there, but must pass the mapping to their
-    children widgets if they have any.
-
-  :js:func:`~openerp.base.search.Widget.start`
-
-    The last operation of the search view startup is to initialize all
-    its widgets in order. This is again done recursively (the search
-    view starts its children, which have to start their own children).
-
-:js:func:`~openerp.base.SearchView.stop`
-
-  Used before discarding a search view, allows the search view to
-  disable its events and pass the message to its own widgets,
-  gracefully shutting down the whole view.
-
-Widgets
-"""""""
-
-In a search view, the widget is simply a unit of display.
-
-All widgets must be able to react to three events, which will be
-called in this order:
-
-:js:func:`~openerp.base.search.Widget.render`
-
-  Called with a map of default values. The widget must return a
-  ``String``, which is its HTML representation. That string can be
-  empty (if the widget should not be represented).
-
-  Widgets are responsible for asking their children for rendering, and
-  for passing along the default values.
-
-:js:func:`~openerp.base.search.Widget.start`
-
-  Called without arguments. At this point, the widget has been fully
-  rendered and can set its events up, if any.
-
-  The widget is responsible for starting its children, if it has any.
-
-:js:func:`~openerp.base.search.Widget.stop`
-
-  Gives the widget the opportunity to unbind its events, remove itself
-  from the DOM and perform any other cleanup task it may have.
-
-  Even if the widget does not do anything itself, it is responsible
-  for shutting down its children.
-
-An abstract type is available and can be inherited from, to simplify
-the implementation of those tasks:
-
-.. TODO: insert Widget here
-
-.. remember to document all methods
-
-Inputs
-""""""
-
-The search namespace (``openerp.base.search``) provides two more
-abstract types, used to implement input widgets:
-
-* :js:class:`openerp.base.search.Input` is the most basic input type,
-  it only implements :ref:`input registration
-  <views-search-registration>`.
-
-  If inherited from, descendant classes should not call its
-  implementations of :js:func:`~openerp.base.search.Input.get_context`
-  and :js:func:`~openerp.base.search.Input.get_domain`.
-
-* :js:class:`openerp.base.search.Field` is used to implement more
-  "field" widgets (which allow the user to input potentially complex
-  values).
-
-  It provides various services for its subclasses:
-
-  * Sets up the field attributes, using attributes from the field and
-    the view node.
-
-  * It fills the widget with :js:class:`~openerp.base.search.Filter`
-    if the field has any child filter.
-
-  * It automatically generates an identifier based on the field type
-    and the field name, using
-    :js:func:`~openerp.base.search.Widget.make_id`.
-
-  * It sets up a basic (overridable)
-    :js:attr:`~openerp.base.search.Field.template` attribute, combined
-    with the previous tasks, this makes subclasses of
-    :js:class:`~openerp.base.search.Field` render themselves "for
-    free".
-
-  * It provides basic implementations of ``get_context`` and
-    ``get_domain``, both hinging on the subclasses implementing
-    ``get_value()`` (which should return a correct, converted
-    Javascript value):
-
-    :js:func:`~openerp.base.search.Field.get_context`
-
-        Checks if the field has a non-``null`` and non-empty
-        (``String``) value, and that the field has a ``context`` attr.
-
-        If both conditions are fullfilled, returns the context.
-
-    :js:func:`~openerp.base.search.Field.get_domain`
-
-        Only requires that the field has a non-``null`` and non-empty
-        value.
-
-        If the field has a ``filter_domain``, returns it
-        immediately. Otherwise, builds a context using the field's
-        name, the field :js:attr:`~openerp.base.search.Field.operator`
-        and the field value, and returns it.
-
-.. TODO: insert Input, Field, Filter, and just about every Field subclass
-
-List View
-+++++++++
-
-OpenERP Web's list views don't actually exist as such in OpenERP itself: a
-list view is an OpenERP tree view in the ``view_mode`` form.
-
-The overall purpose of a list view is to display collections of objects in two
-main forms: per-object, where each object is a row in and of itself, and
-grouped, where multiple objects are represented with a single row providing
-an aggregated view of all grouped objects.
-
-These two forms can be mixed within a single list view, if needed.
-
-The root of a list view is :js:class:`openerp.base.ListView`, which may need
-to be overridden (partially or fully) to control list behavior in non-view
-cases (when using a list view as sub-component of a form widget for instance).
-
-Creation and Initialization
-"""""""""""""""""""""""""""
-
-As with most OpenERP Web views, the list view's
-:js:func:`~openerp.base.ListView.init` takes quite a number of arguments.
-
-While most of them are the standard view constructor arguments
-(``view_manager``, ``session``, ``element_id``, ``dataset`` and an
-optional ``view_id``), the list view adds a number of options for basic
-customization (without having to override methods or templates):
-
-``selectable`` (default: ``true``)
-    Indicates that the list view should allow records to be selected
-    individually. Displays selection check boxes to the left of all record rows,
-    and allows for the triggering of the
-    :ref:`selection event <listview-events-selection>`.
-``deletable`` (default: ``true``)
-    Indicates that the list view should allow records to be removed
-    individually. Displays a deletion button to the right of all record rows,
-    and allows for the triggering of the
-    :ref:`deletion event <listview-events-deletion>`.
-``header`` (default: ``true``)
-    Indicates that list columns should bear a header sporting their name (for
-    non-action columns).
-``addable`` (default: ``"New"``)
-    Indicates that a record addition/creation button should be displayed in
-    the list's header, along with its label. Also allows for the triggering of
-    the :ref:`record addition event <listview-events-addition>`.
-``sortable`` (default: ``true``)
-    Indicates that the list view can be sorted per-column (by clicking on its
-    column headers).
-
-    .. TODO: event?
-``reorderable`` (default: ``true``)
-    Indicates that the list view records can be reordered (and re-sequenced)
-    by drag and drop.
-
-    .. TODO: event?
-
-Events
-""""""
-.. _listview-events-addition:
-
-Addition
-''''''''
-The addition event is used to add a record to an existing list view. The
-default behavior is to switch to the form view, on a new record.
-
-Addition behavior can be overridden by replacing the
-:js:func:`~openerp.base.ListView.do_add_record` method.
-
-.. _listview-events-selection:
-
-Selection
-'''''''''
-The selection event is triggered when a given record is selected in the list
-view.
-
-It can be overridden by replacing the
-:js:func:`~openerp.base.ListView.do_select` method.
-
-The default behavior is simply to hide or display the list-wise deletion button
-depending on whether there are selected records or not.
-
-.. _listview-events-deletion:
-
-Deletion
-''''''''
-The deletion event is triggered when the user tries to remove 1..n records from
-the list view, either individually or globally (via the header button).
-
-Deletion can be overridden by replacing the
-:js:func:`~openerp.base.ListView.do_delete` method. By default, this method
-calls :js:func:`~openerp.base.DataSet.unlink` in order to remove the records
-entirely.
-
-.. note::
-
-  the list-wise deletion button (next to the record addition button)
-  simply proxies to :js:func:`~openerp.base.ListView.do_delete` after
-  obtaining all selected record ids, but it is possible to override it
-  alone by replacing
-  :js:func:`~openerp.base.ListView.do_delete_selected`.
-
-Internal API Doc
-----------------
-
-Python
-++++++
-
-These classes should be moved to other sections of the doc as needed,
-probably.
-
-.. automodule:: web.common.http
-    :members:
-    :undoc-members:
-
-    See also: :class:`~web.common.session.OpenERPSession`,
-    :class:`~web.common.openerplib.main.OpenERPModel`
-
-.. automodule:: web.controllers.main
-    :members:
-    :undoc-members:
-
-Testing
--------
-
-Python
-++++++
-
-Testing for the OpenERP Web core is similar to :ref:`testing addons
-<addons-testing>`: the tests live in ``openerpweb.tests``, unittest2_
-is the testing framework and tests can be run via either unittest2
-(``unit2 discover``) or via nose_ (``nosetests``).
-
-Tests for the OpenERP Web core can also be run using ``setup.py
-test``.
-
-
-.. _unittest2:
-    http://www.voidspace.org.uk/python/articles/unittest2.shtml
-
-.. _nose:
-    http://somethingaboutorange.com/mrl/projects/nose/1.0.0/
diff --git a/doc/source/getting-started.rst b/doc/source/getting-started.rst
deleted file mode 100644 (file)
index cd7f7ee..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-Getting Started with OpenERP Web
-================================
-
-Installing
-----------
-
-.. per-distro packaging
-
-Launching
----------
diff --git a/doc/source/guides/client-action.rst b/doc/source/guides/client-action.rst
deleted file mode 100644 (file)
index 2e11773..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-Creating a new client action
-============================
-
-Client actions are the client-side of OpenERP's "Server Actions": instead of
-allowing for semi-arbitrary code to be executed in the server, they allow
-for execution of client-customized code.
-
-On the server side, a client action is an action of type ``ir.actions.client``,
-which has (at most) two properties: a mandatory ``tag``, which is an arbitrary
-string by which the client will identify the action, and an optional ``params``
-which is simply a map of keys and values sent to the client as-is (this way,
-client actions can be made generic and reused in multiple contexts).
-
-General Structure
------------------
-
-In the OpenERP Web code, a client action only requires two pieces of
-information:
-
-* Mapping the action's ``tag`` to an OpenERP Web object
-
-* The OpenERP Web object itself, which must inherit from
-  :js:class:`openerp.web.Widget`
-
-Our example will be the actual code for the widgets client action (a client
-action displaying a ``res.widget`` object, used in the homepage dashboard of
-the web client):
-
-.. code-block:: javascript
-
-    // Registers the object 'openerp.web_dashboard.Widget' to the client
-    // action tag 'board.home.widgets'
-    openerp.web.client_actions.add(
-        'board.home.widgets', 'openerp.web_dashboard.Widget');
-    // This object inherits from View, but only Widget is required
-    openerp.web_dashboard.Widget = openerp.web.View.extend({
-        template: 'HomeWidget'
-    });
-
-At this point, the generic ``Widget`` lifecycle takes over, the template is
-rendered, inserted in the client DOM, bound on the object's ``$element``
-property and the object is started.
-
-If the client action takes parameters, these parameters are passed in as a
-second positional parameter to the constructor:
-
-.. code-block:: javascript
-
-    init: function (parent, params) {
-        // execute the Widget's init
-        this._super(parent);
-        // board.home.widgets only takes a single param, the identifier of the
-        // res.widget object it should display. Store it for later
-        this.widget_id = params.widget_id;
-    }
-
-More complex initialization (DOM manipulations, RPC requests, ...) should be
-performed in the ``start()`` method.
-
-.. note::
-    As required by ``Widget``'s contract, if ``start`` executes any
-    asynchronous code it should return a ``$.Deferred`` so callers know when
-    it's ready for interaction.
-
-    Although generally speaking client actions are not really interacted with.
-
-.. code-block:: javascript
-
-    start: function () {
-        return $.when(
-            this._super(),
-            // Simply read the res.widget object this action should display
-            new openerp.web.DataSet(this, 'res.widget').read_ids(
-                [this.widget_id], ['title'], this.on_widget_loaded));
-    }
-
-The client action can then behave exactly as it wishes to within its root
-(``this.$element``). In this case, it performs further renderings once its
-widget's content is retrieved:
-
-.. code-block:: javascript
-
-    on_widget_loaded: function (widgets) {
-        var widget = widgets[0];
-        var url = _.sprintf(
-            '/web_dashboard/widgets/content?session_id=%s&widget_id=%d',
-            this.session.session_id, widget.id);
-        this.$element.html(QWeb.render('HomeWidget.content', {
-            widget: widget,
-            url: url
-        }));
-    }
diff --git a/doc/source/guides/sidebar-protocol.rst b/doc/source/guides/sidebar-protocol.rst
deleted file mode 100644 (file)
index 83626c3..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-Adding a sidebar to a view
-==========================
-
-Initialization
---------------
-
-Each view has the responsibility to create its sidebar (or not) if and only if
-the ``sidebar`` flag is set in its options.
-
-In that case, it should use the ``sidebar_id`` value (from its options) to
-initialize the sidebar at the right position in the DOM:
-
-.. code-block:: javascript
-
-    if (this.options.sidebar && this.options.sidebar_id) {
-        this.sidebar = new openerp.web.Sidebar(this, this.options.sidebar_id);
-        this.sidebar.start();
-    }
-
-Because the sidebar is an old-style widget, it must be started after being
-initialized.
-
-Sidebar communication protocol
-------------------------------
-
-In order to behave correctly, a sidebar needs informations from its parent
-view.
-
-This information is extracted via a very basic protocol consisting of a
-property and two methods:
-
-.. js:attribute:: dataset
-
-    the view's dataset, used to fetch the currently active model and provide it
-    to remote action handlers as part of the basic context
-
-.. js:function:: get_selected_ids()
-
-    Used to query the parent view for the set of currently available record
-    identifiers. Used to setup the basic context's ``active_id`` and
-    ``active_ids`` keys.
-
-    .. warning::
-
-        :js:func:`get_selected_ids` must return at least one id
-
-    :returns: an array of at least one id
-    :rtype: Array<Number>
-
-.. js:function:: sidebar_context()
-
-    Queries the view for additional context data to provide to the sidebar.
-
-    :js:class:`~openerp.base.View` provides a default NOOP implementation,
-    which simply resolves to an empty object.
-
-    :returns: a promise yielding an object on success, this object is mergeed
-              into the sidebar's own context
-    :rtype: $.Deferred<Object>
-
-Programmatic folding and unfolding
-----------------------------------
-
-The sidebar object starts folded. It provides three methods to handle its
-folding status:
-
-.. js:function:: do_toggle
-
-    Toggles the status of the sidebar
-
-.. js:function:: do_fold
-
-    Forces the sidebar closed if it's currently open
-
-.. js:function:: do_unfold
-
-    Forces the sidebar open if it's currently closed
-
diff --git a/doc/source/index.rst b/doc/source/index.rst
deleted file mode 100644 (file)
index efa4d1c..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-.. OpenERP Web documentation master file, created by
-   sphinx-quickstart on Fri Mar 18 16:31:55 2011.
-   You can adapt this file completely to your liking, but it should at least
-   contain the root `toctree` directive.
-
-Welcome to OpenERP Web's documentation!
-=======================================
-
-Contents:
-
-.. toctree::
-   :maxdepth: 2
-
-   getting-started
-   production
-   widgets
-   addons
-   development
-   project
-   old-version
-
-Indices and tables
-==================
-
-* :ref:`genindex`
-* :ref:`modindex`
-* :ref:`search`
diff --git a/doc/source/old-version.rst b/doc/source/old-version.rst
deleted file mode 100644 (file)
index d745806..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-Main differences with the 6.0 client
-====================================
-
-.. No more populate.sh, use virtualenvs
-
-.. Logic is mainly in Javascript (had to make a choice between JS and
-.. Python logic)
-
-.. Templating language changes
-
-.. How to port addons and modules?
diff --git a/doc/source/production.rst b/doc/source/production.rst
deleted file mode 100644 (file)
index 2524471..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-Deploying OpenERP Web
-=====================
-
-.. After release one, add upgrade instructions if any
-
-.. How about running the web client on alternative Python
-.. implementations e.g. pypy or Jython? Since the only lib with C
-.. accelerators we're using right now is SimpleJSON and it has a pure
-.. Python base component, we should be able to test and deploy on
-.. non-cpython no?
-
-In-depth configuration
-----------------------
-
-SSL, basic proxy (link to relevant section), links to sections and
-example files for various servers and proxies, WSGI
-integration/explanation (if any), ...
-
-Deployment Options
-------------------
-
-Serving via WSGI
-~~~~~~~~~~~~~~~~
-
-Apache mod_wsgi
-+++++++++++++++
-
-NGinx mod_wsgi
-++++++++++++++
-
-uWSGI
-+++++
-
-Gunicorn
-++++++++
-
-FastCGI, SCGI, or AJP
-+++++++++++++++++++++
-
-Behind a proxy
-~~~~~~~~~~~~~~
-
-Apache mod_proxy
-++++++++++++++++
-
-NGinx HttpProxy
-+++++++++++++++
diff --git a/doc/source/project.rst b/doc/source/project.rst
deleted file mode 100644 (file)
index aa465aa..0000000
+++ /dev/null
@@ -1,451 +0,0 @@
-The OpenERP Web open-source project
-===================================
-
-Getting involved
-----------------
-
-Translations
-++++++++++++
-
-Bug reporting
-+++++++++++++
-
-Source code repository
-++++++++++++++++++++++
-
-Merge proposals
-+++++++++++++++
-
-Coding issues and coding conventions
-++++++++++++++++++++++++++++++++++++
-
-Javascript coding
-~~~~~~~~~~~~~~~~~
-
-These are a number of guidelines for javascript code. More than coding
-conventions, these are warnings against potentially harmful or sub-par
-constructs.
-
-Ideally, you should be able to configure your editor or IDE to warn you against
-these kinds of issues.
-
-Use ``var`` for *all* declarations
-**********************************
-
-In javascript (as opposed to Python), assigning to a variable which does not
-already exist and is not explicitly declared (via ``var``) will implicitly
-create a global variable. This is bad for a number of reasons:
-
-* It leaks information outside function scopes
-* It keeps memory of previous run, with potentially buggy behaviors
-* It may conflict with other functions with the same issue
-* It makes code harder to statically check (via e.g. IDE inspectors)
-
-.. note::
-    It is perfectly possible to use ``var`` in ``for`` loops:
-
-    .. code-block:: javascript
-
-        for (var i = 0; i < some_array.length; ++i) {
-            // code here
-        }
-
-    this is not an issue
-
-All local *and global* variables should be declared via ``var``.
-
-.. note:: generally speaking, you should not need globals in OpenERP Web: you
-          can just declare a variable local to your top-level function. This
-          way, if your widget/addon is instantiated several times on the same
-          page (because it's used in embedded mode) each instance will have its
-          own internal but global-to-its-objects data.
-
-Do not leave trailing commas in object literals
-***********************************************
-
-While it is legal to leave trailing commas in Python dictionaries, e.g.
-
-.. code-block:: python
-
-    foo = {
-        'a': 1,
-        'b': 2,
-    }
-
-and it's valid in ECMAScript 5 and most browsers support it in Javascript, you
-should *never* use trailing commas in Javascript object literals:
-
-* Internet Explorer does *not* support trailing commas (at least until and
-  including Internet Explorer 8), and trailing comma will cause hard-to-debug
-  errors in it
-
-* JSON does not accept trailing comma (it is a syntax error), and using them
-  in object literals puts you at risks of using them in literal JSON strings
-  as well (though there are few reasons to write JSON by hand)
-
-*Never* use ``for … in`` to iterate on arrays
-*********************************************
-
-:ref:`Iterating over an object with for…in is a bit tricky already
-<for-in-iteration>`, it is far more complex than in Python (where it Just
-Works™) due to the interaction of various Javascript features, but to iterate
-on arrays it becomes downright deadly and errorneous: ``for…in`` really
-iterates over an *object*'s *properties*.
-
-With an array, this has the following consequences:
-
-* It does not necessarily iterate in numerical order, nor does it iterate in
-  any kind of set order. The order is implementation-dependent and may vary
-  from one run to the next depending on a number of reasons and implementation
-  details.
-* If properties are added to an array, to ``Array.prototype`` or to
-  ``Object.prototype`` (the latter two should not happen in well-behaved
-  javascript code, but you never know...) those properties *will* be iterated
-  over by ``for…in``. While ``Object.hasOwnProperty`` will guard against
-  iterating prototype properties, they will not guard against properties set
-  on the array instance itself (as memoizers for instance).
-
-  Note that this includes setting negative keys on arrays.
-
-For this reason, ``for…in`` should **never** be used on array objects. Instead,
-you should use either a normal ``for`` or (even better, unless you have
-profiled the code and found a hotspot) one of Underscore's array iteration
-methods (`_.each`_, `_.map`_, `_.filter`_, etc...).
-
-Underscore is guaranteed to be bundled and available in OpenERP Web scopes.
-
-.. _for-in-iteration:
-
-Use ``hasOwnProperty`` when iterating on an object with ``for … in``
-********************************************************************
-
-``for…in`` is Javascript's built-in facility for iterating over and object's
-properties.
-
-`It is also fairly tricky to use`_: it iterates over *all* non-builtin
-properties of your objects [#]_, which includes methods of an object's class.
-
-As a result, when iterating over an object with ``for…in`` the first line of
-the body *should* generally be a call to `Object.hasOwnProperty`_. This call
-will check whether the property was set directly on the object or comes from
-the object's class:
-
-.. code-block:: javascript
-
-    for(var key in ob) {
-        if (!ob.hasOwnProperty(key)) {
-            // comes from ob's class
-            continue;
-        }
-        // do stuff with key
-    }
-
-Since properties can be added directly to e.g. ``Object.prototype`` (even
-though it's usually considered bad style), you should not assume you ever know
-which properties ``for…in`` is going to iterate over.
-
-An alternative is to use Underscore's iteration methods, which generally work
-over objects as well as arrays:
-
-Instead of
-
-.. code-block:: javascript
-
-    for (var key in ob) {
-        if (!ob.hasOwnProperty(key)) { continue; }
-        var value = ob[key];
-        // Do stuff with key and value
-    }
-
-you could write:
-
-.. code-block:: javascript
-
-    _.each(ob, function (value, key) {
-        // do stuff with key and value
-    });
-
-and not worry about the details of the iteration: underscore should do the
-right thing for you on its own [#]_.
-
-Writing documentation
-+++++++++++++++++++++
-
-The OpenERP Web project documentation uses Sphinx_ for the literate
-documentation (this document for instance), the development guides
-(for Python and Javascript alike) and the Python API documentation
-(via autodoc_).
-
-For the Javascript API, documentation should be written using the
-`JsDoc Toolkit`_.
-
-Guides and main documentation
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The meat and most important part of all documentation. Should be
-written in plain English, using reStructuredText_ and taking advantage
-of `Sphinx's extensions`_, especially `cross-references`_.
-
-Python API Documentation
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-All public objects in Python code should have a docstring written in
-RST, using Sphinx's `Python domain`_ [#]_:
-
-* Functions and methods documentation should be in their own
-  docstring, using Sphinx's `info fields`_
-
-  For parameters types, built-in and stdlib types should be using the
-  combined syntax:
-
-  .. code-block:: restructuredtext
-
-      :param dict foo: what the purpose of foo is
-
-  unless a more extensive explanation needs to be given (e.g. the
-  specification that the input should be a list of 3-tuple needs to
-  use ``:type:`` even though all types involved are built-ins). Any
-  other type should be specified in full using the ``:type:`` field
-
-  .. code-block:: restructuredtext
-
-      :param foo: what the purpose of foo is
-      :type foo: some.addon.Class
-
-  Mentions of other methods (including within the same class), modules
-  or types in descriptions (of anything, including parameters) should
-  be cross-referenced.
-
-* Classes should likewise be documented using their own docstring, and
-  should include the documentation of their construction (``__init__``
-  and ``__new__``), using the `info fields`_  as well.
-
-* Attributes (class and instance) should be documented in their
-  class's docstring via the ``.. attribute::`` directive, following
-  the class's own documentation.
-
-* The relation between modules and module-level attributes is similar:
-  modules should be documented in their own docstring, public module
-  attributes should be documented in the module's docstring using the
-  ``.. data::`` directive.
-
-Javascript API documentation
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Javascript API documentation uses JsDoc_, a javascript documentation
-toolkit with a syntax similar to (and inspired by) JavaDoc's.
-
-Due to limitations of JsDoc, the coding patterns in OpenERP Web and
-the Sphinx integration, there are a few peculiarities to be aware of
-when writing javascript API documentation:
-
-* Namespaces and classes *must* be explicitly marked up even if they
-  are not documented, or JsDoc will not understand what they are and
-  will not generate documentation for their content.
-
-  As a result, the bare minimum for a namespace is:
-
-  .. code-block:: javascript
-
-      /** @namespace */
-      foo.bar.baz = {};
-
-  while for a class it is:
-
-  .. code-block:: javascript
-
-      /** @class */
-      foo.bar.baz.Qux = [...]
-
-* Because the OpenERP Web project uses `John Resig's Class
-  implementation`_ instead of direct prototypal inheritance [#]_,
-  JsDoc fails to infer class scopes (and constructors or super
-  classes, for that matter) and has to be told explicitly.
-
-  See :ref:`js-class-doc` for the complete rundown.
-
-* Much like the JavaDoc, JsDoc does not include a full markup
-  language. Instead, comments are simply marked up in HTML.
-
-  This has a number of inconvenients:
-
-  * Complex documentation comments become nigh-unreadable to read in
-    text editors (as opposed to IDEs, which may handle rendering
-    documentation comments on the fly)
-
-  * Though cross-references are supported by JsDoc (via ``@link`` and
-    ``@see``), they only work within the JsDoc
-
-  * More general impossibility to integrate correctly with Sphinx, and
-    e.g. reference JavaScript objects from a tutorial, or have all the
-    documentation live at the same place.
-
-  As a result, JsDoc comments should be marked up using RST, not
-  HTML. They may use Sphinx's cross-references as well.
-
-.. _js-class-doc:
-
-Documenting a Class
-*******************
-
-The first task when documenting a class using JsDoc is to *mark* that
-class, so JsDoc knows it can be used to instantiate objects (and, more
-importantly as far as it's concerned, should be documented with
-methods and attributes and stuff).
-
-This is generally done through the ``@class`` tag, but this tag has a
-significant limitation: it "believes" the constructor and the class
-are one and the same [#]_. This will work for constructor-less
-classes, but because OpenERP Web uses Resig's class the constructor is
-not the class itself but its ``init()`` method.
-
-Because this pattern is common in modern javascript code bases, JsDoc
-supports it: it is possible to mark an arbitrary instance method as
-the *class specification* by using the ``@constructs`` tag.
-
-.. warning:: ``@constructs`` is a class specification in and of
-    itself, it *completely replaces* the class documentation.
-
-    Using both a class documentation (even without ``@class`` itself)
-    and a constructor documentation is an *error* in JsDoc and will
-    result in incorrect behavior and broken documentation.
-
-The second issue is that Resig's class uses an object literal to
-specify instance methods, and because JsDoc does not know anything
-about Resig's class, it does not know about the role of the object
-literal.
-
-As with constructors, though, JsDoc provides a pluggable way to tell
-it about methods: the ``@lends`` tag. It specifies that the object
-literal "lends" its properties to the class being built.
-
-``@lends`` must be specified right before the opening brace of the
-object literal (between the opening paren of the ``#extend`` call and
-the brace), and takes the full qualified name of the class being
-created as a parameter, followed by the character ``#`` or by
-``.prototype``. This latter part tells JsDoc these are instance
-methods, not class (static) methods..
-
-Finally, specifying a class's superclass is done through the
-``@extends`` tag, which takes a fully qualified class name as a
-parameter.
-
-Here are a class without a constructor, and a class with one, so that
-everything is clear (these are straight from the OpenERP Web source,
-with the descriptions and irrelevant atttributes stripped):
-
-.. code-block:: javascript
-
-    /**
-     * <Insert description here, not below>
-     *
-     * @class
-     * @extends openerp.base.search.Field
-     */
-    openerp.base.search.CharField = openerp.base.search.Field.extend(
-        /** @lends openerp.base.search.CharField# */ {
-            // methods here
-    });
-
-.. code-block:: javascript
-
-    openerp.base.search.Widget = openerp.base.Controller.extend(
-        /** @lends openerp.base.search.Widget# */{
-        /**
-         * <Insert description here, not below>
-         *
-         * @constructs
-         * @extends openerp.base.Controller
-         *
-         * @param view the ancestor view of this widget
-         */
-        init: function (view) {
-            // construction of the instance
-        },
-        // bunch of other methods
-    });
-
-OpenERP Web over time
----------------------
-
-Release process
-+++++++++++++++
-
-OpenSUSE packaging: http://blog.lowkster.com/2011/04/packaging-python-packages-in-opensuse.html
-
-Roadmap
-+++++++
-
-Release notes
-+++++++++++++
-
-.. [#] More precisely, it iterates over all *enumerable* properties. It just
-       happens that built-in properties (such as ``String.indexOf`` or
-       ``Object.toString``) are set to non-enumerable.
-
-       The enumerability of a property can be checked using
-       `Object.propertyIsEnumeable`_.
-
-       Before ECMAScript 5, it was not possible for user-defined properties
-       to be non-enumerable in a portable manner. ECMAScript 5 introduced
-       `Object.defineProperty`_ which lets user code create non-enumerable
-       properties (and more, read-only properties for instance, or implicit
-       getters and setters). However, support for these is not fully complete
-       at this point, and they are not being used in OpenERP Web code anyway.
-
-.. [#] While using underscore is generally the preferred method (simpler,
-       more reliable and easier to write than a *correct* ``for…in``
-       iteration), it is also probably slower (due to the overhead of
-       calling a bunch of functions).
-
-       As a result, if you profile some code and find out that an underscore
-       method adds unacceptable overhead in a tight loop, you may want to
-       replace it with a ``for…in`` (or a regular ``for`` statement for
-       arrays).
-
-.. [#] Because Python is the default domain, the ``py:`` markup prefix
-       is optional and should be left out.
-
-.. [#] Resig's Class still uses prototypes under the hood, it doesn't
-       reimplement its own object system although it does add several
-       helpers such as the ``_super()`` instance method.
-
-.. [#] Which is the case in normal Javascript semantics. Likewise, the
-       ``.prototype`` / ``#`` pattern we will see later on is due to
-       JsDoc defaulting to the only behavior it can rely on: "normal"
-       Javascript prototype-based type creation.
-
-.. _reStructuredText:
-    http://docutils.sourceforge.net/rst.html
-.. _Sphinx:
-    http://sphinx.pocoo.org/index.html
-.. _Sphinx's extensions:
-    http://sphinx.pocoo.org/markup/index.html
-.. _Python domain:
-    http://sphinx.pocoo.org/domains.html#the-python-domain
-.. _info fields:
-    http://sphinx.pocoo.org/domains.html#info-field-lists
-.. _autodoc:
-    http://sphinx.pocoo.org/ext/autodoc.html
-        ?highlight=autodoc#sphinx.ext.autodoc
-.. _cross-references:
-    http://sphinx.pocoo.org/markup/inline.html#xref-syntax
-.. _JsDoc:
-.. _JsDoc Toolkit:
-    http://code.google.com/p/jsdoc-toolkit/
-.. _John Resig's Class implementation:
-    http://ejohn.org/blog/simple-javascript-inheritance/
-.. _\_.each:
-    http://documentcloud.github.com/underscore/#each
-.. _\_.map:
-    http://documentcloud.github.com/underscore/#map
-.. _\_.filter:
-    http://documentcloud.github.com/underscore/#select
-.. _It is also fairly tricky to use:
-    https://developer.mozilla.org/en/JavaScript/Reference/Statements/for...in#Description
-.. _Object.propertyIsEnumeable:
-    https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/propertyIsEnumerable
-.. _Object.defineProperty:
-    https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/defineProperty
-.. _Object.hasOwnProperty:
-    https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/hasOwnProperty
diff --git a/doc/source/widgets.rst b/doc/source/widgets.rst
deleted file mode 100644 (file)
index 20e51db..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-OpenERP Web as a widgets provider
-=================================
-
-* Using a readonly view as a widget
-
-  * Site example
-  * iGoogle example
-  * social site example e.g. Facebook app?
-
-* Write-access widgets (e.g. contact form)
-* Multiple widgets on the same page
-* JSON-RPC2 API description for third-parties?
diff --git a/doc/widgets.rst b/doc/widgets.rst
new file mode 100644 (file)
index 0000000..20e51db
--- /dev/null
@@ -0,0 +1,12 @@
+OpenERP Web as a widgets provider
+=================================
+
+* Using a readonly view as a widget
+
+  * Site example
+  * iGoogle example
+  * social site example e.g. Facebook app?
+
+* Write-access widgets (e.g. contact form)
+* Multiple widgets on the same page
+* JSON-RPC2 API description for third-parties?