development.rst 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182
  1. .. raw:: html
  2. <div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/development.rst">Edit me on GitHub</a></div>
  3. .. _development:
  4. ===========
  5. Development
  6. ===========
  7. .. contents:: Table of Contents
  8. :depth: 2
  9. :local:
  10. If you want to work with the non-minified Javascript and CSS files you'll soon
  11. notice that there are references to a missing *components* folder. Please
  12. follow the instructions below to create this folder and fetch Converse's
  13. 3rd-party dependencies.
  14. .. note::
  15. Windows environment: We recommend installing the required tools using `Chocolatey <https://chocolatey.org/>`_
  16. You will need Node.js (nodejs.install), Git (git.install) and optionally to build using Makefile, GNU Make (make)
  17. If you have trouble setting up a development environment on Windows,
  18. please read `this post <http://librelist.com/browser//conversejs/2014/11/5/openfire-converse-and-visual-studio-questions/#b28387e7f8f126693b11598a8acbe810>`_
  19. in the mailing list.:
  20. Install the development and front-end dependencies
  21. ==================================================
  22. We use development tools (`Grunt <http://gruntjs.com>`_ and `Bower <http://bower.io>`_)
  23. which depend on Node.js and npm (the Node package manager).
  24. If you don't have Node.js installed, you can download and install the latest
  25. version `here <https://nodejs.org/download>`_.
  26. Also make sure you have ``Git`` installed. `Details <http://git-scm.com/book/en/Getting-Started-Installing-Git>`_.
  27. .. note::
  28. Windows users should use Chocolatey as recommended above.:
  29. .. note::
  30. Debian & Ubuntu users : apt-get install git npm nodejs-legacy
  31. Once you have *Node.js* and *git* installed, run the following command inside the Converse.js
  32. directory:
  33. ::
  34. make dev
  35. On Windows you need to specify Makefile.win to be used by running: ::
  36. make -f Makefile.win dev
  37. Or alternatively, if you don't have GNU Make:
  38. ::
  39. npm install
  40. bower update
  41. This will first install the Node.js development tools (like Grunt and Bower)
  42. and then use Bower to install all of Converse.js's front-end dependencies.
  43. The front-end dependencies are those javascript files on which
  44. Converse.js directly depends and which will be loaded in the browser.
  45. If you are curious to know what the different dependencies are:
  46. * Development dependencies:
  47. Take a look at whats under the *devDependencies* key in
  48. `package.json <https://github.com/jcbrand/converse.js/blob/master/package.json>`_.
  49. * Front-end dependencies:
  50. See *dependencies* in
  51. `bower.json <https://github.com/jcbrand/converse.js/blob/master/bower.json>`_.
  52. .. note::
  53. After running ```make dev```, you should now have a new directory *components*,
  54. which contains all the front-end dependencies of Converse.js.
  55. If this directory does NOT exist, something must have gone wrong.
  56. Double-check the output of ```make dev``` to see if there are any errors
  57. listed. For support, you can write to the mailing list: conversejs@librelist.com
  58. With AMD and require.js (recommended)
  59. =====================================
  60. Converse.js uses `require.js <http://requirejs.org>`_ to asynchronously load dependencies.
  61. If you want to develop or customize converse.js, you'll want to load the
  62. non-minified javascript files.
  63. Add the following two lines to the *<head>* section of your webpage:
  64. .. code-block:: html
  65. <link rel="stylesheet" type="text/css" media="screen" href="converse.css">
  66. <script data-main="main" src="components/requirejs/require.js"></script>
  67. require.js will then let the main.js file be parsed (because of the *data-main*
  68. attribute on the *script* tag), which will in turn cause converse.js to be
  69. parsed.
  70. Without AMD and require.js
  71. ==========================
  72. Converse.js can also be used without require.js. If you for some reason prefer
  73. to use it this way, please refer to
  74. `non_amd.html <https://github.com/jcbrand/converse.js/blob/master/non_amd.html>`_
  75. for an example of how and in what order all the Javascript files that converse.js
  76. depends on need to be loaded.
  77. Before submitting a pull request
  78. ================================
  79. Please follow the usual github workflow. Create your own local fork of this repository,
  80. make your changes and then submit a pull request.
  81. Before submitting a pull request
  82. --------------------------------
  83. Please read the `style guide </docs/html/style_guide.html>`_ and make sure that your code follows it.
  84. Add tests for your bugfix or feature
  85. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  86. Add a test for any bug fixed or feature added. We use Jasmine
  87. for testing.
  88. Take a look at `tests.html <https://github.com/jcbrand/converse.js/blob/master/tests.html>`_
  89. and the `spec files <https://github.com/jcbrand/converse.js/blob/master/tests.html>`_
  90. to see how tests are implemented.
  91. Check that the tests pass
  92. ~~~~~~~~~~~~~~~~~~~~~~~~~
  93. Check that all tests complete sucessfully.
  94. Run ``make check`` in your terminal or open `tests.html <https://github.com/jcbrand/converse.js/blob/master/tests.html>`_
  95. in your browser.
  96. Developer API
  97. =============
  98. .. note:: The API documented here is available in Converse.js 0.8.4 and higher.
  99. Earlier versions of Converse.js might have different API methods or none at all.
  100. In the Converse.js API, you traverse towards a logical grouping, from
  101. which you can then call certain standardised accessors and mutators, such as::
  102. .get
  103. .set
  104. .add
  105. .remove
  106. This is done to increase readability and to allow intuitive method chaining.
  107. For example, to get a contact, you would do the following::
  108. converse.contacts.get('jid@example.com');
  109. To get multiple contacts, just pass in an array of jids::
  110. converse.contacts.get(['jid1@example.com', 'jid2@example.com']);
  111. To get all contacts, simply call ``get`` without any jids::
  112. converse.contacts.get();
  113. **Here follows now a breakdown of all API groupings and methods**:
  114. initialize
  115. ----------
  116. .. note:: This method is the one exception of a method which is not logically grouped
  117. as explained above.
  118. Initializes converse.js. This method must always be called when using
  119. converse.js.
  120. The `initialize` method takes a map (also called a hash or dictionary) of
  121. :ref:`configuration-variables`.
  122. Example:
  123. .. code-block:: javascript
  124. converse.initialize({
  125. allow_otr: true,
  126. auto_list_rooms: false,
  127. auto_subscribe: false,
  128. bosh_service_url: 'https://bind.example.com',
  129. hide_muc_server: false,
  130. i18n: locales['en'],
  131. keepalive: true,
  132. play_sounds: true,
  133. prebind: false,
  134. show_controlbox_by_default: true,
  135. debug: false,
  136. roster_groups: true
  137. });
  138. send
  139. ----
  140. Allows you to send XML stanzas.
  141. For example, to send a message stanza:
  142. .. code-block:: javascript
  143. var msg = converse.env.$msg({
  144. from: 'juliet@example.com/balcony',
  145. to:'romeo@example.net',
  146. type:'chat'
  147. });
  148. converse.send(msg);
  149. The "archive" grouping
  150. ----------------------
  151. Converse.js supports the *Message Archive Management*
  152. (`XEP-0313 <https://xmpp.org/extensions/xep-0313.html>`_) protocol,
  153. through which it is able to query an XMPP server for archived messages.
  154. See also the **message_archiving** option in the :ref:`configuration-variables` section, which you'll usually
  155. want to in conjunction with this API.
  156. query
  157. ~~~~~
  158. The ``query`` method is used to query for archived messages.
  159. It accepts the following optional parameters:
  160. * **options** an object containing the query parameters. Valid query parameters
  161. are ``with``, ``start``, ``end``, ``first``, ``last``, ``after``, ``before``, ``index`` and ``count``.
  162. * **callback** is the callback method that will be called when all the messages
  163. have been received.
  164. * **errback** is the callback method to be called when an error is returned by
  165. the XMPP server, for example when it doesn't support message archiving.
  166. Examples
  167. ^^^^^^^^
  168. **Requesting all archived messages**
  169. The simplest query that can be made is to simply not pass in any parameters.
  170. Such a query will return all archived messages for the current user.
  171. Generally, you'll however always want to pass in a callback method, to receive
  172. the returned messages.
  173. .. code-block:: javascript
  174. var errback = function (iq) {
  175. // The query was not successful, perhaps inform the user?
  176. // The IQ stanza returned by the XMPP server is passed in, so that you
  177. // may inspect it and determine what the problem was.
  178. }
  179. var callback = function (messages) {
  180. // Do something with the messages, like showing them in your webpage.
  181. }
  182. converse.archive.query(callback, errback))
  183. **Waiting until server support has been determined**
  184. The query method will only work if converse.js has been able to determine that
  185. the server supports MAM queries, otherwise the following error will be raised:
  186. - *This server does not support XEP-0313, Message Archive Management*
  187. The very first time converse.js loads in a browser tab, if you call the query
  188. API too quickly, the above error might appear because service discovery has not
  189. yet been completed.
  190. To work solve this problem, you can first listen for the ``serviceDiscovered`` event,
  191. through which you can be informed once support for MAM has been determined.
  192. For example:
  193. .. code-block:: javascript
  194. converse.listen.on('serviceDiscovered', function (event, feature) {
  195. if (feature.get('var') === converse.env.Strophe.NS.MAM) {
  196. converse.archive.query()
  197. }
  198. });
  199. **Requesting all archived messages for a particular contact or room**
  200. To query for messages sent between the current user and another user or room,
  201. the query options need to contain the the JID (Jabber ID) of the user or
  202. room under the ``with`` key.
  203. .. code-block:: javascript
  204. // For a particular user
  205. converse.archive.query({'with': 'john@doe.net'}, callback, errback);)
  206. // For a particular room
  207. converse.archive.query({'with': 'discuss@conference.doglovers.net'}, callback, errback);)
  208. **Requesting all archived messages before or after a certain date**
  209. The ``start`` and ``end`` parameters are used to query for messages
  210. within a certain timeframe. The passed in date values may either be ISO8601
  211. formatted date strings, or Javascript Date objects.
  212. .. code-block:: javascript
  213. var options = {
  214. 'with': 'john@doe.net',
  215. 'start': '2010-06-07T00:00:00Z',
  216. 'end': '2010-07-07T13:23:54Z'
  217. };
  218. converse.archive.query(options, callback, errback);
  219. **Limiting the amount of messages returned**
  220. The amount of returned messages may be limited with the ``max`` parameter.
  221. By default, the messages are returned from oldest to newest.
  222. .. code-block:: javascript
  223. // Return maximum 10 archived messages
  224. converse.archive.query({'with': 'john@doe.net', 'max':10}, callback, errback);
  225. **Paging forwards through a set of archived messages**
  226. When limiting the amount of messages returned per query, you might want to
  227. repeatedly make a further query to fetch the next batch of messages.
  228. To simplify this usecase for you, the callback method receives not only an array
  229. with the returned archived messages, but also a special RSM (*Result Set
  230. Management*) object which contains the query parameters you passed in, as well
  231. as two utility methods ``next``, and ``previous``.
  232. When you call one of these utility methods on the returned RSM object, and then
  233. pass the result into a new query, you'll receive the next or previous batch of
  234. archived messages. Please note, when calling these methods, pass in an integer
  235. to limit your results.
  236. .. code-block:: javascript
  237. var callback = function (messages, rsm) {
  238. // Do something with the messages, like showing them in your webpage.
  239. // ...
  240. // You can now use the returned "rsm" object, to fetch the next batch of messages:
  241. converse.archive.query(rsm.next(10), callback, errback))
  242. }
  243. converse.archive.query({'with': 'john@doe.net', 'max':10}, callback, errback);
  244. **Paging backwards through a set of archived messages**
  245. To page backwards through the archive, you need to know the UID of the message
  246. which you'd like to page backwards from and then pass that as value for the
  247. ``before`` parameter. If you simply want to page backwards from the most recent
  248. message, pass in the ``before`` parameter with an empty string value ``''``.
  249. .. code-block:: javascript
  250. converse.archive.query({'before': '', 'max':5}, function (message, rsm) {
  251. // Do something with the messages, like showing them in your webpage.
  252. // ...
  253. // You can now use the returned "rsm" object, to fetch the previous batch of messages:
  254. rsm.previous(5); // Call previous method, to update the object's parameters,
  255. // passing in a limit value of 5.
  256. // Now we query again, to get the previous batch.
  257. converse.archive.query(rsm, callback, errback);
  258. }
  259. The "connection" grouping
  260. -------------------------
  261. This grouping collects API functions related to the XMPP connection.
  262. connected
  263. ~~~~~~~~~
  264. A boolean attribute (i.e. not a callable) which is set to `true` or `false` depending
  265. on whether there is an established connection.
  266. disconnect
  267. ~~~~~~~~~~
  268. Terminates the connection.
  269. The "user" grouping
  270. -------------------
  271. This grouping collects API functions related to the current logged in user.
  272. jid
  273. ~~~
  274. Return's the current user's full JID (Jabber ID).
  275. .. code-block:: javascript
  276. converse.user.jid()
  277. // Returns for example jc@opkode.com/conversejs-351236
  278. login
  279. ~~~~~
  280. Logs the user in. This method can accept a map with the credentials, like this:
  281. .. code-block:: javascript
  282. converse.user.login({
  283. 'jid': 'dummy@example.com',
  284. 'password': 'secret'
  285. });
  286. or it can be called without any parameters, in which case converse.js will try
  287. to log the user in by calling the `prebind_url` or `credentials_url` depending
  288. on whether prebinding is used or not.
  289. logout
  290. ~~~~~~
  291. Log the user out of the current XMPP session.
  292. .. code-block:: javascript
  293. converse.user.logout();
  294. The "status" sub-grouping
  295. ~~~~~~~~~~~~~~~~~~~~~~~~~
  296. Set and get the user's chat status, also called their *availability*.
  297. get
  298. ^^^
  299. Return the current user's availability status:
  300. .. code-block:: javascript
  301. converse.user.status.get(); // Returns for example "dnd"
  302. set
  303. ^^^
  304. The user's status can be set to one of the following values:
  305. * **away**
  306. * **dnd**
  307. * **offline**
  308. * **online**
  309. * **unavailable**
  310. * **xa**
  311. For example:
  312. .. code-block:: javascript
  313. converse.user.status.set('dnd');
  314. Because the user's availability is often set together with a custom status
  315. message, this method also allows you to pass in a status message as a
  316. second parameter:
  317. .. code-block:: javascript
  318. converse.user.status.set('dnd', 'In a meeting');
  319. The "message" sub-grouping
  320. ^^^^^^^^^^^^^^^^^^^^^^^^^^
  321. The ``user.status.message`` sub-grouping exposes methods for setting and
  322. retrieving the user's custom status message.
  323. .. code-block:: javascript
  324. converse.user.status.message.set('In a meeting');
  325. converse.user.status.message.get(); // Returns "In a meeting"
  326. The "contacts" grouping
  327. -----------------------
  328. get
  329. ~~~
  330. This method is used to retrieve roster contacts.
  331. To get a single roster contact, call the method with the contact's JID (Jabber ID):
  332. .. code-block:: javascript
  333. converse.contacts.get('buddy@example.com')
  334. To get multiple contacts, pass in an array of JIDs:
  335. .. code-block:: javascript
  336. converse.contacts.get(['buddy1@example.com', 'buddy2@example.com'])
  337. To return all contacts, simply call ``get`` without any parameters:
  338. .. code-block:: javascript
  339. converse.contacts.get()
  340. The returned roster contact objects have these attributes:
  341. +----------------+-----------------------------------------------------------------------------------------------------------------+
  342. | Attribute | |
  343. +================+=================================================================================================================+
  344. | ask | If ask === 'subscribe', then we have asked this person to be our chat buddy. |
  345. +----------------+-----------------------------------------------------------------------------------------------------------------+
  346. | fullname | The person's full name. |
  347. +----------------+-----------------------------------------------------------------------------------------------------------------+
  348. | jid | The person's Jabber/XMPP username. |
  349. +----------------+-----------------------------------------------------------------------------------------------------------------+
  350. | requesting | If true, then this person is asking to be our chat buddy. |
  351. +----------------+-----------------------------------------------------------------------------------------------------------------+
  352. | subscription | The subscription state between the current user and this chat buddy. Can be `none`, `to`, `from` or `both`. |
  353. +----------------+-----------------------------------------------------------------------------------------------------------------+
  354. | id | A unique id, same as the jid. |
  355. +----------------+-----------------------------------------------------------------------------------------------------------------+
  356. | chat_status | The person's chat status. Can be `online`, `offline`, `busy`, `xa` (extended away) or `away`. |
  357. +----------------+-----------------------------------------------------------------------------------------------------------------+
  358. | user_id | The user id part of the JID (the part before the `@`). |
  359. +----------------+-----------------------------------------------------------------------------------------------------------------+
  360. | resources | The known resources for this chat buddy. Each resource denotes a separate and connected chat client. |
  361. +----------------+-----------------------------------------------------------------------------------------------------------------+
  362. | groups | The roster groups in which this chat buddy was placed. |
  363. +----------------+-----------------------------------------------------------------------------------------------------------------+
  364. | status | Their human readable custom status message. |
  365. +----------------+-----------------------------------------------------------------------------------------------------------------+
  366. | image_type | The image's file type. |
  367. +----------------+-----------------------------------------------------------------------------------------------------------------+
  368. | image | The Base64 encoded image data. |
  369. +----------------+-----------------------------------------------------------------------------------------------------------------+
  370. | url | The buddy's website URL, as specified in their VCard data. |
  371. +----------------+-----------------------------------------------------------------------------------------------------------------+
  372. | vcard_updated | When last the buddy's VCard was updated. |
  373. +----------------+-----------------------------------------------------------------------------------------------------------------+
  374. add
  375. ~~~
  376. Add a contact.
  377. Provide the JID of the contact you want to add:
  378. .. code-block:: javascript
  379. converse.contacts.add('buddy@example.com')
  380. You may also provide the fullname. If not present, we use the jid as fullname:
  381. .. code-block:: javascript
  382. converse.contacts.add('buddy@example.com', 'Buddy')
  383. The "chats" grouping
  384. --------------------
  385. Note, for MUC chat rooms, you need to use the "rooms" grouping instead.
  386. get
  387. ~~~
  388. Returns an object representing a chat box.
  389. To return a single chat box, provide the JID of the contact you're chatting
  390. with in that chat box:
  391. .. code-block:: javascript
  392. converse.chats.get('buddy@example.com')
  393. To return an array of chat boxes, provide an array of JIDs:
  394. .. code-block:: javascript
  395. converse.chats.get(['buddy1@example.com', 'buddy2@example.com'])
  396. To return all open chat boxes, call the method without any JIDs::
  397. converse.chats.get()
  398. open
  399. ~~~~
  400. Opens a chat box and returns an object representing a chat box.
  401. To open a single chat box, provide the JID of the contact:
  402. .. code-block:: javascript
  403. converse.chats.open('buddy@example.com')
  404. To return an array of chat boxes, provide an array of JIDs:
  405. .. code-block:: javascript
  406. converse.chats.open(['buddy1@example.com', 'buddy2@example.com'])
  407. *The returned chat box object contains the following methods:*
  408. +-------------+------------------------------------------+
  409. | Method | Description |
  410. +=============+==========================================+
  411. | endOTR | End an OTR (Off-the-record) session. |
  412. +-------------+------------------------------------------+
  413. | get | Get an attribute (i.e. accessor). |
  414. +-------------+------------------------------------------+
  415. | initiateOTR | Start an OTR (off-the-record) session. |
  416. +-------------+------------------------------------------+
  417. | maximize | Minimize the chat box. |
  418. +-------------+------------------------------------------+
  419. | minimize | Maximize the chat box. |
  420. +-------------+------------------------------------------+
  421. | set | Set an attribute (i.e. mutator). |
  422. +-------------+------------------------------------------+
  423. | close | Close the chat box. |
  424. +-------------+------------------------------------------+
  425. | open | Opens the chat box. |
  426. +-------------+------------------------------------------+
  427. *The get and set methods can be used to retrieve and change the following attributes:*
  428. +-------------+-----------------------------------------------------+
  429. | Attribute | Description |
  430. +=============+=====================================================+
  431. | height | The height of the chat box. |
  432. +-------------+-----------------------------------------------------+
  433. | url | The URL of the chat box heading. |
  434. +-------------+-----------------------------------------------------+
  435. The "rooms" grouping
  436. --------------------
  437. get
  438. ~~~
  439. Returns an object representing a multi user chat box (room).
  440. It takes 3 parameters:
  441. * the room JID (if not specified, all rooms will be returned).
  442. * a map (object) containing any extra room attributes For example, if you want
  443. to specify the nickname, use ``{'nick': 'bloodninja'}``. Previously (before
  444. version 1.0.7, the second parameter only accepted the nickname (as a string
  445. value). This is currently still accepted, but then you can't pass in any
  446. other room attributes. If the nickname is not specified then the node part of
  447. the user's JID will be used.
  448. * a boolean, indicating whether the room should be created if not found (default: `false`)
  449. .. code-block:: javascript
  450. var nick = 'dread-pirate-roberts';
  451. var create_if_not_found = true;
  452. converse.rooms.open('group@muc.example.com', {'nick': nick}, create_if_not_found)
  453. open
  454. ~~~~
  455. Opens a multi user chat box and returns an object representing it.
  456. Similar to chats.get API
  457. It takes 2 parameters:
  458. * the room JID (if not specified, all rooms will be returned).
  459. * a map (object) containing any extra room attributes. For example, if you want
  460. to specify the nickname, use ``{'nick': 'bloodninja'}``.
  461. To open a single multi user chat box, provide the JID of the room:
  462. .. code-block:: javascript
  463. converse.rooms.open('group@muc.example.com')
  464. To return an array of rooms, provide an array of room JIDs:
  465. .. code-block:: javascript
  466. converse.rooms.open(['group1@muc.example.com', 'group2@muc.example.com'])
  467. To setup a custom nickname when joining the room, provide the optional nick argument:
  468. .. code-block:: javascript
  469. converse.rooms.open('group@muc.example.com', {'nick': 'mycustomnick'})
  470. close
  471. ~~~~~
  472. Lets you close open chat rooms. You can call this method without any arguments
  473. to close all open chat rooms, or you can specify a single JID or an array of
  474. JIDs.
  475. The "settings" grouping
  476. -----------------------
  477. This grouping allows you to get or set the configuration settings of converse.js.
  478. get(key)
  479. ~~~~~~~~
  480. Returns the value of a configuration settings. For example:
  481. .. code-block:: javascript
  482. converse.settings.get("play_sounds"); // default value returned would be false;
  483. set(key, value) or set(object)
  484. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  485. Set one or many configuration settings. For example:
  486. .. code-block:: javascript
  487. converse.settings.set("play_sounds", true);
  488. or :
  489. .. code-block:: javascript
  490. converse.settings.set({
  491. "play_sounds", true,
  492. "hide_offline_users" true
  493. });
  494. Note, this is not an alternative to calling ``converse.initialize``, which still needs
  495. to be called. Generally, you'd use this method after converse.js is already
  496. running and you want to change the configuration on-the-fly.
  497. The "tokens" grouping
  498. ---------------------
  499. get
  500. ~~~
  501. Returns a token, either the RID or SID token depending on what's asked for.
  502. Example:
  503. .. code-block:: javascript
  504. converse.tokens.get('rid')
  505. .. _`listen-grouping`:
  506. The "listen" grouping
  507. ---------------------
  508. Converse.js emits events to which you can subscribe from your own Javascript.
  509. Concerning events, the following methods are available under the "listen"
  510. grouping:
  511. * **on(eventName, callback)**:
  512. Calling the ``on`` method allows you to subscribe to an event.
  513. Every time the event fires, the callback method specified by ``callback`` will be
  514. called.
  515. Parameters:
  516. * ``eventName`` is the event name as a string.
  517. * ``callback`` is the callback method to be called when the event is emitted.
  518. For example:
  519. .. code-block:: javascript
  520. converse.listen.on('message', function (event, messageXML) { ... });
  521. * **once(eventName, callback)**:
  522. Calling the ``once`` method allows you to listen to an event
  523. exactly once.
  524. Parameters:
  525. * ``eventName`` is the event name as a string.
  526. * ``callback`` is the callback method to be called when the event is emitted.
  527. For example:
  528. .. code-block:: javascript
  529. converse.listen.once('message', function (event, messageXML) { ... });
  530. * **not(eventName, callback)**
  531. To stop listening to an event, you can use the ``not`` method.
  532. Parameters:
  533. * ``eventName`` is the event name as a string.
  534. * ``callback`` refers to the function that is to be no longer executed.
  535. For example:
  536. .. code-block:: javascript
  537. converse.listen.not('message', function (event, messageXML) { ... });
  538. Events
  539. ======
  540. .. note:: see also :ref:`listen-grouping` above.
  541. Event Types
  542. -----------
  543. Here are the different events that are emitted:
  544. cachedRoster
  545. ~~~~~~~~~~~~
  546. The contacts roster has been retrieved from the local cache (`sessionStorage`).
  547. ``converse.listen.on('cachedRoster', function (event, items) { ... });``
  548. See also the `roster` event further down.
  549. callButtonClicked
  550. ~~~~~~~~~~~~~~~~~
  551. When a call button (i.e. with class .toggle-call) on a chat box has been clicked.
  552. ``converse.listen.on('callButtonClicked', function (event, connection, model) { ... });``
  553. chatBoxInitialized
  554. ~~~~~~~~~~~~~~~~~~
  555. When a chat box has been initialized. Relevant to converse-chatview.js plugin.
  556. ``converse.listen.on('chatBoxInitialized', function (event, chatbox) { ... });``
  557. chatBoxOpened
  558. ~~~~~~~~~~~~~
  559. When a chat box has been opened. Relevant to converse-chatview.js plugin.
  560. ``converse.listen.on('chatBoxOpened', function (event, chatbox) { ... });``
  561. chatRoomOpened
  562. ~~~~~~~~~~~~~~
  563. When a chat room has been opened. Relevant to converse-chatview.js plugin.
  564. ``converse.listen.on('chatRoomOpened', function (event, chatbox) { ... });``
  565. chatBoxClosed
  566. ~~~~~~~~~~~~~
  567. When a chat box has been closed. Relevant to converse-chatview.js plugin.
  568. ``converse.listen.on('chatBoxClosed', function (event, chatbox) { ... });``
  569. chatBoxFocused
  570. ~~~~~~~~~~~~~~
  571. When the focus has been moved to a chat box. Relevant to converse-chatview.js plugin.
  572. ``converse.listen.on('chatBoxFocused', function (event, chatbox) { ... });``
  573. chatBoxToggled
  574. ~~~~~~~~~~~~~~
  575. When a chat box has been minimized or maximized. Relevant to converse-chatview.js plugin.
  576. ``converse.listen.on('chatBoxToggled', function (event, chatbox) { ... });``
  577. connected
  578. ~~~~~~~~~
  579. After connection has been established and converse.js has got all its ducks in a row.
  580. ``converse.listen.on('connected', function (event) { ... });``
  581. contactRequest
  582. ~~~~~~~~~~~~~~
  583. Someone has requested to subscribe to your presence (i.e. to be your contact).
  584. ``converse.listen.on('contactRequest', function (event, user_data) { ... });``
  585. contactRemoved
  586. ~~~~~~~~~~~~~~
  587. The user has removed a contact.
  588. ``converse.listen.on('contactRemoved', function (event, data) { ... });``
  589. contactStatusChanged
  590. ~~~~~~~~~~~~~~~~~~~~
  591. When a chat buddy's chat status has changed.
  592. ``converse.listen.on('contactStatusChanged', function (event, buddy) { ... });``
  593. contactStatusMessageChanged
  594. ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  595. When a chat buddy's custom status message has changed.
  596. ``converse.listen.on('contactStatusMessageChanged', function (event, data) { ... });``
  597. disconnected
  598. ~~~~~~~~~~~~
  599. After converse.js has disconnected from the XMPP server.
  600. ``converse.listen.on('disconnected', function (event) { ... });``
  601. initialized
  602. ~~~~~~~~~~~
  603. Once converse.js has been initialized.
  604. ``converse.listen.on('initialized', function (event) { ... });``
  605. See also `pluginsInitialized`_.
  606. messageSend
  607. ~~~~~~~~~~~
  608. When a message will be sent out.
  609. ``storage_memoryconverse.listen.on('messageSend', function (event, messageText) { ... });``
  610. noResumeableSession
  611. ~~~~~~~~~~~~~~~~~~~
  612. When keepalive=true but there aren't any stored prebind tokens.
  613. ``converse.listen.on('noResumeableSession', function (event) { ... });``
  614. pluginsInitialized
  615. ~~~~~~~~~~~~~~~~~~
  616. Once all plugins have been initialized. This is a useful event if you want to
  617. register event handlers but would like your own handlers to be overridable by
  618. plugins. In that case, you need to first wait until all plugins have been
  619. initialized, so that their overrides are active. One example where this is used
  620. is in [converse-notifications.js](https://github.com/jcbrand/converse.js/blob/master/src/converse-notification.js).
  621. ``converse.listen.on('pluginsInitialized', function (event) { ... });``
  622. reconnected
  623. ~~~~~~~~~~~
  624. After the connection has dropped and converse.js has reconnected.
  625. Any Strophe stanza handlers (as registered via `converse.listen.stanza`) will
  626. have to be registered anew.
  627. ``converse.listen.on('reconnected', function (event) { ... });``
  628. roomInviteSent
  629. ~~~~~~~~~~~~~~
  630. After the user has sent out a direct invitation, to a roster contact, asking them to join a room.
  631. ``converse.listen.on('roomInvite', function (event, data) { ... });``
  632. roomInviteReceived
  633. ~~~~~~~~~~~~~~~~~~
  634. After the user has sent out a direct invitation, to a roster contact, asking them to join a room.
  635. ``converse.listen.on('roomInvite', function (event, data) { ... });``
  636. roster
  637. ~~~~~~
  638. When the roster has been received from the XMPP server.
  639. ``converse.listen.on('roster', function (event, items) { ... });``
  640. See also the `cachedRoster` event further up, which gets called instead of
  641. `roster` if its already in `sessionStorage`.
  642. rosterPush
  643. ~~~~~~~~~~
  644. When the roster receives a push event from server. (i.e. New entry in your buddy list)
  645. ``converse.listen.on('rosterPush', function (event, items) { ... });``
  646. statusInitialized
  647. ~~~~~~~~~~~~~~~~~
  648. When own chat status has been initialized.
  649. ``converse.listen.on('statusInitialized', function (event, status) { ... });``
  650. statusChanged
  651. ~~~~~~~~~~~~~
  652. When own chat status has changed.
  653. ``converse.listen.on('statusChanged', function (event, status) { ... });``
  654. statusMessageChanged
  655. ~~~~~~~~~~~~~~~~~~~~
  656. When own custom status message has changed.
  657. ``converse.listen.on('statusMessageChanged', function (event, message) { ... });``
  658. serviceDiscovered
  659. ~~~~~~~~~~~~~~~~~
  660. When converse.js has learned of a service provided by the XMPP server. See XEP-0030.
  661. ``converse.listen.on('serviceDiscovered', function (event, service) { ... });``
  662. Writing a converse.js plugin
  663. ============================
  664. Developers are able to extend and override the objects, functions and the
  665. Backbone models and views that make up converse.js by means of writing plugins.
  666. Converse.js uses `pluggable.js <https://github.com/jcbrand/pluggable.js/>`_ as
  667. its plugin architecture.
  668. To understand how this plugin architecture works, please read the
  669. `pluggable.js documentation <https://jcbrand.github.io/pluggable.js/>`_
  670. and to grok its inner workins, please refer to the `annotated source code
  671. <https://jcbrand.github.io/pluggable.js/docs/pluggable.html>`_.
  672. You register a converse.js plugin as follows:
  673. .. code-block:: javascript
  674. converse.plugins.add('myplugin', {
  675. // Your plugin code goes in here
  676. });
  677. Security and access to the inner workings
  678. -----------------------------------------
  679. The globally available ``converse`` object, which exposes the API methods, such
  680. as ``initialize`` and ``plugins.add``, is a wrapper that encloses and protects
  681. a sensitive inner object.
  682. This inner object contains all the Backbone models and views, as well as
  683. various other attributes and functions.
  684. Within a plugin, you will have access to this internal
  685. `"closured" <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures>`_
  686. converse object, which is normally not exposed in the global variable scope. The
  687. hiding of this inner object is due to the fact that it contains sensitive information,
  688. such as the user's JID and password (if they logged in manually). You should
  689. therefore make sure NOT to expose this object globally.
  690. An example plugin
  691. -----------------
  692. .. code-block:: javascript
  693. (function (root, factory) {
  694. if (typeof define === 'function' && define.amd) {
  695. // AMD. Register as a module called "myplugin"
  696. define("myplugin", ["converse"], factory);
  697. } else {
  698. // Browser globals. If you're not using a module loader such as require.js,
  699. // then this line below executes. Make sure that your plugin's <script> tag
  700. // appears after the one from converse.js.
  701. factory(converse);
  702. }
  703. }(this, function (converse_api) {
  704. // Commonly used utilities and variables can be found under the "env"
  705. // namespace of converse_api
  706. // Strophe methods for building stanzas
  707. var Strophe = converse_api.env.Strophe,
  708. $iq = converse_api.env.$iq,
  709. $msg = converse_api.env.$msg,
  710. $pres = converse_api.env.$pres,
  711. $build = converse_api.env.$build,
  712. b64_sha1 = converse_api.env.b64_sha1;
  713. // Other frequently used utilities
  714. var $ = converse_api.env.jQuery,
  715. _ = converse_api.env._,
  716. moment = converse_api.env.moment;
  717. // The following line registers your plugin.
  718. converse_api.plugins.add('myplugin', {
  719. initialize: function () {
  720. // Converse.js's plugin mechanism will call the initialize
  721. // method on any plugin (if it exists) as soon as the plugin has
  722. // been loaded.
  723. // Inside this method, you have access to the protected "inner"
  724. // converse object, from which you can get any configuration
  725. // options that the user might have passed in via
  726. // converse.initialize. These values are stored in the
  727. // "user_settings" attribute.
  728. // Let's assume the user might in a custom setting, like so:
  729. // converse.initialize({
  730. // "initialize_message": "My plugin has been initialized"
  731. // });
  732. //
  733. // Then we can alert that message, like so:
  734. alert(this.converse.user_settings.initialize_message);
  735. },
  736. myFunction: function () {
  737. // This is a function which does not override anything in
  738. // converse.js itself, but in which you still have access to
  739. // the protected "inner" converse object.
  740. var converse = this.converse;
  741. // Custom code comes here
  742. // ...
  743. },
  744. overrides: {
  745. // If you want to override some function or a Backbone model or
  746. // view defined inside converse, then you do that under this
  747. // "overrides" namespace.
  748. // For example, the inner protected *converse* object has a
  749. // method "onConnected". You can override that method as follows:
  750. onConnected: function () {
  751. // Overrides the onConnected method in converse.js
  752. // Top-level functions in "overrides" are bound to the
  753. // inner "converse" object.
  754. var converse = this;
  755. // Your custom code comes here.
  756. // ...
  757. // You can access the original function being overridden
  758. // via the __super__ attribute.
  759. // Make sure to pass on the arguments supplied to this
  760. // function and also to apply the proper "this" object.
  761. this.__super__.onConnected.apply(this, arguments);
  762. },
  763. XMPPStatus: {
  764. // Override converse.js's XMPPStatus Backbone model so that we can override the
  765. // function that sends out the presence stanza.
  766. sendPresence: function (type, status_message, jid) {
  767. // The "converse" object is available via the __super__
  768. // attribute.
  769. var converse = this.__super__.converse;
  770. // Custom code can come here
  771. // ...
  772. // You can call the original overridden method, by
  773. // accessing it via the __super__ attribute.
  774. // When calling it, you need to apply the proper
  775. // context as reference by the "this" variable.
  776. this.__super__.sendPresence.apply(this, arguments);
  777. }
  778. },
  779. }
  780. });
  781. }));