# Documentation Index

To be generated

# What is renderJS?

renderJS is a JavaScript library which helps modularizing your HTML5 code and your JavaScript applications. It uses the HTML5 standard as an easy way to specify self-contained components which consist of HTML5 code, CSS code and Javascript code. It helps reusing components in different applications just as easily as linking an HTML5 page to another. It also helps combining multiple reusable component within the same single page application.

The main focus of renderJS is graphic user interface (GUI) components such as editors, viewers, fields or widgets. renderJS can also be used to define reusable components with no GUI such as translators or format converters.

## A Simple Example

Let us suppose we want to add a text editor to an HTML5 page, here is how we proceed:

`<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Simple example</title>
<script src="jquery.js" type="text/javascript"></script>
<script src="render.js" type="text/javascript"></script>
</head>
<body>
<p>Text editor displays below:</p>
<div data-gadget-path="http://www.renderjs.org/editor/rtl/index.html"></div>
</body>
</html>`

renderJS takes care if managing all dependencies and rendering.

## How does it work?

renderJS is separated into 3 parts: renderJS library, renderJS interfaces and renderJS core gadgets.

renderJS library provides a simple way to load inside an existing HTML5 page third-party components which follow the renderJS specification. It implements a recursive macro language in pure HTML5. This macro language provides a way to embed and combine recursively components from different sources.

