Skip to content

Commit

Permalink
Improve app and registry documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
nickstenning committed Apr 15, 2015
1 parent 615c333 commit e90cc06
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 51 deletions.
47 changes: 37 additions & 10 deletions doc/api/app.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ annotator package
passed to the plugin module at initialisation.

If the returned plugin has a `configure` function, this will be called with
the application registry as its first parameter.
the application registry as a parameter.

:param Object module:
:param Object options:
:returns: The Annotator instance, to allow chained method calls.
:returns: Itself.
:rtype: App


.. function:: annotator.App.prototype.start()
Expand All @@ -31,26 +32,52 @@ annotator package

Runs the 'start' plugin hook.

:returns Promise: Resolved when all plugin 'start' hooks have completed.
:returns: A promise, resolved when all plugin 'start' hooks have completed.
:rtype: Promise


.. function:: annotator.App.prototype.runHook(name[, args])
.. function:: annotator.App.prototype.destroy()

Run the named hook with the provided arguments
Destroy the App. Unbinds all event handlers and runs the 'destroy' plugin
hook.

:returns Promise: Resolved when all over the hook handlers are complete.
:returns: A promise, resolved when destroyed.
:rtype: Promise


.. function:: annotator.App.prototype.destroy()
.. function:: annotator.App.prototype.runHook(name[, args])

Destroy the App. Unbinds all event handlers and runs the 'destroy' plugin
hook.
Run the named module hook and return a promise of the results of all the hook
functions. You won't usually need to run this yourself unless you are
extending the base functionality of App.

Optionally accepts an array of argument (`args`) to pass to each hook
function.

:returns Promise: Resolved when destroyed.
:returns: A promise, resolved when all hooks are complete.
:rtype: Promise


.. function:: annotator.App.extend(object)

Create a new object which inherits from the App class.

For example, here we create a ``CustomApp`` which will include the
hypothetical ``mymodules.foo.bar`` module depending on the options object
passed into the constructor::

var CustomApp = annotator.App.extend({
constructor: function (options) {
App.apply(this);
if (options.foo === 'bar') {
this.include(mymodules.foo.bar);
}
}
});

var app = new CustomApp({foo: 'bar'});

:returns: The subclass constructor.
:rtype: Function


6 changes: 3 additions & 3 deletions doc/api/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ API documentation
app
registry
storage
authorizer
identifier
notifier
authz
identity
notification
ui
51 changes: 41 additions & 10 deletions doc/api/registry.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,66 @@ annotator.registry package

.. class:: annotator.registry.Registry()

Registry is an application registry. It serves a registry of configuration
information consulted by an Annotator application while running. Configurable
components are managed through the registry.
`Registry` is an application registry. It serves as a place to register and
find shared components in a running :class:`annotator.App`.

You won't usually create your own `Registry` -- one will be created for you
by the :class:`~annotator.App`. If you are writing an Annotator module, there
are, broadly, two main scenarios in which you will need to interact with the
registry.

1. If you are writing a module which overrides some default component, such
as the "storage" component, you will use the registry in your module's
`configure` function to register your component::

function myStorage () {
return {
configure: function (registry) {
registry.registerUtility(this, 'storage');
},
...
};
}

2. If your module needs to interact with some of the core components of the
`App`, then you will find these exposed on the `Registry` instance. For
example, if your module needs to send a notification when the application
starts, you can use the "notifier" component which is exposed as the
``notify()`` function on the registry::

function myModule () {
return {
start: function (registry) {
registry.notify("Hello, world!");
},
...
};
}


.. function:: annotator.registry.Registry.prototype.registerUtility(component, iface)

Register component `component` as an implementer of interface `iface`.

:param component: The component to register.
:param string iface:
:param string iface: The name of the interface.


.. function:: annotator.registry.Registry.prototype.getUtility(iface)

Get component implementing interface `iface`. Throws :class:`LookupError` if
no matching component is found.
Get component implementing interface `iface`.

:param string iface:
:returns: Component matching `iface`, if found.
:throws LookupError:
:param string iface: The name of the interface.
:returns: Component matching `iface`.
:throws LookupError: If no component is found for interface `iface`.


.. function:: annotator.registry.Registry.prototype.queryUtility(iface)

Get component implementing interface `iface`. Returns `null` if no matching
component is found.

:param string iface:
:param string iface: The name of the interface.
:returns: Component matching `iface`, if found; `null` otherwise.


