From bfd7d037d7e402e31122e4e7415e5b0ab675e65a Mon Sep 17 00:00:00 2001 From: JC Brand Date: Thu, 20 Oct 2016 10:46:31 +0000 Subject: [PATCH] Document angular.js integration --- config.js | 3 +- docs/source/development.rst | 153 +++++++++++++++++++++++++++++++----- 2 files changed, 134 insertions(+), 22 deletions(-) diff --git a/config.js b/config.js index f4a3cff9f..6786de4f6 100644 --- a/config.js +++ b/config.js @@ -18,6 +18,7 @@ require.config({ "backbone": "node_modules/backbone/backbone", "backbone.browserStorage": "node_modules/backbone.browserStorage/backbone.browserStorage", "backbone.overview": "node_modules/backbone.overview/backbone.overview", + "converse": "src/converse", "eventemitter": "node_modules/otr/build/dep/eventemitter", "jquery": "node_modules/jquery/dist/jquery", "jquery-private": "src/jquery-private", @@ -25,6 +26,7 @@ require.config({ "jquery.easing": "node_modules/jquery-easing/jquery.easing.1.3.umd", // XXX: Only required for https://conversejs.org website "moment": "node_modules/moment/moment", "pluggable": "node_modules/pluggable.js/pluggable", + "polyfill": "src/polyfill", "strophe": "node_modules/strophe.js/src/wrapper", "strophe-base64": "node_modules/strophe.js/src/base64", "strophe-bosh": "node_modules/strophe.js/src/bosh", @@ -43,7 +45,6 @@ require.config({ "typeahead": "components/typeahead.js/index", "underscore": "node_modules/underscore/underscore", "utils": "src/utils", - "polyfill": "src/polyfill", // Converse "converse-api": "src/converse-api", diff --git a/docs/source/development.rst b/docs/source/development.rst index ed93ec272..acc9e9526 100644 --- a/docs/source/development.rst +++ b/docs/source/development.rst @@ -13,8 +13,8 @@ Development :local: If you want to work with the non-minified Javascript and CSS files you'll soon -notice that there are references to a missing *components* folder. Please -follow the instructions below to create this folder and fetch Converse's +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:: @@ -36,7 +36,7 @@ version `here `_. Also make sure you have ``Git`` installed. `Details `_. .. note:: - Windows users should use Chocolatey as recommended above.: + Windows users should use Chocolatey as recommended above. .. note:: Debian & Ubuntu users : apt-get install git npm nodejs-legacy @@ -60,25 +60,18 @@ Or alternatively, if you don't have GNU Make: bower update This will first install the Node.js development tools (like Grunt and Bower) -and then use Bower to install all of Converse.js's front-end dependencies. +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. -If you are curious to know what the different dependencies are: - -* Development dependencies: - Take a look at whats under the *devDependencies* key in +To see the dependencies, take a look at whats under the *devDependencies* key in `package.json `_. -* Front-end dependencies: - See *dependencies* in - `bower.json `_. - .. note:: - After running ```make dev```, you should now have a new directory *components*, - which contains all the front-end dependencies of Converse.js. - If this directory does NOT exist, something must have gone wrong. + 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 @@ -117,13 +110,13 @@ 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. -Before submitting a pull request --------------------------------- +The programming style guide +--------------------------- Please read the `style guide `_ 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. @@ -132,7 +125,7 @@ and the `spec files `_ @@ -180,8 +173,7 @@ initialize Initializes converse.js. This method must always be called when using converse.js. -The `initialize` method takes a map (also called a hash or dictionary) of -:ref:`configuration-variables`. +The `initialize` method takes a map (also called a hash or dictionary) of :ref:`configuration-variables`. Example: @@ -1044,6 +1036,125 @@ When converse.js has learned of a service provided by the XMPP server. See XEP-0 ``converse.listen.on('serviceDiscovered', function (event, service) { ... });`` +Integration into other frameworks +================================= + +Angular.js +---------- + +Angular.js has the concept of a `service `_, +which is a special kind of `provider `_. + +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 `_ +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:: + + angular.module('my-module', ['converse']); + +Then you can have the converse service dependency injected into +your components, for example:: + + 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. + +The API of converse is available via the ``.api`` attribute on the service. +So you can call it like this for example:: + + converse.api.user.status.set('online'); + Writing a converse.js plugin ============================