renderJS core interfaces (http://www.renderjs.org/interface/) provide the documentation to common interfaces shared by all renderJS components. It defines in particular the renderable interface for all components which can be rendered in a page such as editors, viewers, fields or widgets.

renderJS core gadgets (http://www.renderjs.org/gadget/core/) provide a reference implementation of renderJS interfaces. It provides in particular the default implementation of renderJS router and renderJS catalog. renderJS router is used to manage interactions between user and components or between components themselves. renderJS catalog provides a way to search for components which meet a given interface.

## Getting started

This walkthrough is designed to get you started using a basic renderJS instance.

Download renderJS library, renderJS core as well as the dependencies required to start using core components.

Script | Description | Source
--- | --- | ---
renderJS | The renderJS library | render.js
jquery | The JQuery library version XXX | jquery.js

Add the renderJS script to your HTML page:

`<script src="jquery.js" type="text/javascript"></script>
<script src="render.js" type="text/javascript"></script>`

## renderJS fundamentals

renderJS can be used either by adding HTML5 tags to your page or by invoking Javascript methods.

The renderJS script provides 10 HTML5 tags which can be added to any HTML5 page.

Method | Sample Call | Description
--- | --- | ---
data-gadget-path | `<div data-gadget-path="hello-world.html"></div>` | Embeds the HTML5 code of a gadget in a page, loads CSS and Javascript depencies and call render() method on the gadget if it is defined.
data-gadget-slot | `<div data-gadget-slot="main"> <p>This content is</p> <p>Going to be replaced/p> </div>` | Defines the porting of the DOM tree in the HTML5 code of a gadget which is going to be replaced after render() method is called
data-gadget-fill | `<div data-gadget-path="hello-layout.html"> <div data-gadget-fill="main"> <div data-gadget-path="hello-world.html"/> </div> </div>` | Fills given slot in DOM parent gadget with HTML5 content defined in DOM child tree. Filling is applied recursively.
data-gadget-scope | `<div data-gadget-path="hello-layout.html" data-gadget-scope="hello"></div>` | Associates a gadget to a namespace which can later be used to retrieve a gadget by URL or programmatically
data-gadget-state | `<div data-gadget-path="html-viewer.html" data-gadget-state="{'text_content':'<p>Some content</p>'"></div>` | Defines the state of the gadget as serialized JSON string with properties. This state can be used to implement persistency of a gadget and ability to move it from one page to another.
data-gadget-cache | `<div data-gadget-path="hello-layout.html" data-gadget-cache="form"></div>` | Defines the caching policy of a gadget. Caching itself is implemented by a "Cache services" gadget.
data-gadget-sandbox | `<div data-gadget-path="hello-layout.html" data-gadget-sandbox="iframe"></div>` | Defines the sandboxing type of a gadget (iframe, safejs, etc.).
data-gadget-public | `<div data-gadget-path="hello-layout.html" data-gadget-public="bang"></div>` | Declares which methods or events of a gadget are public.
data-gadget-routed | `<div data-gadget-path="hello-layout.html" data-gadget-routed="a.someMethod:bang; b.anotherEvent:bang"></div>` | Declares which methods or events of a gadget are forwarded to the router.

The renderJS Javascript API replicates and extends HTML5 tags.

Method | Parameters | Returns | Description
--- | --- | --- | ---
€(scope_selector) | `selector` | Gadget selection. | Select all gadgets matching the scope selector.
€(scope_selector).declareGadget OR $(selector).declareGadget | url, // the path of the gadget definition ex. "slide-gadget.html' [settings] // A set of key/value pairs state, // gadget state scope, // some scope for all URLs published ???? position, // useful to try to order gadgets inside an element sandbox, // defines the sandboxing type | Promise (for callback) | Declares that a given gadget with given parameters should exist as the parent of another gadget and should be attached to a given DOM position.
€(scope_selector).remove | `scope` | Promise (for callback) | Remove the set of matched gadgets
€(scope_selector).declareMethod | method name function | Chainable gagdet selector | Declares a public method of a gadget.

# Step by step tutorials

We will learn here how to create a gadget, how to use a gadget and how to make gadgets interact.

## Tutorial 1: Hello Viewer

Many people just want to use renderJS in order to display and edit content and leverage the rich library of gadgets of OfficeJS which renderJS is based.

Here how to do.

Let us add an HTML document to our web server in `/var/www/html/hello_viewer/test.html`

Let us add an SVG document to our web server in `/var/www/html/hello_viewer/test.svg`

We are going to display both documents in the page using whichever editor is available to display it.

We create the HTML file `/var/www/html/hello_viewer/test.html` with the following code.

    <html>
      <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Hello Viewer Application</title>
        <script src="jquery.js" type="text/javascript"></script>
        <script src="render.js" type="text/javascript"></script>
      </head>
      <body>
        <!-- Warning message if no javascript -->
        <noscript>Please turn on Javascript.</noscript>

        <!-- Include two universal viewers -->
        <p>Display first viewer with HTML file</p>
        <div data-gadget-path="http://officejs.org/editor/universal/index.html"
             data-gadget-sandbox="iframe"
             data-gadget-state="{'src': '/hello_viewer/test.html'}" />
        <p>Display second viewer with SVG file</p>
        <div data-gadget-path="http://officejs.org/editor/universal/index.html"
             data-gadget-sandbox="iframe"
             data-gadget-state="{'src': '/hello_viewer/test.svg'}" />
      </body>
    </html>

Here is the result:

[DRAWING]

We only use here a single gadget: the universal editor. This gadget has two instances. Each instance is able to download a file, guess its mime type and select the most appropriate viewer to display it. It removes the burden to select a viewer from the developer. We have used the tag `data-gadget-sandbox` on both gadgets in order to make sure that an iframe sandbox prevent CSS conflicts which most viewers generate because of poor namespacing.

## Tutorial 2: Hello World

Let us now create a simple gadget from scratch. This gadget displays the text "Hello World". We first create a directory in our web server.

`/var/www/html/gadget/hello_world`

Then we create the file `/var/www/html/gadget/hello_world/index.html` that will contain the gadget code.

    <html>
      <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Hello World</title>
      </head>
      <body>
        <p>Hello World</p>
      </body>
    </html>

We can display the gadget by opening the URL

`http://localhost/gadget/hello_world/index.html`

Which displays the "Hello World" test in a blank page:

[DRAWING]

We will now embed the "Hello World" the gadget in a renderJS application.

Let us create the file `/var/www/html/gadget/hello_application/index.html` which will contain the HTML5 application.

    <html>
      <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Hello World Application</title>
        <script src="jquery.js" type="text/javascript"></script>
        <script src="render.js" type="text/javascript"></script>
      </head>
      <body>
        <!-- Warning message if no javascript -->
        <noscript>Please turn on Javascript.</noscript>

        <!-- Include Hello World gadget -->
        <div data-gadget-path="../hello_world/index.html" />
      </body>
    </html>

Let us now check the result:

[DRAWING]

And the HTML5 code which was generated:

    <html>
      <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Hello World Application</title>
        <script src="jquery.js" type="text/javascript"></script>
        <script src="render.js" type="text/javascript"></script>
      </head/>
      <body/>
        <!-- Warning message if no javascript -->
        <noscript>Please turn on Javascript.</noscript>

        <!-- Include Hello World gadget -->
        <div data-gadget-path="../hello_world/index.html"
             data-gadget-scope="Hello World">
          <p>Hello World</p>
        </div>
      </body>
    </html>

This example shows the basic feature of renderJS: the ability to dynamically include in a page code defined in another page. You can consider in this example that renderJS is a kind of macro system which runs on the client side rather than on the server side. You will also take note that renderJS generated the tag "data-gadget-scope" automatically by taking the default value provided by the title of the gadget.

Let us now add some behaviour to our gadget. We create a script `/var/www/html/gadget/hello_world/hello.js` with the following code

    €(this).declareMethod("foo", function () {
         // replace body paragraph with Bang! word
         $(this).find('p').text("Bang!");
      });

We now need to attach a dependency to this script in the gadget definition. We are going also to use the `data-gadget-public` tag.

    <html>
      <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Hello World</title>
        <script src="jquery.js" type="text/javascript"></script>
        <script src="render.js" type="text/javascript"></script>
        <script src="hello.js" type="text/javascript"></script>
      </head>
      <body data-gadget-public="foo">
        <p>Hello World</p>
      </body>
    </html>

If we open our Web browser to `http://localhost/gadget/hello_world/index.html`, we can view the Hello Word gadget itself:

[DRAWING]

Now, if we type the URL `http://localhost/gadget/hello_world/index.html#foo`, we get something new:

[DRAWING]

What happens here is that the `data-gadget-public` has declared the method `foo` as a public method that can be invoked through a hashtag. This is simular to the concept of method publication in application servers such as Zope, Flash. `http://localhost/gadget/hello_application/index.html#hello/foo`. Here is the result:

[DRAWING]

The content "Hello World" was replaced by "Bang!". This example shows the concept of recursive publication of gadgets provided by renderJS. By using the `data-gadget-scope` tag, every public method of a gadget can be accessed through a simple URL.

## Tutorial 3: a slider gadget containing two forms and an interactor

We will now show a more complex example to illustrate the advanced macro capabilities of renderJS and the concept of interactor.

Let us create a slider field where the slider widget itself can contain any gadgets, such as forms, date fields, animated sprite, etc.

[DRAWING]

Let us first define the HTML5 code of the gadget in `/var/www/gadget/slider/index.html`

    <html>

      <!-- Define dependencies and supported interfaces -->
      <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Slider Gadget</title>
        <script src="jquery.js" type="text/javascript"></script>
        <script src="render.js" type="text/javascript"></script>
        <link rel="stylesheet" src="slider.css"/>
        <script src="slider.js" type="text/javascript"></script>
        <link rel="http://www.renderjs.org/rel/interface"
              src="http://www.renderjs.org/interface/renderable"/>
        <link rel="http://www.renderjs.org/rel/interface"
              src="http://www.renderjs.org/interface/field"/>
      </head>

      <!-- Sample display made by HTML designer -->
      <body>
        <noscript>Please turn on Javascript.</noscript>

        <!-- Sample display made by HTML designer -->
        <div class="slider">
          <div class="slider_element">
            <!-- The content of this div is replaced dynamically by the call to render() -->
            <div data-gadget-slot="main"> <!-- main is the default -->
              <!-- This part is destroyed and replaced by render() -->
              <form>
                <input type="text" />
              </form>
            </div>
          </div>
        </div>
      </body>

    </html>

We can now define the CSS of `slider.css`:

        .slider {
          background-color: black;
          display: inline-block;
          height: 0.5em;
          margin: 0.5em 0;
          position: relative;
          width: 20em;
        }
        .slider_element {
          background-clip: padding-box;
          background-color: #A1A1A1;
          border-radius: 0.75em 0.75em 0.75em 0.75em;
          border-width: 0;
          cursor: pointer;
          left: 50%;
          line-height: 1em;
          padding: 0.25em;
          position: absolute;
          top: -1em;
        }
        form input {
          cursor: pointer;
          max-width: 2em;
        }

The Javascript code of `slider.js` looks like this:

    XXX TO BE COMPLETED

This example introduces some new concepts of renderJS. The `data-gadget-slot` slot defines a placeholder in the gadget which can be filled with another gadget at render time. It is now filled with a single form with a single field. We will show later how to dynamically replace this single form with two forms.

Another important concept introduced in this example is the notion of interface. The relation type `http://www.renderjs.org/rel/interface` defines an interface relation, following the concepts of link relation used increasingly in modern REST applications based on the HATEOAS approach. We define here that our gadget follows the renderable interface and the field interface.

Interfaces are self-documented online:

    # http://www.renderjs.org/interface/renderable

    A gadget is meant to be rendered as part of the DOM tree of an HTML5 page.

    €(selector).render() [returns Promise]

    Renders the gadget in the given DOM context.

    # http://www.renderjs.org/interface/field

    A renderJS gadget which provides a way for user to display information and
    collect information.

    €(selector).getValue() [returns Promise]

    Returns the value of given gadget.

    €(selector).setValue(value) [returns Promise]
    * value -- value to set

    Sets the value of a given gadget.

Let us now create a small application which embeds two forms inside a slider gadget and created an interaction between forms and the slider.

We should first create a form gadget in `/var/www/gadget/slider/form.html`

    <html>
      <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Form Gadget</title>
        <script src="jquery.js" type="text/javascript"></script>
        <script src="render.js" type="text/javascript"></script>
        <script src="form.js" type="text/javascript"></script>
        <link rel="http://www.renderjs.org/rel/interface"
              src="http://www.renderjs.org/interface/renderable"/>
        <link rel="http://www.renderjs.org/rel/interface"
              src="http://www.renderjs.org/interface/field"/>
      </head>
      <body data-gadget-public="setValue">
        <form>
          <input type="text" />
        </form>
      </body>
    </html>

and define the `form.js` script which implements the field API for the form itself.

    €(this)
      .declareMethod("getValue", function () {
           // Deferred object is returned automatically by renderJS
           return $(this).find('input').val();
        })
      .declareMethod("setValue", function (value) {
           // Deferred object is returned automatically by renderJS
           $(this).find('input').val(value);
        });

It is time now to assemble all parts into an application: a slide gadget and two instances of the form in `/var/www/gadget/slider/example.html`

    <html>

      <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Slider Example Application</title>
        <script src="jquery.js" type="text/javascript"></script>
        <script src="render.js" type="text/javascript"></script>
      </head>

      <body>
        <!-- Warning message if no javascript -->
        <noscript>Please turn on Javascript.</noscript>

        <!-- Page structure -->
        <div data-gadget-path="slider.html">
          <div data-gadget-fill="main">
            <!-- First Form -->
            <div data-gadget-path="form.html"
                 data-gadget-scope="first"/>
            <!-- Second Form -->
            <div data-gadget-path="form.html"
                 data-gadget-scope="second"/>
          </div>
        </div>
      </body>

    </html>

This example shows a typical example of the `data-gadget-scope` tag in order to distinguish to instances of the same gadget. It also shows how the `data-gadget-fill` tag operates by filling the `data-gadget-slot` named "main" in the Slider gadget.

Let us display the result by opening the URL `http://localhost/gadget/slider/sample.html`:

[DISPLAY]

Let us illustrate how the `data-gadget-public` tag works in combination with `data-gadget-scope`.

And if we call `http://localhost/gadget/slider/sample.html#first/setValue?value=3` [DISPLAY]

The second form changes with value set to 3.

If we call `http://localhost/gadget/slider/sample.html#second/setValue?value=7` [DISPLAY]

The second form changes with value set to 7.

We will now make the slider and forms interact so that moving the slider updates both forms and changing any form moves the slider. In order to achieve this, we need to add a interactor gadget to the application. The code of the application will look like this.

    <html>

      <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Slider Example Application</title>
        <script src="jquery.js" type="text/javascript"></script>
        <script src="render.js" type="text/javascript"></script>
      </head>

      <body>
        <!-- Warning message if no javascript -->
        <noscript>Please turn on Javascript.</noscript>

        <!-- Page structure -->
        <div data-gadget-path="slider.html"
             data-gadget-scope="slider"
             data-gadget-routed="setValue:interactor/notifyUpdatedValue?value={$value}" >
          <div data-gadget-fill="main">
            <!-- First Form -->
            <div data-gadget-path="form.html"
                 data-gadget-scope="first"
                 data-gadget-routed="setValue:interactor/notifyUpdatedValue?value={$value}" />
            <!-- Second Form -->
            <div data-gadget-path="form.html"
                 data-gadget-scope="second"
                 data-gadget-routed="setValue:interactor/notifyUpdatedValue?value={$value}" />
          </div>
        </div>
        <div data-gadget-path="interactor.html"
             data-gadget-scope="interactor"
             data-gadget-public="notifyUpdatedValue" />
      </body>

    </html>

What we just did here is to use the tag `data-gadget-public` which simulates the call to a URL each time a method of a gadget is invokes. For example, if `setValue` is invoked on the first single field form, then we simulate a call to the URL `interactor/notifyUpdatedValue` and pass to it the parameters of setValue which ere interested in.

We can now define the interactor HTML5 code for `interactor.html`:

    <html/>
      <head/>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Slide Interactor</title>
        <script src="jquery.js" type="text/javascript"></script>
        <script src="render.js" type="text/javascript"></script>
        <script src="interactor.js" type="text/javascript"></script>
      </head/>
      <body/>
        <!-- Warning message if no javascript --/>
        <noscript>Please turn on Javascript.</noscript>
      </body/>
    </html/>

and its javascript code:

    €(this).declareMethod("notifyUpdatedValue", function (value) {
       var slider = €("slider"),
         first = slider.find("first"),
         second = slider.find("second"),
       slider.getValue().done(function (current_value) {
         if (current_value !== value) {
           slider.setValue(value);
         }
       });
       first.getValue().done(function (current_value) {
         if (current_value !== value) {
           first.setValue(value);
         }
       });
       second.getValue().done(function (current_value) {
         if (current_value !== value) {
           second.setValue(value);
         }
       });
    });

Now each time the user moves the slider, the forms are updated and each time forms are updated, the slider is moved.

## Tutorial 4: using Javascript only

TBD, mainly by calling declareGadget, declarePublic and declareRouted

# HTML5 Tags

## data-gadget-path

TBD

## data-gadget-scope

TBD

## data-gadget-state

TBD

## data-gadget-cache

TBD

## data-gadget-sandbox

TBD

## data-gadget-slot

TBD

## data-gadget-fill

TBD

## data-gadget-public

Makes a given method of the gadget accessible through the router.

The simple form does not require any parameter:

    <div data-gadget-path="a.html"
         data-gadget-public="someMethodOfA"
         data-gadget-scope="a"/>

can be invoked by a GET as:

    #a/someMethodOfA

A more complex form adds name translation:

    <div data-gadget-path="a.html"
         data-gadget-public="someOtherName:someMethodOfA"
         data-gadget-scope="a"/>

can be invoked by a GET as:

    #a/someOtherName

It is also possible to publish a method as a POST:

    <div data-gadget-path="a.html"
         data-gadget-public="POST:someOtherName:someMethodOfA"
         data-gadget-scope="a"/>

can be invoked by a POST on the page with _route parameter set in the HTTP request to.

    _route: a/someOtherName

## data-gadget-routed

Routes a given method or event to the router.

In the first example, the interactor gadget defines routes on other gadgets. It is the preferred approach in terms of encapsulation but may cause security issues in the future.

    <html>

      <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Sample Application with 2 gadgets and interactor</title>
        <script src="jquery.js" type="text/javascript"></script>
        <script src="render.js" type="text/javascript"></script>
      </head>

      <body>
        <!-- Warning message if no javascript -->
        <noscript>Please turn on Javascript.</noscript>

        <!-- Page structure -->
        <div data-gadget-path="a.html" data-gadget-scope="a"/>
        <div data-gadget-path="b.html" data-gadget-scope="b"/>
        <!-- tell the router that calling browser://interact/bang should call bang -->
        <!-- wrap on a.someMehod a call to browser://interact/bang -->
        <!-- wrap on b.anotherEvent a call to browser://interact/bang -->
        <div data-gadget-path="interactor.html" data-gadget-scope="interactor"
             data-gadget-public="bang:bang; "
             data-gadget-routed="a.someMethod:bang; b.anotherEvent:bang">
        </div>
      </body>

    </html>

In the second example, each gadget defines its own routes.

    <html>

      <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Sample Application with 2 gadgets and interactor</title>
        <script src="jquery.js" type="text/javascript"></script>
        <script src="render.js" type="text/javascript"></script>
      </head>

      <body>
        <!-- Warning message if no javascript -->
        <noscript>Please turn on Javascript.</noscript>

        <!-- Page structure -->
        <div data-gadget-path="a.html" data-gadget-scope="a"
             data-gadget-routed="someMethod:interactor/bang"/>
        <div data-gadget-path="b.html" data-gadget-scope="b"
             data-gadget-routed="someMethod:interactor/bang"/>
        <!-- tell the router that calling browser://interact/bang should call bang -->
        <!-- wrap on a.someMehod a call to browser://interact/bang -->
        <!-- wrap on b.anotherEvent a call to browser://interact/bang -->
        <div data-gadget-path="interactor.html" data-gadget-scope="interactor"
             data-gadget-public="bang:bang;">
        </div>
      </body>

    </html>

# API

## Core

renderJS core consists of 3 global methods.

    €(scope_selector).declareGadget OR $(selector).declareGadget

    * url -- the path of the gadget definition ex. "slide-gadget.html'
    * [settings] // A set of key/value pairs
      * state -- the state of the gadget (JSON)
      * scope -- it defines the URL path where the gadget is publishable and the way to retrieve for its parent
      * position -- useful to try to order gadgets inside an element
      * sandbox -- the type of sandboxing (iframe, safefs)

    Declares the existence of a gadget by creating or updating it if necessary.

    €(scope_selector)

    Select all gadgets matching the scope selector.

    €(scope_selector).remove

    Remove the set of matched gadgets

# Interfaces

renderJS provides a standard way to define interfaces using text files.

    #http://standard/path/to/interface

    Some description of the interface in plain English in one
    or more lines of text.

    methodName
    * parameter1 -- description [OPTIONAL]
    * parameter2 -- description [OPTIONAL]

    Description of the method in in one or more lines of text.

    anotherMethodName
    * parameter1 -- description [OPTIONAL]
    * parameter2 -- description [OPTIONAL]

    Description of the method in in one or more lines of text.

All interfaces should returns promise because everything in renderJS is asynchronous.

## Gadget

    # http://www.renderjs.org/interface/gadget

    The Gadget interface defines gadget introspection.
    It should be implemented by every gadget.

    getInterfaceList()

    Return the list of URL of interfaces of a gadget

    getPath()

    Returns the path of the HTML5 code of a gadget

    getTitle()

    Returns the title of a gadget

    getRequiredCSSList()

    Returns a list of CSS required by the gadget

    getRequiredJSList()

    Returns a list of JS required by the gadget

## Catalog

The Catalog interface defines how to search gadgets badget on gadget metadata.

    # http://www.renderjs.org/interface/catalog

    The Catalog interface defines a single method to search gadgets based
    on their metadata. Its API mimics the API of JIO.

    allDocs(filter)
    * filter -- JSON dict which defines a predicate on metadata

    allDocs returns a list of dictionnaries of the form:
    {
      "path" :      "http://some/path/to/the/gadget/source",
      "title" :     "Gadget Title",
      "link" :      "http://some/link/to/the/gadget",
      "interface" : "http://officejs.org/interface/field",
    }

    Additional parameters can be added to the list in order to
    extend the Catalog. For example, mime types and a priority
    could be added:

    {
      "path" :      "http://some/path/to/the/gadget/source",
      "title" :     "Gadget Title",
      "link" :      "http://some/link/to/the/gadget",
      "interface" : "http://officejs.org/interface/field",
      "mime_type" : "text/svg",
      "priority" :  3,
    }

## Router

    # http://www.renderjs.org/interface/router

    The Router interface describes how to make gadgets
    communicate and interact eachother. It is based on the
    idea of link and the possibility for two gadgets located
    in different sandboxes or on different runtime to communicate.

    makeLink(gadget, method, link_type)
    * gadget -- a gadget or a handle to a gadget
    * method -- the method of the gadget or the method ID [OPTIONAL]
    * link_type -- the type of link (GET, POST, PUT).a list of mime types which the gadget supports
    at least on certain platforms. This method can be used
    to build a platform independent catalog of viewer gadgets.

## Editor

    # http://www.renderjs.org/interface/editor

    The Editor interface provides a way to interact
    with content in real time through menu actions.
    It enables different editors with different menus
    to share more commonality in their appearance.

    setEditableState
    * editable -- true or false

    Turns on or off the ability to edit content.

    setMenuVisibility
    * visibility -- true or false

    Shows of hides the default menu of the editor.

    getMenuItemTree

    Returns the tree of menu actions supported by the
    editor. Each menu action is described as a JSON dict
    with the following format.

    {
      "id":     "open",
      "title":  "Open...",
      "dialog": true,
    }

    triggerAction
    * action

    Simulates an action on a menu item.

    notifyChange
    * location -- the location of the content
    * value -- the value of the content which is changed

    Each time some content is changes (title, paragraph, etc.)
    notifyChange is invoked with two parameters, once which describes
    the location of the content which was changed and the other the
    new value if any. If undefined value is passed, it is considered
    as a way to specify that location was deleted.

    setContent
    * location -- the location of the content
    * value -- the value of the content which is changed

    Updates content (by merging if needed).

## Text Editor

    # http://www.renderjs.org/interface/text-editor

    The Text Editor interface provides common text
    processing features.

    searchAndReplace
    * search_pattern --
    * replace_pattern --

    Replaces one string by another.

    getParagraphItemList
    * paragraph_type -- can be chapter or an HTML tag

    Returns a list of JSON dicts which describe each chapter
    in a text editor. This is useful for example to display
    a list of chapters outside the text editor.

    goToPosition
    * position -- the position to set the editor to. Position is an
                  arbitrary value defined by getParagraphItemList

    Moves text editor to a given position.

## Table Editor

    # http://www.renderjs.org/interface/image-editor

    The Table Editor interface provides a simple way to
    access or change lines, columns and cells in a table.

# Application Standard Services

Any application needs at least a gadget catalog and a router. By default, renderJS creates a standard router and a standard catalog. It is however possible to overload default services with your own as shown in the example below.

    <html>
      <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Gadget Container Slider </title>
        <script src="jquery.js" type="text/javascript"></script>
        <script src="render.js" type="text/javascript"></script>
      </head>

      <body>
        <!-- Warning message if no javascript -->
        <noscript>Please turn on Javascript.</noscript>

        <!-- Overload dummy router and catalog with dummy ones -->
        <div data-gadget="dummy-router.html" data-gadget-scope="router"/>
        <div data-gadget="dummy-catalog.html" data-gadget-scope="catalog"/>
      </body>

    </html>

By using appropriate scope, the standard catalog and router are overloaded with dummy implementations which... do nothing.

## The Standard Router

The router is where everything happens to convert method calls into link invocations emissions and link invocations into method calls, both locally and remotely. It is key to communication between sandboxes in the same page, between URLs and gadgets and between gadgets on different hosts.

The makeHandle method converts a URL of a link to a handle. A handle is a proxy object capable of converting any method call to an AJAX POST. For performance reasons, gadgets in the same sandbox can access eachother directly, without conversion to link of method calls. Yet, the proxying is kept to enforce clean development.

    // Get the router which is just a gadget
    var router = €("router"),
      // Get a handle to a remote gadget
      handle = router.makeHandle('http://some.server/some/scope/some/gadget');
    // Call a method on the remote gadget through the transparent invocation of a link
    //   this is just a form of syntactic sugar
    handle.someMethod(some_parameter);
    // This will call AJAX POST http://some.server/some/scope/some/gadget/someMethod?some_parameter=some_parameter

The makeLink method converts a gadget to a link by concatenating its scope and parent scope.

    // Compute the link of a gadget based on its scope and the scope of its parents
    link = router.makeLink(gadget);

The makeLink method can receive option method parameters to create links to published methods more easily.

    // Compute the link of a gadget based on its scope and the scope of its parents and pass parameters in link
    link = router.makeLink(gadget, "POST", "someMethod", {"parameter_name": value});

The router can be used to connect to remote gadgets. In the not so distant future, two routers on different browsers can be interconected through WebRTC. Until this happens, two routers can be interconnected by COMET or Websocket and some intermediate server.

In this example, Gadget A in a remote host and Gadget B is on local host.

First we publish some method of Gadget A by running the following code on remote host:

    // This code is executed on remote host (A)
    var router_a = €("router"),
      gadget_a = €("a");
    // Publish someMethod of gadget_a
    router_a.declarePublic(gadget_a, "someMethod?parameter={value}", gadget_a.someMethod);
    // Publish declareRouted method of router_a so that it can be remotely invoked
    router_a.declarePublic(router_a, "declareRouted", router_a.declareRouted);

Next we invoke on local host the following code:

    // This code is executed on local host (B)
    var router_b = €("router"),
      gadget_b = €("b"),
      link_b = router.makeLink(gadget_b, 'callB'),
      router_a = router.makeHandle('http://remote.com/router'),
      link_a = "http://remote.com/a";
    router_b.declarePublic(gadget_b, "callB", gadget_b.callB);
    router_a.declareRouted(link_a, someAMethod, link_b);

What will happen after this is that each time someAMethod is called on Gadget A, Gadget A will invoke link_b which itself will call method callB on Gadget B. In order to achieve this we need to publish declareRouted method of router on A side sode that it can be invoked from B.

## The Standard Catalog

RenderJS catalog uses the allDocs API of JIO, including queries.

    var catalog = €("catalog"),
      i = 0,
      link,
      catalog_item;
    // Use JIO syntax
    catalog.allDocs(filter={}).done(function (catalog_item_list) {
      for (i = 0; i < catalog_item_list.length; i += 1) {
        catalog_item = catalog_item_list.length[i];
        link = catalog_item['link'];
        makeHandle(link).done(function (handle) {
          // does a remote call to a living gadget
          handle.getInterfaceList().done(function (interface_list) {
            ...
          });
        });
      }
    }

# Open Questions

- Who is allowed to publish a method ? (parent is allowed to publish method of child ?) -> parent for child OR security policy defined
- Is it better to have promise based (setGadget) or imperative based (addGadget) -> declarative
- are makeLink and makeHandle part of router API, global methods or gadget methods ? -> router API
- Should it be router.makeLink(gadget) or gadget.makeLink() or makeLink(gadget, someMethod) etc. -> router API
- Should fireLink be method of router or each gadget -> router

# Problems Solved by renderJS

It is possible for example to embed in an HTML5 an SVG editor gadget which itself embeds a menu gadget, both of which are defined by different sources.

# Authors

- Ivan Tyagov
- Jean-Paul Smets
- Sven Franck
- Romain Courteaud

# Copyright and license

renderJS is an open-source library and is licensed under the LGPL license. More information on LGPL can be found here

Last update: Tuesday, June 12th, 2013