Expand Down
63 changes: 45 additions & 18 deletions src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,12 @@ function App() {
* passed to the plugin module at initialisation.
*
* If the returned plugin has a `configure` function, this will be called with
* the application registry as its first parameter.
* the application registry as a parameter.
*
* :param Object module:
* :param Object options:
* :returns: The Annotator instance, to allow chained method calls.
* :returns: Itself.
* :rtype: App
*/
App.prototype.include = function (module, options) {
var plugin = module(options);
Expand All @@ -69,7 +70,8 @@ App.prototype.include = function (module, options) {
*
* Runs the 'start' plugin hook.
*
* :returns Promise: Resolved when all plugin 'start' hooks have completed.
* :returns: A promise, resolved when all plugin 'start' hooks have completed.
* :rtype: Promise
*/
App.prototype.start = function () {
if (this._started) {
Expand All @@ -95,12 +97,32 @@ App.prototype.start = function () {
};


/**
* function:: App.prototype.destroy()
*
* Destroy the App. Unbinds all event handlers and runs the 'destroy' plugin
* hook.
*
* :returns: A promise, resolved when destroyed.
* :rtype: Promise
*/
App.prototype.destroy = function () {
return this.runHook('destroy');
};


/**
* function:: App.prototype.runHook(name[, args])
*
* Run the named hook with the provided arguments
* Run the named module hook and return a promise of the results of all the hook
* functions. You won't usually need to run this yourself unless you are
* extending the base functionality of App.
*
* :returns Promise: Resolved when all over the hook handlers are complete.
* Optionally accepts an array of argument (`args`) to pass to each hook
* function.
*
* :returns: A promise, resolved when all hooks are complete.
* :rtype: Promise
*/
App.prototype.runHook = function (name, args) {
var results = [];
Expand All @@ -114,23 +136,28 @@ App.prototype.runHook = function (name, args) {
};


/**
* function:: App.prototype.destroy()
*
* Destroy the App. Unbinds all event handlers and runs the 'destroy' plugin
* hook.
*
* :returns Promise: Resolved when destroyed.
*/
App.prototype.destroy = function () {
return this.runHook('destroy');
};


/**
* function:: App.extend(object)
*
* Create a new object which inherits from the App class.
*
* For example, here we create a ``CustomApp`` which will include the
* hypothetical ``mymodules.foo.bar`` module depending on the options object
* passed into the constructor::
*
* var CustomApp = annotator.App.extend({
* constructor: function (options) {
* App.apply(this);
* if (options.foo === 'bar') {
* this.include(mymodules.foo.bar);
* }
* }
* });
*
* var app = new CustomApp({foo: 'bar'});
*
* :returns: The subclass constructor.
* :rtype: Function
*/
App.extend = extend;

Expand Down
52 changes: 42 additions & 10 deletions src/registry.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,42 @@
/**
* class:: Registry()
*
* Registry is an application registry. It serves a registry of configuration
* information consulted by an Annotator application while running. Configurable
* components are managed through the registry.
* `Registry` is an application registry. It serves as a place to register and
* find shared components in a running :class:`annotator.App`.
*
* You won't usually create your own `Registry` -- one will be created for you
* by the :class:`~annotator.App`. If you are writing an Annotator module, there
* are, broadly, two main scenarios in which you will need to interact with the
* registry.
*
* 1. If you are writing a module which overrides some default component, such
* as the "storage" component, you will use the registry in your module's
* `configure` function to register your component::
*
* function myStorage () {
* return {
* configure: function (registry) {
* registry.registerUtility(this, 'storage');
* },
* ...
* };
* }
*
* 2. If your module needs to interact with some of the core components of the
* `App`, then you will find these exposed on the `Registry` instance. For
* example, if your module needs to send a notification when the application
* starts, you can use the "notifier" component which is exposed as the
* ``notify()`` function on the registry::
*
* function myModule () {
* return {
* start: function (registry) {
* registry.notify("Hello, world!");
* },
* ...
* };
* }
*
*/
function Registry() {
this.utilities = {};
Expand All @@ -19,7 +52,7 @@ function Registry() {
* Register component `component` as an implementer of interface `iface`.
*
* :param component: The component to register.
* :param string iface:
* :param string iface: The name of the interface.
*/
Registry.prototype.registerUtility = function (component, iface) {
this.utilities[iface] = component;
Expand All @@ -28,12 +61,11 @@ Registry.prototype.registerUtility = function (component, iface) {
/**
* function:: Registry.prototype.getUtility(iface)
*
* Get component implementing interface `iface`. Throws :class:`LookupError` if
* no matching component is found.
* Get component implementing interface `iface`.
*
* :param string iface:
* :returns: Component matching `iface`, if found.
* :throws LookupError:
* :param string iface: The name of the interface.
* :returns: Component matching `iface`.
* :throws LookupError: If no component is found for interface `iface`.
*/
Registry.prototype.getUtility = function (iface) {
var component = this.queryUtility(iface);
Expand All @@ -49,7 +81,7 @@ Registry.prototype.getUtility = function (iface) {
* Get component implementing interface `iface`. Returns `null` if no matching
* component is found.
*
* :param string iface:
* :param string iface: The name of the interface.
* :returns: Component matching `iface`, if found; `null` otherwise.
*/
Registry.prototype.queryUtility = function (iface) {
Expand Down

0 comments on commit e90cc06

Please sign in to comment.