Commit 575e9da7 authored by JC Brand's avatar JC Brand

Split development docs into separate files/sections

parent bfd7d037
......@@ -15,6 +15,11 @@ h5 {
font-weight: bold;
}
.toctree-l1 > a {
font-size: 110%;
font-weight: bold;
}
.navbar-brand {
padding-top: 7px;
}
......
Developer guidelines
====================
If you want to work with the non-minified Javascript and CSS files you'll soon
notice that there are references to missing *components* and *node_modules* directories.
Please follow the instructions below to create these directories and fetch Converse's
3rd-party dependencies.
.. note::
Windows environment: We recommend installing the required tools using `Chocolatey <https://chocolatey.org/>`_
You will need Node.js (nodejs.install), Git (git.install) and optionally to build using Makefile, GNU Make (make)
If you have trouble setting up a development environment on Windows,
please read `this post <http://librelist.com/browser//conversejs/2014/11/5/openfire-converse-and-visual-studio-questions/#b28387e7f8f126693b11598a8acbe810>`_
in the mailing list.:
Installing the development and front-end dependencies
-----------------------------------------------------
We use development tools (`Grunt <http://gruntjs.com>`_ and `Bower <http://bower.io>`_)
which depend on Node.js and npm (the Node package manager).
If you don't have Node.js installed, you can download and install the latest
version `here <https://nodejs.org/download>`_.
Also make sure you have ``Git`` installed. `Details <http://git-scm.com/book/en/Getting-Started-Installing-Git>`_.
.. note::
Windows users should use Chocolatey as recommended above.
.. note::
Debian & Ubuntu users : apt-get install git npm nodejs-legacy
Once you have *Node.js* and *git* installed, run the following command inside the Converse.js
directory:
::
make dev
On Windows you need to specify Makefile.win to be used by running: ::
make -f Makefile.win dev
Or alternatively, if you don't have GNU Make:
::
npm install
bower update
This will first install the Node.js development tools (like Grunt and Bower)
as well as Converse.js's front-end dependencies.
The front-end dependencies are those javascript files on which
Converse.js directly depends and which will be loaded in the browser.
To see the dependencies, take a look at whats under the *devDependencies* key in
`package.json <https://github.com/jcbrand/converse.js/blob/master/package.json>`_.
.. note::
After running ```make dev```, you should now have new directories *components*
and *node_modules*, which contain all the front-end dependencies of Converse.js.
If these directory does NOT exist, something must have gone wrong.
Double-check the output of ```make dev``` to see if there are any errors
listed. For support, you can write to the mailing list: conversejs@librelist.com
Loading converse.js and its dependencies
----------------------------------------
With AMD and require.js (recommended)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Converse.js uses `require.js <http://requirejs.org>`_ to asynchronously load dependencies.
If you want to develop or customize converse.js, you'll want to load the
non-minified javascript files.
Add the following two lines to the *<head>* section of your webpage:
.. code-block:: html
<link rel="stylesheet" type="text/css" media="screen" href="converse.css">
<script data-main="main" src="components/requirejs/require.js"></script>
require.js will then let the main.js file be parsed (because of the *data-main*
attribute on the *script* tag), which will in turn cause converse.js to be
parsed.
Without AMD and require.js
~~~~~~~~~~~~~~~~~~~~~~~~~~
Converse.js can also be used without require.js. If you for some reason prefer
to use it this way, please refer to
`non_amd.html <https://github.com/jcbrand/converse.js/blob/master/non_amd.html>`_
for an example of how and in what order all the Javascript files that converse.js
depends on need to be loaded.
Before submitting a pull request
--------------------------------
Please follow the usual github workflow. Create your own local fork of this repository,
make your changes and then submit a pull request.
Follow the programming style guide
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Please read the `style guide </docs/html/style_guide.html>`_ and make sure that your code follows it.
Add tests for your bugfix or feature
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Add a test for any bug fixed or feature added. We use Jasmine
for testing.
Take a look at `tests.html <https://github.com/jcbrand/converse.js/blob/master/tests.html>`_
and the `spec files <https://github.com/jcbrand/converse.js/blob/master/tests.html>`_
to see how tests are implemented.
Check that the tests pass
~~~~~~~~~~~~~~~~~~~~~~~~~
Check that all tests complete sucessfully.
Run ``make check`` in your terminal or open `tests.html <https://github.com/jcbrand/converse.js/blob/master/tests.html>`_
in your browser.
This diff is collapsed.
Developer guidelines
====================
If you want to work with the non-minified Javascript and CSS files you'll soon
notice that there are references to missing *components* and *node_modules* directories.
Please follow the instructions below to create these directories and fetch Converse's
3rd-party dependencies.
.. note::
Windows environment: We recommend installing the required tools using `Chocolatey <https://chocolatey.org/>`_
You will need Node.js (nodejs.install), Git (git.install) and optionally to build using Makefile, GNU Make (make)
If you have trouble setting up a development environment on Windows,
please read `this post <http://librelist.com/browser//conversejs/2014/11/5/openfire-converse-and-visual-studio-questions/#b28387e7f8f126693b11598a8acbe810>`_
in the mailing list.:
Installing the development and front-end dependencies
-----------------------------------------------------
We use development tools (`Grunt <http://gruntjs.com>`_ and `Bower <http://bower.io>`_)
which depend on Node.js and npm (the Node package manager).
If you don't have Node.js installed, you can download and install the latest
version `here <https://nodejs.org/download>`_.
Also make sure you have ``Git`` installed. `Details <http://git-scm.com/book/en/Getting-Started-Installing-Git>`_.
.. note::
Windows users should use Chocolatey as recommended above.
.. note::
Debian & Ubuntu users : apt-get install git npm nodejs-legacy
Once you have *Node.js* and *git* installed, run the following command inside the Converse.js
directory:
::
make dev
On Windows you need to specify Makefile.win to be used by running: ::
make -f Makefile.win dev
Or alternatively, if you don't have GNU Make:
::
npm install
bower update
This will first install the Node.js development tools (like Grunt and Bower)
as well as Converse.js's front-end dependencies.
The front-end dependencies are those javascript files on which
Converse.js directly depends and which will be loaded in the browser.
To see the dependencies, take a look at whats under the *devDependencies* key in
`package.json <https://github.com/jcbrand/converse.js/blob/master/package.json>`_.
.. note::
After running ```make dev```, you should now have new directories *components*
and *node_modules*, which contain all the front-end dependencies of Converse.js.
If these directory does NOT exist, something must have gone wrong.
Double-check the output of ```make dev``` to see if there are any errors
listed. For support, you can write to the mailing list: conversejs@librelist.com
Loading converse.js and its dependencies
----------------------------------------
With AMD and require.js (recommended)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Converse.js uses `require.js <http://requirejs.org>`_ to asynchronously load dependencies.
If you want to develop or customize converse.js, you'll want to load the
non-minified javascript files.
Add the following two lines to the *<head>* section of your webpage:
.. code-block:: html
<link rel="stylesheet" type="text/css" media="screen" href="converse.css">
<script data-main="main" src="components/requirejs/require.js"></script>
require.js will then let the main.js file be parsed (because of the *data-main*
attribute on the *script* tag), which will in turn cause converse.js to be
parsed.
Without AMD and require.js
~~~~~~~~~~~~~~~~~~~~~~~~~~
Converse.js can also be used without require.js. If you for some reason prefer
to use it this way, please refer to
`non_amd.html <https://github.com/jcbrand/converse.js/blob/master/non_amd.html>`_
for an example of how and in what order all the Javascript files that converse.js
depends on need to be loaded.
Before submitting a pull request
--------------------------------
Please follow the usual github workflow. Create your own local fork of this repository,
make your changes and then submit a pull request.
Follow the programming style guide
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Please read the `style guide </docs/html/style_guide.html>`_ and make sure that your code follows it.
Add tests for your bugfix or feature
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Add a test for any bug fixed or feature added. We use Jasmine
for testing.
Take a look at `tests.html <https://github.com/jcbrand/converse.js/blob/master/tests.html>`_
and the `spec files <https://github.com/jcbrand/converse.js/blob/master/tests.html>`_
to see how tests are implemented.
Check that the tests pass
~~~~~~~~~~~~~~~~~~~~~~~~~
Check that all tests complete sucessfully.
Run ``make check`` in your terminal or open `tests.html <https://github.com/jcbrand/converse.js/blob/master/tests.html>`_
in your browser.
This diff is collapsed.
......@@ -12,8 +12,8 @@ Writing Documentation
.. note:: Contributions to the documentation are much appreciated.
What is used to write the documentation
=======================================
What is used to write the documentation?
========================================
This documentation is written in `Sphinx <http://sphinx-doc.org/>`_, a
documentation generator written in `Python <http://python.org>`_.
......@@ -24,15 +24,15 @@ a very easy to write plain text format, relatively similar to Markdown.
So see what the source looks like, click the **Source** link in the footer of
this page.
Where is the documentation
==========================
Where is the documentation?
===========================
The reST documentation files are located in the
`converse.js code repository <https://github.com/jcbrand/converse.js/tree/master/docs/source>`_
under ``docs/source``.
How to generate HTML from the source files
==========================================
How to generate HTML from the source files?
===========================================
Install Dependencies
--------------------
......
Events emitted by converse.js
=============================
.. note:: see also :ref:`listen-grouping` above.
Event Types
-----------
Here are the different events that are emitted:
cachedRoster
~~~~~~~~~~~~
The contacts roster has been retrieved from the local cache (`sessionStorage`).
``converse.listen.on('cachedRoster', function (event, items) { ... });``
See also the `roster` event further down.
callButtonClicked
~~~~~~~~~~~~~~~~~
When a call button (i.e. with class .toggle-call) on a chat box has been clicked.
``converse.listen.on('callButtonClicked', function (event, connection, model) { ... });``
chatBoxInitialized
~~~~~~~~~~~~~~~~~~
When a chat box has been initialized. Relevant to converse-chatview.js plugin.
``converse.listen.on('chatBoxInitialized', function (event, chatbox) { ... });``
chatBoxOpened
~~~~~~~~~~~~~
When a chat box has been opened. Relevant to converse-chatview.js plugin.
``converse.listen.on('chatBoxOpened', function (event, chatbox) { ... });``
chatRoomOpened
~~~~~~~~~~~~~~
When a chat room has been opened. Relevant to converse-chatview.js plugin.
``converse.listen.on('chatRoomOpened', function (event, chatbox) { ... });``
chatBoxClosed
~~~~~~~~~~~~~
When a chat box has been closed. Relevant to converse-chatview.js plugin.
``converse.listen.on('chatBoxClosed', function (event, chatbox) { ... });``
chatBoxFocused
~~~~~~~~~~~~~~
When the focus has been moved to a chat box. Relevant to converse-chatview.js plugin.
``converse.listen.on('chatBoxFocused', function (event, chatbox) { ... });``
chatBoxToggled
~~~~~~~~~~~~~~
When a chat box has been minimized or maximized. Relevant to converse-chatview.js plugin.
``converse.listen.on('chatBoxToggled', function (event, chatbox) { ... });``
connected
~~~~~~~~~
After connection has been established and converse.js has got all its ducks in a row.
``converse.listen.on('connected', function (event) { ... });``
contactRequest
~~~~~~~~~~~~~~
Someone has requested to subscribe to your presence (i.e. to be your contact).
``converse.listen.on('contactRequest', function (event, user_data) { ... });``
contactRemoved
~~~~~~~~~~~~~~
The user has removed a contact.
``converse.listen.on('contactRemoved', function (event, data) { ... });``
contactStatusChanged
~~~~~~~~~~~~~~~~~~~~
When a chat buddy's chat status has changed.
``converse.listen.on('contactStatusChanged', function (event, buddy) { ... });``
contactStatusMessageChanged
~~~~~~~~~~~~~~~~~~~~~~~~~~~
When a chat buddy's custom status message has changed.
``converse.listen.on('contactStatusMessageChanged', function (event, data) { ... });``
disconnected
~~~~~~~~~~~~
After converse.js has disconnected from the XMPP server.
``converse.listen.on('disconnected', function (event) { ... });``
initialized
~~~~~~~~~~~
Once converse.js has been initialized.
``converse.listen.on('initialized', function (event) { ... });``
See also `pluginsInitialized`_.
messageSend
~~~~~~~~~~~
When a message will be sent out.
``converse.listen.on('messageSend', function (event, messageText) { ... });``
noResumeableSession
~~~~~~~~~~~~~~~~~~~
When keepalive=true but there aren't any stored prebind tokens.
``converse.listen.on('noResumeableSession', function (event) { ... });``
pluginsInitialized
~~~~~~~~~~~~~~~~~~
Once all plugins have been initialized. This is a useful event if you want to
register event handlers but would like your own handlers to be overridable by
plugins. In that case, you need to first wait until all plugins have been
initialized, so that their overrides are active. One example where this is used
is in `converse-notifications.js <https://github.com/jcbrand/converse.js/blob/master/src/converse-notification.js>`.
``converse.listen.on('pluginsInitialized', function (event) { ... });``
reconnected
~~~~~~~~~~~
After the connection has dropped and converse.js has reconnected.
Any Strophe stanza handlers (as registered via `converse.listen.stanza`) will
have to be registered anew.
``converse.listen.on('reconnected', function (event) { ... });``
roomInviteSent
~~~~~~~~~~~~~~
After the user has sent out a direct invitation, to a roster contact, asking them to join a room.
``converse.listen.on('roomInvite', function (event, data) { ... });``
roomInviteReceived
~~~~~~~~~~~~~~~~~~
After the user has sent out a direct invitation, to a roster contact, asking them to join a room.
``converse.listen.on('roomInvite', function (event, data) { ... });``
roster
~~~~~~
When the roster has been received from the XMPP server.
``converse.listen.on('roster', function (event, items) { ... });``
See also the `cachedRoster` event further up, which gets called instead of
`roster` if its already in `sessionStorage`.
rosterContactsFetched
~~~~~~~~~~~~~~~~~~~~~
Triggered once roster contacts have been fetched. Used by the
`converse-rosterview.js` plugin to know when it can start to show the roster.
rosterGroupsFetched
~~~~~~~~~~~~~~~~~~~
Triggered once roster groups have been fetched. Used by the
`converse-rosterview.js` plugin to know when it can start alphabetically
position roster groups.
rosterPush
~~~~~~~~~~
When the roster receives a push event from server. (i.e. New entry in your buddy list)
``converse.listen.on('rosterPush', function (event, items) { ... });``
statusInitialized
~~~~~~~~~~~~~~~~~
When own chat status has been initialized.
``converse.listen.on('statusInitialized', function (event, status) { ... });``
statusChanged
~~~~~~~~~~~~~
When own chat status has changed.
``converse.listen.on('statusChanged', function (event, status) { ... });``
statusMessageChanged
~~~~~~~~~~~~~~~~~~~~
When own custom status message has changed.
``converse.listen.on('statusMessageChanged', function (event, message) { ... });``
serviceDiscovered
~~~~~~~~~~~~~~~~~
When converse.js has learned of a service provided by the XMPP server. See XEP-0030.
``converse.listen.on('serviceDiscovered', function (event, service) { ... });``
......@@ -48,10 +48,7 @@ Table of Contents
setup
configuration
development
style_guide
theming
translations
troubleshooting
documentation
builds
Integrating converse.js into other frameworks
=============================================
Angular.js
----------
Angular.js has the concept of a `service <https://docs.angularjs.org/guide/services#!>`_,
which is a special kind of `provider <https://docs.angularjs.org/guide/providers>`_.
An angular.js service is a constructor or object which provides an API defined by the
writer of the service. The goal of a service is to organize and share code, so
that it can be used across an application.
So, if we wanted to properly integrate converse.js into an angular.js
application, then putting it into a service is a good approach.
This lets us avoid having a global ``converse`` API object (accessible via
``windows.converse``), and instead we can get hold of the converse API via
angular.js dependency injection, when we specify it as a dependency for our
angular components.
Below is an example code that wraps converse.js as an angular.js service.
.. code-block:: javascript
angular.module('converse', []).service('converse', function() {
var deferred = new $.Deferred(),
promise = deferred.promise();
var service = {
'load': _.constant(promise),
'initialize': function initConverse(options) {
this.load().done(_.partial(this.api.initialize, options));
}
};
define("converse", [
"converse-api",
// START: Removable components
// --------------------
// Any of the following components may be removed if they're not needed.
"locales", // Translations for converse.js. This line can be removed
// to remove *all* translations, or you can modify the
// file src/locales.js to include only those
// translations that you care about.
"converse-chatview", // Renders standalone chat boxes for single user chat
"converse-controlbox", // The control box
"converse-bookmarks", // XEP-0048 Bookmarks
"converse-mam", // XEP-0313 Message Archive Management
"converse-muc", // XEP-0045 Multi-user chat
"converse-vcard", // XEP-0054 VCard-temp
"converse-otr", // Off-the-record encryption for one-on-one messages
"converse-register", // XEP-0077 In-band registration
"converse-ping", // XEP-0199 XMPP Ping
"converse-notification", // HTML5 Notifications
"converse-minimize", // Allows chat boxes to be minimized
"converse-dragresize", // Allows chat boxes to be resized by dragging them
"converse-headline", // Support for headline messages
// END: Removable components
], function(converse_api) {
service.api = converse_api;
return deferred.resolve();
});
require(["converse"]);
return service;
});
The above code is a modified version of the file `src/converse.js <https://github.com/jcbrand/converse.js/blob/master/src/converse.js>`_
which defines the converse AMD module and specifies which plugins will go into
this build.
You should replace the contents of that file with the above, if you want such a
service registered. Then, you should run `make build`, to create new build
files in the `dist` directory, containing your new angular.js service.
The above code registers an angular.js module and service, both named ``converse``.
This module should then be added as a dependency for your own angular.js
modules, for example:
.. code-block:: javascript
angular.module('my-module', ['converse']);
Then you can have the converse service dependency injected into
your components, for example:
.. code-block:: javascript
angular.module('my-module').provider('my-provider', function(converse) {
// Your custom code can come here..
// Then when you're ready, you can initialize converse.js
converse.load().done(function () {
converse.initialize({
'allow_logout': false,
'auto_login': 'true',
'auto_reconnect': true,
'bosh_service_url': bosh_url,
'jid': bare_jid,
'keepalive': true,
'credentials_url': credentials_url,
});
// More custom code could come here...
});
});
You might have noticed the ``load()`` method being called on the ``converse``
service. This is a special method added to the service (see the implementation
example above) that makes sure that converse.js is loaded and available. It
returns a jQuery promise which resolves once converse.js is available.
This is necessary because with otherwise you might run into race-conditions
when your angular application loads more quickly then converse.js.
Lastly, the API of converse is available via the ``.api`` attribute on the service.
So you can call it like this for example:
.. code-block:: javascript
converse.api.user.status.set('online');
Writing a converse.js plugin
============================
Developers are able to extend and override the objects, functions and the
Backbone models and views that make up converse.js by means of writing plugins.
Converse.js uses `pluggable.js <https://github.com/jcbrand/pluggable.js/>`_ as
its plugin architecture.
To understand how this plugin architecture works, please read the
`pluggable.js documentation <https://jcbrand.github.io/pluggable.js/>`_
and to grok its inner workins, please refer to the `annotated source code
<https://jcbrand.github.io/pluggable.js/docs/pluggable.html>`_.
You register a converse.js plugin as follows:
.. code-block:: javascript
converse.plugins.add('myplugin', {
// Your plugin code goes in here
});
Security and access to the inner workings
-----------------------------------------
The globally available ``converse`` object, which exposes the API methods, such
as ``initialize`` and ``plugins.add``, is a wrapper that encloses and protects
a sensitive inner object.
This inner object contains all the Backbone models and views, as well as
various other attributes and functions.
Within a plugin, you will have access to this internal
`"closured" <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures>`_
converse object, which is normally not exposed in the global variable scope. The
hiding of this inner object is due to the fact that it contains sensitive information,
such as the user's JID and password (if they logged in manually). You should
therefore make sure NOT to expose this object globally.
An example plugin
-----------------
.. code-block:: javascript
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as a module called "myplugin"
define("myplugin", ["converse"], factory);
} else {
// Browser globals. If you're not using a module loader such as require.js,
// then this line below executes. Make sure that your plugin's <script> tag
// appears after the one from converse.js.
factory(converse);
}
}(this, function (converse_api) {
// Commonly used utilities and variables can be found under the "env"
// namespace of converse_api
// Strophe methods for building stanzas
var Strophe = converse_api.env.Strophe,
$iq = converse_api.env.$iq,
$msg = converse_api.env.$msg,
$pres = converse_api.env.$pres,
$build = converse_api.env.$build,
b64_sha1 = converse_api.env.b64_sha1;
// Other frequently used utilities
var $ = converse_api.env.jQuery,
_ = converse_api.env._,
moment = converse_api.env.moment;
// The following line registers your plugin.
converse_api.plugins.add('myplugin', {
initialize: function () {
// Converse.js's plugin mechanism will call the initialize
// method on any plugin (if it exists) as soon as the plugin has
// been loaded.
// Inside this method, you have access to the protected "inner"
// converse object, from which you can get any configuration
// options that the user might have passed in via
// converse.initialize. These values are stored in the
// "user_settings" attribute.
// Let's assume the user might in a custom setting, like so:
// converse.initialize({
// "initialize_message": "My plugin has been initialized"
// });
//
// Then we can alert that message, like so:
alert(this.converse.user_settings.initialize_message);
},
myFunction: function () {
// This is a function which does not override anything in
// converse.js itself, but in which you still have access to
// the protected "inner" converse object.
var converse = this.converse;
// Custom code comes here
// ...
},
overrides: {
// If you want to override some function or a Backbone model or
// view defined inside converse, then you do that under this
// "overrides" namespace.
// For example, the inner protected *converse* object has a
// method "onConnected". You can override that method as follows:
onConnected: function () {
// Overrides the onConnected method in converse.js
// Top-level functions in "overrides" are bound to the
// inner "converse" object.
var converse = this;
// Your custom code comes here.
// ...
// You can access the original function being overridden
// via the __super__ attribute.
// Make sure to pass on the arguments supplied to this
// function and also to apply the proper "this" object.
this.__super__.onConnected.apply(this, arguments);
},
XMPPStatus: {
// Override converse.js's XMPPStatus Backbone model so that we can override the
// function that sends out the presence stanza.
sendPresence: function (type, status_message, jid) {
// The "converse" object is available via the __super__
// attribute.
var converse = this.__super__.converse;
// Custom code can come here
// ...
// You can call the original overridden method, by
// accessing it via the __super__ attribute.
// When calling it, you need to apply the proper
// context as reference by the "this" variable.
this.__super__.sendPresence.apply(this, arguments);
}
},
}
});
}));
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment